Sécurisez le développement de vos applications Kubernetes avec Snyk et Tilt
11 janvier 2021
0 minutes de lectureDévelopper des applications Kubernetes peut s’avérer complexe. Nous devons souvent gérer des architectures de microservices comportant de nombreux éléments, ainsi que développer la configuration du cluster pour les connecter. Les workflows permettant d’itérer et de tester rapidement peuvent alors devenir complexes et difficiles à gérer pour les équipes d’ingénierie.
C’est là que des outils comme Tilt entrent en jeu.
Qu’est-ce que Tilt ?
Tilt est un outil formidable pour les développeurs qui travaillent sur des applications Kubernetes. Il propose un workflow de déploiement local hautement configurable qui se met à jour en temps réel pendant que vous travaillez. Au lieu de gérer un ensemble centralisé d’environnements dans lesquels tous vos développeurs travaillent, Tilt fournit à chacun son propre environnement local, avec des déploiements ultrarapides, et lui permet de personnaliser son workflow.
Tilt se configure à l’aide d’un fichier Tilftfile basé sur Starlark. Il propose une interface graphique et une CLI personnalisables, ainsi qu’une API complète. Vous disposez ainsi d’une grande flexibilité pour définir vos workflows et les informations à afficher pendant le développement de votre application. Tilt prend également en charge les extensions personnalisées, ce qui vous offre encore plus d’options pour configurer et exécuter votre environnement de développement.
Mon collègue Shai Mendel a contribué à une extension Tilt qui permet d’exécuter Snyk dans votre Tiltfile. J’ai récemment consacré du temps à mettre à jour cette extension et à explorer les différentes façons d’intégrer Snyk à vos workflows Tilt. Voyons comment cela fonctionne.
Pour commencer
La première étape consiste à déployer un cluster Kubernetes local, ainsi qu’un registre. Tilt fournit un outil qui simplifie grandement cette opération. Ctlptl permet d’exécuter Kubernetes en local de différentes façons, notamment avec miniKube, Kind et Docker Desktop. J’utilise Kind, que vous devez d’abord installer.
Cette commande déploie un cluster Kubernetes avec Kind, ainsi qu’un registre dans votre instance Docker locale, et configure tout ce dont Kubernetes a besoin pour l’utiliser. Une fois la commande exécutée, nous pouvons voir dans Docker que les deux éléments ont été déployés :
Ensuite, je vais cloner une application exemple pour la tester. J’utilise l’exemple Node.js fourni par Tilt. Cette application comprend plusieurs Tiltfiles d’exemple qui présentent les bonnes pratiques d’utilisation de Tilt, ainsi qu’un article de blog qui les explique en détail.
Pour cet article, nous allons utiliser l’exemple de Dockerfile optimisé. Regardons le Tiltfile fourni :
En examinant ce que fait ce Tiltfile, on voit qu’il utilise la fonction docker_build pour créer l’image example-node-js-image à partir du Dockerfile situé dans ce dossier. Il crée également une ressource k8s_yaml à l’aide du fichier kubernetes.yaml, puis l’associe à une ressource k8s_resource avec une redirection de port vers le port 8000. Une ressource local_resource est aussi définie : elle écrit l’heure actuelle dans un fichier et crée une dépendance entre ce fichier et k8s_resource. Elle s’exécute donc toujours avant la mise à jour de la ressource et permet de mesurer le temps de déploiement. Consultez la documentation pour en savoir plus sur toutes les fonctions prises en charge par l’API Tiltfile.
Nous avons également un Dockerfile qui installe les dépendances nécessaires à notre application avec yarn :
Notre application est elle-même très simple : cette application Node.js se contente d’afficher une page Web sur le port 8000 :
Maintenant que notre cluster est déployé, nous pouvons démarrer Tilt. Depuis le dossier qui contient notre Tiltfile, il suffit d’exécuter :
Lorsque Tilt s’exécute dans le terminal, appuyez sur la barre d’espace pour ouvrir son interface dans votre navigateur.

