Le gestionnaire de déploiement kapp"
kapp est un outil de la suite Carvel qui permet de gérer le déploiement d’applications sur des clusters Kubernetes.
Les points forts de kapp :
- Kapp peut fonctionner avec des manifests classiques ou issu de templates Helm ou yyt.
- Kapp sépare la phase de calcul du changement (diff) de la phase d’application du changement (apply) pour donner aux utilisateurs une visibilité sur ce qui va changer.
- Kapp suit et fait converger les ressources sur la base d’une étiquette générée unique, évitant ainsi à ses utilisateurs de se soucier du nettoyage des anciennes ressources lors de la mise à jour de l’application
- Kapp ordonne certaines ressources afin que le serveur d’API Kubernetes puisse les traiter avec succès (par exemple, les CRD et les espaces de noms avant les autres ressources)
- kapp attends que les ressources soient prêtes avant de considérer que le déploiement s’est fait avec succès.
- Kapp est gitops ready.
Installation de kapp
Comme pour les autres outils de la suite on installe tout :
wget -O- https://carvel.dev/install.sh > install.shsudo bash install.shkapp version
kapp version 0.44.0
Succeeded
Utilisation de kapp
Kapp
possède plusieurs commandes permettant de gérer les applications d’un
cluster kubernetes dont les principales sont : deploy
, list
, inspect
et
logs
.
Pour obtenir de l’aide il suffit de taper le classique :
kapps [<command>] --help
Toutes les commandes possèdent des alias (deploy : dep
ou d
) qui sont
affichés dans le début de l’aide de chaque commande.
Kapp
possède une option --json
qui permet d’afficher la ressource sous forme
de json. Bien utile pour les
ansible users entre autre.
Mon exemple d’application vient des exemples fournis sur le projet de kapp ↗.
Je vais utiliser kind pour créer un cluster et déployer dessus.
Déployer à jour une application
Pour déployer une application on doit lui indiquer comme pour helm
un
identifiant qui servira à identifier toutes les ressources associées. Pour cela
on utilise l’option -a
qui vient se placer derrière la commande deploy :
kapp deploy -a simple-app -f config.yml
Target cluster 'https://10.240.0.10:6443' (nodes: master1, 1+)
Changes
Namespace Name Kind Conds. Age Op Op st. Wait to Rs Ridefault simple-app Deployment - - create - reconcile - -^ simple-app Service - - create - reconcile - -
Op: 2 create, 0 delete, 0 update, 0 noop, 0 existsWait to: 2 reconcile, 0 delete, 0 noop
Continue? [yN]:
kapp
compare les ressources spécifiées dans les fichiers de ressources à ceux
qui existent déjà dans le cluster Kubernetes. Une fois l’ensemble de
modifications calculé, il offre une option pour l’appliquer.
Continue? [yN]: y
7:01:44AM: ---- applying 2 changes [0/2 done] ----7:01:44AM: create deployment/simple-app (apps/v1) namespace: default7:01:44AM: create service/simple-app (v1) namespace: default7:01:44AM: ---- waiting on 2 changes [0/2 done] ----7:01:44AM: ok: reconcile service/simple-app (v1) namespace: default7:01:44AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default7:01:44AM: ^ Waiting for generation 2 to be observed7:01:44AM: L ok: waiting on replicaset/simple-app-765bb9c475 (apps/v1) namespace: default7:01:44AM: L ongoing: waiting on pod/simple-app-765bb9c475-fv62b (v1) namespace: default7:01:44AM: ^ Pending7:01:44AM: ---- waiting on 1 changes [1/2 done] ----7:01:46AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default7:01:46AM: ^ Waiting for 1 unavailable replicas7:01:46AM: L ok: waiting on replicaset/simple-app-765bb9c475 (apps/v1) namespace: default7:01:46AM: L ongoing: waiting on pod/simple-app-765bb9c475-fv62b (v1) namespace: default7:01:46AM: ^ Pending: ContainerCreating7:01:54AM: ok: reconcile deployment/simple-app (apps/v1) namespace: default7:01:54AM: ---- applying complete [2/2 done] ----7:01:54AM: ---- waiting complete [2/2 done] ----
Succeeded
Vous remarquez que kapp
attend bien que les ressources passent au status
complete
avant de rendre la main avec le code retour associé.
Lister les applications installées
La commande list
permet d’afficher toutes les applications déployées avec kapp
sur un cluster dans le namespace actuel :
kapp lsTarget cluster 'https://10.240.0.10:6443' (nodes: master1, 1+)
Apps in namespace 'default'
Name Namespaces Lcs Lcasimple-app default true 6m
Lcs: Last Change SuccessfulLca: Last Change Age
1 apps
Succeeded
Cette commande peut prendre deux options pour afficher les applications d’un
namespace : -n <namespace>
et -A
pour tous les namespaces.
Inspecter les applications
kapp
permet d’afficher bien plus d’informations d’une application avec la
commande inspect
qui possède quelques options bien sympathiques :
kapp inspect -a simple-app --treeTarget cluster 'https://10.240.0.10:6443' (nodes: master1, 1+)
Resources in app 'simple-app'
Namespace Name Kind Owner Conds. Rs Ri Agedefault simple-app Deployment kapp 2/2 t ok - 14mdefault L simple-app-765bb9c475 ReplicaSet cluster - ok - 14mdefault L.. simple-app-765bb9c475-fv62b Pod cluster 4/4 t ok - 14mdefault simple-app Service kapp - ok - 14mdefault L simple-app Endpoints cluster - ok - 14mdefault L simple-app-mrbcg EndpointSlice cluster - ok - 14m
Rs: Reconcile stateRi: Reconcile information
6 resources
Succeeded
Notez qu’il reconnaît aussi les ressources qu’il n’a pas créées directement
comme le ReplicaSet
et le Endpoints
.
Afficher les logs d’une application
Vous allez voir tout de suite le bénéfice d’utiliser kapp
pour afficher les
logs d’une application. Il existe des alternatives comme
stern qui peut produire le même résultat. Kapp
s’appuie sur les labels qu’il a posés lors du déploiement pour afficher les logs
des différents pods qui compose une application.
Avant on va passer à trois réplicas :
kubectl scale deployment simple-app --replicas 3deployment.apps/simple-app scaledTarget cluster 'https://127.0.0.1:35919' (nodes: kind-control-plane)
# starting tailing 'simple-app-64bbd6695f-tc25z > simple-app' logs# starting tailing 'simple-app-64bbd6695f-cw7l8 > simple-app' logs# starting tailing 'simple-app-64bbd6695f-wdz2p > simple-app' logssimple-app-64bbd6695f-wdz2p > simple-app | 2022/01/27 07:52:33 Server started# ending tailing 'simple-app-64bbd6695f-wdz2p > simple-app' logssimple-app-64bbd6695f-tc25z > simple-app | 2022/01/27 07:57:50 Server started# ending tailing 'simple-app-64bbd6695f-tc25z > simple-app' logssimple-app-64bbd6695f-cw7l8 > simple-app | 2022/01/27 07:57:50 Server started# ending tailing 'simple-app-64bbd6695f-cw7l8 > simple-app' logs
Succeeded
Utilisation de kapp avec des templates
kapp
peut utiliser des templates
comme source de déclaration. Ici nous allons
utiliser ytt
, mais ca fonctionne aussi avec helm
.
Nous allons utiliser un fichier d’overlay qui vient modifier certaines propriétés du manifest.
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"kind": "Deployment"})---spec: #@overlay/match missing_ok=True replicas: 3
kapp deploy -a simple-app -c -f <(ytt template -f config-step-2-template/ -f config-step-2a-overlays/custom-scale.yml)
Target cluster 'https://127.0.0.1:35919' (nodes: kind-control-plane)
@@ update deployment/simple-app (apps/v1) namespace: default @@ ...103,103 spec:104 - progressDeadlineSeconds: 600105,104 replicas: 3106 - revisionHistoryLimit: 10107,105 selector:108,106 matchLabels: ...110,108 simple-app: ""111 - strategy:112 - rollingUpdate:113 - maxSurge: 25%114 - maxUnavailable: 25%115 - type: RollingUpdate116,109 template:117,110 metadata:118 - creationTimestamp: null119,111 labels:120,112 kapp.k14s.io/app: "1643269818769218079" ...128,120 image: docker.io/dkalinin/k8s-simple-app@sha256:4c8b96d4fffdfae29258d94a22ae4ad1fe36139d47288b8960d9958d1e63a9d0129 - imagePullPolicy: IfNotPresent130,121 name: simple-app131 - resources: {}132 - terminationMessagePath: /dev/termination-log133 - terminationMessagePolicy: File134 - dnsPolicy: ClusterFirst135 - restartPolicy: Always136 - schedulerName: default-scheduler137 - securityContext: {}138 - terminationGracePeriodSeconds: 30139,122 status:140,123 availableReplicas: 3
Changes
Namespace Name Kind Conds. Age Op Op st. Wait to Rs Ridefault simple-app Deployment 2/2 t 9m update - reconcile ok -
Op: 0 create, 0 delete, 1 update, 0 noop, 0 existsWait to: 1 reconcile, 0 delete, 0 noop
Continue? [yN]: y8:01:10AM: ---- applying 1 changes [0/1 done] ----8:01:10AM: update deployment/simple-app (apps/v1) namespace: default8:01:10AM: ---- waiting on 1 changes [0/1 done] ----8:01:11AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default8:01:11AM: ^ Waiting for generation 7 to be observed8:01:11AM: L ok: waiting on replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:01:11AM: L ok: waiting on replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:01:11AM: L ok: waiting on replicaset/simple-app-549947d777 (apps/v1) namespace: default8:01:11AM: L ok: waiting on pod/simple-app-64bbd6695f-wdz2p (v1) namespace: default8:01:11AM: L ok: waiting on pod/simple-app-64bbd6695f-tc25z (v1) namespace: default8:01:11AM: L ok: waiting on pod/simple-app-64bbd6695f-cw7l8 (v1) namespace: default8:01:11AM: L ongoing: waiting on pod/simple-app-549947d777-8rzh8 (v1) namespace: default8:01:11AM: ^ Pending8:01:12AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default8:01:12AM: ^ Waiting for 1 unavailable replicas8:01:12AM: L ok: waiting on replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:01:12AM: L ok: waiting on replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:01:12AM: L ok: waiting on replicaset/simple-app-549947d777 (apps/v1) namespace: default8:01:12AM: L ok: waiting on pod/simple-app-64bbd6695f-wdz2p (v1) namespace: default8:01:12AM: L ok: waiting on pod/simple-app-64bbd6695f-tc25z (v1) namespace: default8:01:12AM: L ok: waiting on pod/simple-app-64bbd6695f-cw7l8 (v1) namespace: default8:01:12AM: L ongoing: waiting on pod/simple-app-549947d777-8rzh8 (v1) namespace: default8:01:12AM: ^ Pending: ContainerCreating8:01:13AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default8:01:13AM: ^ Waiting for 1 unavailable replicas8:01:13AM: L ok: waiting on replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:01:13AM: L ok: waiting on replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:01:13AM: L ok: waiting on replicaset/simple-app-549947d777 (apps/v1) namespace: default8:01:13AM: L ok: waiting on pod/simple-app-64bbd6695f-wdz2p (v1) namespace: default8:01:13AM: L ok: waiting on pod/simple-app-64bbd6695f-tc25z (v1) namespace: default8:01:13AM: L ok: waiting on pod/simple-app-64bbd6695f-cw7l8 (v1) namespace: default8:01:13AM: L ok: waiting on pod/simple-app-549947d777-8rzh8 (v1) namespace: default8:01:14AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default8:01:14AM: ^ Waiting for 1 unavailable replicas8:01:14AM: L ok: waiting on replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:01:14AM: L ok: waiting on replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:01:14AM: L ok: waiting on replicaset/simple-app-549947d777 (apps/v1) namespace: default8:01:14AM: L ok: waiting on pod/simple-app-64bbd6695f-wdz2p (v1) namespace: default8:01:14AM: L ongoing: waiting on pod/simple-app-64bbd6695f-tc25z (v1) namespace: default8:01:14AM: ^ Deleting8:01:14AM: L ok: waiting on pod/simple-app-64bbd6695f-cw7l8 (v1) namespace: default8:01:14AM: L ongoing: waiting on pod/simple-app-549947d777-vz4hx (v1) namespace: default8:01:14AM: ^ Pending: ContainerCreating8:01:14AM: L ok: waiting on pod/simple-app-549947d777-8rzh8 (v1) namespace: default8:01:17AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default8:01:17AM: ^ Waiting for 1 unavailable replicas8:01:17AM: L ok: waiting on replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:01:17AM: L ok: waiting on replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:01:17AM: L ok: waiting on replicaset/simple-app-549947d777 (apps/v1) namespace: default8:01:17AM: L ok: waiting on pod/simple-app-64bbd6695f-wdz2p (v1) namespace: default8:01:17AM: L ongoing: waiting on pod/simple-app-64bbd6695f-tc25z (v1) namespace: default8:01:17AM: ^ Deleting8:01:17AM: L ongoing: waiting on pod/simple-app-64bbd6695f-cw7l8 (v1) namespace: default8:01:17AM: ^ Deleting8:01:17AM: L ok: waiting on pod/simple-app-549947d777-vz4hx (v1) namespace: default8:01:17AM: L ok: waiting on pod/simple-app-549947d777-8rzh8 (v1) namespace: default8:01:17AM: L ongoing: waiting on pod/simple-app-549947d777-7hldh (v1) namespace: default8:01:17AM: ^ Pending: ContainerCreating8:01:20AM: ok: reconcile deployment/simple-app (apps/v1) namespace: default8:01:20AM: ---- applying complete [1/1 done] ----8:01:20AM: ---- waiting complete [1/1 done] ----
Succeeded
Vraiment sympa la sortie au format diff
qui affiche toutes les modifications
qui vont être appliqué.
Afficher l’historique des modifications
Pour afficher l’historique des modifications des applications on utilise la
commande app-change list
:
kapp app-change list -a simple-appTarget cluster 'https://10.240.0.10:6443' (nodes: master1, 1+)
App changes
Name Started At Finished At Successful Descriptionsimple-app-change-k98bc 2022-01-27T09:56:19Z 2022-01-27T09:56:23Z true update: Op: 0 create, 0 delete, 1 update, 0 noop, 0 exists / Wait to: 1 reconcile, 0 delete, 0 noopsimple-app-change-l4fwv 2022-01-27T09:05:44Z 2022-01-27T09:05:50Z true update: Op: 2 create, 0 delete, 0 update, 0 noop, 0 exists / Wait to: 2 reconcile, 0 delete, 0 noop
2 app changes
Succeeded
Supprimer une application
Pour effacer une application rien de plus simple il suffit d’utiliser la
commande delete
:
kapp delete -a simple-appTarget cluster 'https://127.0.0.1:35919' (nodes: kind-control-plane)
Changes
Namespace Name Kind Conds. Age Op Op st. Wait to Rs Ridefault simple-app Deployment 2/2 t 18m delete - delete ok -^ simple-app Endpoints - 18m - - delete ok -^ simple-app Service - 18m delete - delete ok -^ simple-app-549947d777 ReplicaSet - 7m - - delete ok -^ simple-app-5f8db95765 ReplicaSet - 18m - - delete ok -^ simple-app-64bbd6695f ReplicaSet - 16m - - delete ok -^ simple-app-64bbd6695f-ptkqs Pod 4/4 t 2m - - delete ok -^ simple-app-64bbd6695f-qlfkl Pod 4/4 t 2m - - delete ok -^ simple-app-64bbd6695f-v8fhl Pod 4/4 t 2m - - delete ok -^ simple-app-xt22j EndpointSlice - 18m - - delete ok -
Op: 0 create, 2 delete, 0 update, 8 noop, 0 existsWait to: 0 reconcile, 10 delete, 0 noop
Continue? [yN]: y
8:09:15AM: ---- applying 10 changes [0/10 done] ----8:09:15AM: noop pod/simple-app-64bbd6695f-qlfkl (v1) namespace: default8:09:15AM: noop replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:09:15AM: noop pod/simple-app-64bbd6695f-ptkqs (v1) namespace: default8:09:15AM: noop pod/simple-app-64bbd6695f-v8fhl (v1) namespace: default8:09:15AM: noop replicaset/simple-app-549947d777 (apps/v1) namespace: default8:09:15AM: noop endpoints/simple-app (v1) namespace: default8:09:15AM: noop endpointslice/simple-app-xt22j (discovery.k8s.io/v1) namespace: default8:09:15AM: noop replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:09:16AM: delete deployment/simple-app (apps/v1) namespace: default8:09:16AM: delete service/simple-app (v1) namespace: default8:09:16AM: ---- waiting on 10 changes [0/10 done] ----8:09:16AM: ongoing: delete pod/simple-app-64bbd6695f-v8fhl (v1) namespace: default8:09:16AM: ok: delete service/simple-app (v1) namespace: default8:09:16AM: ongoing: delete replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:09:16AM: ongoing: delete pod/simple-app-64bbd6695f-qlfkl (v1) namespace: default8:09:16AM: ongoing: delete replicaset/simple-app-549947d777 (apps/v1) namespace: default8:09:16AM: ongoing: delete pod/simple-app-64bbd6695f-ptkqs (v1) namespace: default8:09:16AM: ongoing: delete endpointslice/simple-app-xt22j (discovery.k8s.io/v1) namespace: default8:09:16AM: ongoing: delete replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:09:16AM: ok: delete deployment/simple-app (apps/v1) namespace: default8:09:16AM: ok: delete endpoints/simple-app (v1) namespace: default8:09:16AM: ---- waiting on 7 changes [3/10 done] ----8:09:16AM: ok: delete replicaset/simple-app-5f8db95765 (apps/v1) namespace: default8:09:16AM: ok: delete replicaset/simple-app-549947d777 (apps/v1) namespace: default8:09:16AM: ok: delete replicaset/simple-app-64bbd6695f (apps/v1) namespace: default8:09:16AM: ok: delete endpointslice/simple-app-xt22j (discovery.k8s.io/v1) namespace: default8:09:16AM: ---- waiting on 3 changes [7/10 done] ----8:09:23AM: ok: delete pod/simple-app-64bbd6695f-ptkqs (v1) namespace: default8:09:23AM: ok: delete pod/simple-app-64bbd6695f-qlfkl (v1) namespace: default8:09:23AM: ---- waiting on 1 changes [9/10 done] ----8:09:24AM: ok: delete pod/simple-app-64bbd6695f-v8fhl (v1) namespace: default8:09:24AM: ---- applying complete [10/10 done] ----8:09:24AM: ---- waiting complete [10/10 done] ----
Succeeded
Vous remarquez il détruit toute trace de tout ce qui a été déployé avec kapp.
Conclusion
kapp
a vraiment du potentiel et je pense que je vais l’intégrer dans ma liste
de pépites. Il manque le moyen de faire un rollback rapidement. Dans un
prochain billet nous verrons la partie gitops de kapp
.