kapp ou pas kapp ?

Objectif

La constellation des outils annexes à Kubernetes n’en finit pas de grandir et il est assez difficile de suivre les nouveautés. Devant cette profusion, nous prenons le temps de nous attarder sur kapp qui introduit le concept d’application comme un regroupement de ressources Kubernetes.

À la clé, une capacité à manipuler une stack applicative (Service, Ingress, Deployment, ConfigMap, Secret…) pendant toutes les étapes de sa vie, et ce, comme un tout.

Principe de fonctionnement

L’utilisation de kapp commence par l’installation d’un binaire statique (compilé à partir de code Go) disponible sur le site GitHub du projet.

Il va être utilisable avec n’importe quel contenu valide décrivant des ressources Kubernetes. Il est donc possible d’utiliser Helm, ytt ou kustomize pour rendre les templates de nos ressources et de laisser à kapp la tâche de les déployer.

À la lecture de la définition des ressources, kapp va manipuler des annotations et des labels permettant de marquer les objets à créer / modifier tout en traçant les opérations. L’affichage ressemble grossièrement à ce qu’afficherait Terraform sur des ressources cloud.

Pour chaque ressource, les actions à opérer côté cluster sont identifiées : ajout, modification, suppression… En cas de modification, un diff permet de voir ce qui va changer.

Notons que dans l’exemple ci-dessus, la définition du namespace a été supprimée. On voit donc que kapp détecte les ressources qu’il est nécessaire de supprimer, ce qui est un vrai plus de cette solution, par rapport à kubectl par exemple.

Le grain manipulé est donc l’application, ce concept permet de regrouper un ensemble de ressources cohérentes. Les applications peuvent aussi être listées et inspectées comme des objets à part entière (ce qu’elles ne sont pas).

À noter que kapp ne se contente pas de créer les objets décrits pour considérer que le travail est fini. L’outil est capable de savoir qu’il y a des objets intermédiaires (des ReplicaSets par exemple) ou fils (des Pods par exemple) qui vont être créés ou modifiés. L’opération n’est considérée comme finie que lorsque tous les objets sont bien présents, dans la limite d’une certaine durée (15 minutes par défaut).

Le code de retour renseigne donc de façon beaucoup plus parlante sur le succès d’un déploiement : 0 si tout va bien, 1 dans le cas contraire. C’est extrêmement pratique et fiable surtout si des ReadinessProbes ont été mises en œuvre dans les Deployments.

Cette fonctionnalité est très précieuse, notamment dans un contexte d’intégration et surtout de déploiement continus (CI/CD pour les intimes), car elle garantit que l’on est capable de valider qu’un déploiement a effectivement réussi et qu’il est intégralement terminé. Les scripts et autres pipelines peuvent alors continuer à s’exécuter en parfaite connaissance de cause.

Sous le capot

L’historisation

Pour effectuer son travail de traçabilité, kapp dépose des quantités massives de labels et d’annotations dans les objets, regroupés sous le préfixe kapp.k14s.io.

En outre, les opérations de changement sont résumées dans des ConfigMaps, dont une du nom de l’application (attention au conflit si vous souhaitez en créer une éponyme).

Cette historisation permet d’avoir (sans les détails précis, ni les diff complets, et c’est un peu dommage) les déploiements de l’application en question qui ont été tentés, avec succès ou non :

Redéploiement sur changement de configuration

kapp offre la possibilité de versionner les config-maps et les secrets ainsi que de redémarrer les pods qui utilisent ces ressources.

Pour l’exemple nous créons une ConfigMap nommée my-config en la référençant dans notre déploiement. Lors de la tentative de déploiement, on observe que kapp va déployer une ConfigMap suivie d’une version (my-config-ver-1 lors du premier déploiement, my-config-ver-2 lors du second…). Son nom n’est donc pas celui que nous avons spécifié !!

Ainsi, à chaque mise à jour de la ConfigMap, une nouvelle version sera créée et le déploiement mis à jour. Il est possible de définir le nombre maximum de versions à historiser.

La gestion de groupes d’applications

kapp intègre également le concept de groupe d’applications qui consiste à préfixer toutes les applications créées par un nom de groupe et de gérer chaque application dans un sous-répertoire :

Chaque sous-répertoire de premier niveau deviendra le suffixe des applications créées. Leur nom complet étant la concaténation du nom du groupe (my-group dans cet exemple) et du nom du sous-dossier (app et app2 dans cet exemple) :

Même si le principe de fonctionnement est élégant, nous ne sommes pas encore convaincus que ce fonctionnement soit très utile (à part pour gagner du temps à la suppression avec la commande kapp app-group delete -g my-group -y).

Points d’attention

Faire le ménage

Enlevez de vos manifestes les valeurs vides (ici strategy mais également status ou les champs techniques), vous risqueriez de vous retrouver avec un déploiement à modifier alors que les valeurs par défaut sont utilisées.

Astuce : assurez-vous donc que les fichiers que vous utilisez sont bien idempotents en les soumettant deux fois de suite et en vérifiant que kapp ne voit pas de changement.

Refactoring

kapp pose des labels sur les ressources au moment de leur création lui permettant de retrouver ses petits. Ainsi, si vous souhaitez déplacer des ressources d’une application à une autre, vous aurez les mêmes problématiques que dans un système à état (avec le tfstate de Terraform par exemple).

L’option --dangerous-override-ownership-of-existing-resources vous permet de remplacer les labels d’une ressource pour la mettre sous le giron de votre nouvelle application. Attention tout de même, certains labels peuvent se retrouver dans des champs immuables (par exemple spec.selector.matchLabels pour les Deployments). Il faudra alors recréer la ressource.

Conclusion

kapp est un outil à recommander pour ses fonctionnalités que l’on aime :

  • Le feedback concernant le déploiement des ressources (savoir si un Deployment s’est bien passé, si les Pods sont dans un état Ready …).
  • Le code de retour qui donne la possibilité de l’utiliser en CI/CD.
  • La suppression d’une ressource quand le manifeste la décrivant n’existe plus !

On regrette cependant :

  • L’injection de labels au niveau des champs immutables qui force à recréer des ressources.
  • La configuration par défaut qu’on ne peut pas surcharger.
  • Les longues annotations injectées par kapp lors du déploiement de notre ressource.

kapp est actuellement en version 0.9.0, espérons que la communauté autour de cette outil grandira !