Tilt exécute le Tiltfile et lance toutes les ressources définies. Dans notre cas, il crée l’image, la déploie sur Kubernetes et configure une redirection de port pour accéder à l’application.
Avec kubectl, nous pouvons vérifier que le pod exécutant l’application est bien en cours d’exécution :
En accédant à http://localhost:8000, nous pouvons voir l’application :

Une fois Tilt lancé, toute modification apportée aux répertoires et aux fichiers surveillés déclenche une nouvelle exécution du Tiltfile, puis la création et le redéploiement automatiques de l’application.
Voyons maintenant comment intégrer Snyk à ce workflow. Si ce n’est pas déjà fait, vous devez installer la CLI Snyk et créer un compte Snyk gratuit.
La première étape consiste à charger l’extension Snyk dans le Tiltfile :
À cette étape, Tilt exécute automatiquement le Tiltfile à nouveau. Dans le dossier de notre application, un répertoire tilt_modules apparaît. Il contient l’extension Snyk. Les extensions sont elles-mêmes des Tiltfiles, qui sont chargés dans le Tiltfile principal.
Une fois l’extension Snyk chargée, nous pouvons l’utiliser pour intégrer Snyk à notre workflow Tilt. L’extension prend en charge les trois modes proposés par la CLI Snyk : nous pouvons donc analyser les conteneurs, les dépendances des packages et les fichiers d’infrastructure as code, ici au format YAML Kubernetes. Elle est également conçue pour offrir un maximum de flexibilité et vous permettre de créer différents workflows dans Tilt.
Commençons par analyser notre fichier YAML Kubernetes. Dans le Tiltfile, nous appelons l’extension Snyk et la configurons pour analyser le fichier kubernetes.yaml :
L’extension accepte différents arguments. Pour consulter la documentation complète, reportez-vous au README. Ici, nous ciblons kubernetes.yaml, demandons une analyse IaC, attribuons un nom à cette ressource, définissons le mode sur info et configurons le déclenchement manuel. L’indicateur de mode peut être défini sur info ou gate. En mode info, la commande renvoie toujours le code de sortie zéro, même si des vulnérabilités sont détectées ; l’analyse n’est donc pas considérée comme un échec dans l’interface Tilt. Si nous définissons le déclenchement sur auto, l’analyse s’exécutera chaque fois que Tilt détectera une modification de kubernetes.yaml. En mode manuel, nous devrons la lancer depuis l’interface Tilt.
Après avoir enregistré le Tiltfile, nous voyons dans l’interface Tilt un nouveau lien dans la barre latérale, intitulé snyk-iac-manual.

Cette entrée comporte un bouton d’actualisation, qui indique que nous pouvons l’exécuter manuellement. Allons-y.

Lorsque nous lançons l’analyse, nous voyons la CLI Snyk s’exécuter sur kubernetes.yaml, ainsi que les résultats dans l’interface. Plusieurs problèmes de sécurité potentiels ont été détectés dans le fichier, mais le test est toujours indiqué comme ayant réussi, puisque nous avions choisi le mode informatif. Voyons ce qui se passe si nous passons en mode gate. Dans le Tiltfile, modifiez la configuration de ce contrôle :
Après la nouvelle exécution du Tiltfile, nous remarquons d’abord dans l’interface que le bouton d’actualisation de notre contrôle manuel est mis en évidence. Cela signifie qu’il n’est plus synchronisé avec les autres étapes et qu’il doit être actualisé.

Relançons la configuration mise à jour :

Puisque nous avons défini la ressource en mode gate, Tilt la signale comme un échec de build.
Examinons maintenant les différentes options d’intégration de l’analyse des conteneurs à notre workflow Tilt. Il est important de noter que Tilt utilise des tags immuables : chaque build créé reçoit un tag unique, qui est également transmis à Kubernetes. Cela accélère le processus de déploiement. Pour en savoir plus, consultez cette page.
Par défaut, la fonction docker_build génère de nombreux tags immuables, que vous pouvez voir en examinant les images dans Docker :
Cela pose également un problème pour l’analyse : il n’existe actuellement aucune fonction intégrée permettant d’accéder à ces tags ailleurs dans le Tiltfile. Or, nous devons connaître le tag de l’image pour pouvoir l’analyser avec Snyk.
Nous avons toutefois plusieurs options pour y remédier. Tilt fournit une fonction qui permet de définir vos propres étapes de build, que nous pouvons utiliser pour créer notre workflow.
Commençons par configurer une étape d’analyse manuelle. Nous allons rendre le tag de notre image mutable : nous lui attribuerons un tag fixe que nous utiliserons pour tous nos builds. Tilt attribuera ensuite un tag immuable au build avant son déploiement.
Dans notre Tiltfile, supprimons la fonction docker_build et remplaçons-la par une fonction custom_build :
Nous allons donc appeler Docker, comme le ferait la fonction docker_build, mais en ajoutant la variable d’environnement spéciale $EXPECTED_REF. Nous avons également spécifié tag=’dev’,, que Tilt utilisera pour renseigner cette variable. Une fois le Tiltfile enregistré, nous constatons que Tilt a créé une image avec un tag mutable, puis lui a attribué un nouveau tag :
Nous avons ici défini comme cible le tag connu, spécifié le mode conteneur, nommé l’analyse et choisi le mode informatif. Comme le Dockerfile se trouve dans notre répertoire, nous pouvons également l’ajouter à l’argument extra_opts pour obtenir des suggestions d’images de base.

Notre barre latérale comporte maintenant l’analyse manuelle du conteneur. Nous pouvons la lancer.

Nous avons donc lancé manuellement l’analyse du conteneur. Mais comment l’exécuter automatiquement à chaque build Tilt ? Ce scénario est un peu plus complexe, car Tilt ne gère pas encore très bien les dépendances avant ou après le build. Nous pourrions appeler Snyk directement dans la fonction custom_build, mais l’objectif de l’extension est de proposer aux utilisateurs une méthode flexible pour intégrer les analyses Snyk à leurs workflows.
Commençons par modifier notre fonction custom_build. Supprimons l’argument tag=’dev’ : $EXPECTED_REF prendra alors la valeur du tag immuable généré automatiquement par Tilt. À chaque build, nous écrirons ensuite ce tag dans un fichier de notre système de fichiers. Nous utilisons ici printf pour éviter qu’un saut de ligne soit ajouté à la fin du tag lors de son écriture dans le fichier.
Nous allons également ajouter une fonction pour récupérer le tag depuis le fichier. La fonction read_file renvoie un blob : nous devons donc le convertir en chaîne de caractères, puis supprimer les éventuels sauts de ligne :
Nous allons ensuite appeler l’extension Snyk en définissant comme cible le résultat de notre fonction get_tag, en activant le déclenchement automatique et en créant une dépendance avec le fichier dans le système de fichiers. Ainsi, chaque fois que ce fichier est modifié, notre extension s’exécute.
Une fois le Tiltfile à nouveau enregistré, nous constatons qu’à chaque exécution de notre build, nous déclenchons également automatiquement
l’analyse Snyk.

Enfin, examinons l’analyse des dépendances du code source de notre application. Comme il s’agit d’une application Node.js qui utilise yarn comme gestionnaire de packages, le dossier contient un fichier yarn.lock qui indique les versions des modules utilisés.
Nous pouvons l’analyser automatiquement avec Snyk pour détecter les vulnérabilités :

Dans cet exemple, l’application est très simple et aucune de ses dépendances ne présente de vulnérabilité. Tout est donc en ordre !
Tilt est un outil fantastique qui peut accélérer considérablement le développement local d’applications Kubernetes basées sur des microservices. Ses nombreuses options de configuration vous permettent de créer le workflow qui vous convient parfaitement.
Dans cet article, nous avons découvert différentes façons d’intégrer l’analyse Snyk à vos workflows Tilt à l’aide de l’extension Snyk pour Tilt, afin de sécuriser vos applications cloud natives et leur configuration. Créez un compte Snyk gratuit et essayez-la.
Lancez-vous dans les compétitions Capture The Flag
Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.


