Assurez-vous que vous êtes dans le bon espace de noms :
kubectl config set-context --current --namespace=myspace
Assurez-vous que rien d’autre n’est déployé :
kubectl get all
No resources found in myspace namespace.
Déployez une application avec le jeu de sondes Live and Ready :
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: myboot
spec:
replicas: 3
selector:
matchLabels:
app: myboot
template:
metadata:
labels:
app: myboot
env: dev
spec:
containers:
- name: myboot
image: quay.io/rhdevelopers/myboot:v1
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
requests:
memory: "300Mi"
cpu: "250m" # 1/4 core
limits:
memory: "400Mi"
cpu: "1000m" # 1 core
livenessProbe:
httpGet:
port: 8080
path: /
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 3
EOF
Décrivez le déploiement :
kubectl describe deployment myboot
...
Image: quay.io/rhdevelopers/myboot:v1
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 1
memory: 400Mi
Requests:
cpu: 250m
memory: 300Mi
Liveness: http-get http://:8080/ delay=10s timeout=2s period=5s #success=1 #failure=3
Readiness: http-get http://:8080/health delay=10s timeout=1s period=3s #success=1 #failure=3
...
Déployer un service :
kubectl apply -f apps/kubefiles/myboot-service.yml
Créer les variables IP et PORT
IP=$(minikube ip)
PORT=$(kubectl get service/myboot -o jsonpath="{.spec.ports[*].nodePort}")
Réaliser une requete sur le service :
curl $IP:$PORT
Et lancez le script de la boucle :
while true
do curl $IP:$PORT
sleep .3
done
Changez l’image :
kubectl set image deployment/myboot myboot=quay.io/rhdevelopers/myboot:v2
Et remarquez la mise à jour sans erreur :
Aloha from Spring Boot! 131 on myboot-845968c6ff-k4rvb
Aloha from Spring Boot! 134 on myboot-845968c6ff-9wvt9
Aloha from Spring Boot! 122 on myboot-845968c6ff-9824z
Bonjour from Spring Boot! 0 on myboot-8449d5468d-m88z4
Bonjour from Spring Boot! 1 on myboot-8449d5468d-m88z4
Aloha from Spring Boot! 135 on myboot-845968c6ff-9wvt9
Aloha from Spring Boot! 133 on myboot-845968c6ff-k4rvb
Aloha from Spring Boot! 137 on myboot-845968c6ff-9wvt9
Bonjour from Spring Boot! 3 on myboot-8449d5468d-m88z4
Regardez les points d’extrémité pour voir quels pods font partie du service :
kubectl get endpoints myboot -o json | jq '.subsets[].addresses[].ip'
Ce sont les IP des Pods qui ont passé leur test de préparation :
"10.129.2.40"
"10.130.2.37"
"10.130.2.38"
Exec en un seul Pod et changer son indicateur de disponibilité :
kubectl exec -it myboot-845968c6ff-k5lcb /bin/bash
curl localhost:8080/misbehave
exit
Vérifiez que le pod n’est plus prêt :
NAME READY STATUS RESTARTS AGE
myboot-845968c6ff-9wshg 1/1 Running 0 11m
myboot-845968c6ff-k5lcb 0/1 Running 0 12m
myboot-845968c6ff-zsgx2 1/1 Running 0 11m
Maintenant, vérifiez les points de terminaison :
kubectl get endpoints myboot -o json | jq '.subsets[].addresses[].ip'
Et ce pod est maintenant absent de l’équilibreur de charge du service :
"10.130.2.37"
"10.130.2.38"
Ce qui est aussi une évidence dans la boucle de la boucle :
Aloha from Spring Boot! 845 on myboot-845968c6ff-9wshg
Aloha from Spring Boot! 604 on myboot-845968c6ff-zsgx2
Aloha from Spring Boot! 846 on myboot-845968c6ff-9wshg
kubectl set image deployment/myboot myboot=quay.io/rhdevelopers/myboot:v3
Laissez le déploiement se terminer sur les 3 répliques :
watch kubectl get pods
NAME READY STATUS RESTARTS AGE
myboot-56659c9d69-6sglj 1/1 Running 0 2m2s
myboot-56659c9d69-mdllq 1/1 Running 0 97s
myboot-56659c9d69-zjt6q 1/1 Running 0 72s
Et comme on le voit dans la boucle de curl/poller :
Jambo from Spring Boot! 40 on myboot-56659c9d69-mdllq
Jambo from Spring Boot! 26 on myboot-56659c9d69-zjt6q
Jambo from Spring Boot! 71 on myboot-56659c9d69-6sglj
Modifiez le déploiement pour qu’il pointe vers l’URL /alive :
kubectl edit deployment myboot
Et changez la sonde de Liveness probe :
...
spec:
containers:
- image: quay.io/rhdevelopers/myboot:v3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: /alive
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 2
name: myboot
...
Sauvegardez et fermez l’éditeur, ce qui permet à cette modification d’être appliquée.
watch kubectl get pods
NAME READY STATUS RESTARTS AGE
myboot-558b4f8678-nw762 1/1 Running 0 59s
myboot-558b4f8678-qbrgc 1/1 Running 0 81s
myboot-558b4f8678-z7f9n 1/1 Running 0 36s
Maintenant, choisissez un pod, exécutez-la et tirez dessus :
kubectl exec -it myboot-558b4f8678-qbrgc /bin/bash
curl localhost:8080/shot
Et vous verrez qu’il sera redémarré :
NAME READY STATUS RESTARTS AGE
myboot-558b4f8678-nw762 1/1 Running 0 4m7s
myboot-558b4f8678-qbrgc 1/1 Running 1 4m29s
myboot-558b4f8678-z7f9n 1/1 Running 0 3m44s
De plus, votre exécution sera terminée :
kubectl exec -it myboot-558b4f8678-qbrgc /bin/bash
curl localhost:8080/shot
I have been shot in the head1000610000@myboot-558b4f8678-qbrgc:/app$ command terminated with exit code 137
Et vos utilisateurs finaux ne verront pas d’erreurs :
Jambo from Spring Boot! 174 on myboot-558b4f8678-z7f9n
Jambo from Spring Boot! 11 on myboot-558b4f8678-qbrgc
Jambo from Spring Boot! 12 on myboot-558b4f8678-qbrgc
Jambo from Spring Boot! 206 on myboot-558b4f8678-nw762
Jambo from Spring Boot! 207 on myboot-558b4f8678-nw762
Jambo from Spring Boot! 175 on myboot-558b4f8678-z7f9n
Jambo from Spring Boot! 176 on myboot-558b4f8678-z7f9n
Supprimer les ressources
kubectl delete deployment myboot
kubectl delete service myboot
Certaines applications nécessitent un temps de démarrage supplémentaire lors de leur première initialisation.
Il peut s’avérer difficile d’intégrer ce scénario dans les sondes de disponibilité/préparation car vous devez les configurer pour qu’elles aient un comportement normal afin de détecter les anomalies pendant le temps d’exécution et, en outre, pour couvrir le long temps de démarrage.
Les sondes de démarrage résolvent ce problème, car une fois que la sonde de démarrage a réussi, le reste des sondes prend le relais.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: myboot
spec:
replicas: 1
selector:
matchLabels:
app: myboot
template:
metadata:
labels:
app: myboot
env: dev
spec:
containers:
- name: myboot
image: quay.io/rhdevelopers/myboot:zoombie
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
requests:
memory: "300Mi"
cpu: "250m" # 1/4 core
limits:
memory: "400Mi"
cpu: "1000m" # 1 core
livenessProbe:
httpGet:
port: 8080
path: /
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 3
startupProbe:
httpGet:
path: /alive
port: 8080
failureThreshold: 12
periodSeconds: 5
EOF
La sonde de démarrage attend une minute (5 * 12) pour démarrer l’application.
L’application actuelle renvoie une erreur 503 dans le endpoint /alive, elle ne réussira donc jamais à démarrer et la restartPolicy est appliquée.
watch kubectl get pods
NAME READY STATUS RESTARTS AGE
myboot-579cc5cc47-2bk5p 0/1 Running 0 67s
Attendez 60 secondes jusqu’à ce que vous voyiez que le pod est redémarré.
Et vous verrez qu’il a redémarré :
NAME READY STATUS RESTARTS AGE
myboot-579cc5cc47-2bk5p 0/1 Running 1 3m7s
Pour que le pod réussisse, exécutez-la et faites-la renaître :
kubectl exec -it myboot-579cc5cc47-2bk5p /bin/bash
curl localhost:8080/reborn
Et enfin, c’est parti :
NAME READY STATUS RESTARTS AGE
myboot-579cc5cc47-2bk5p 1/1 Running 1 3m41s
Décrire le pod pour obtenir les statistiques des sondes :
kubectl describe pod myboot-579cc5cc47-2bk5p
Limits:
cpu: 1
memory: 400Mi
Requests:
cpu: 250m
memory: 300Mi
Liveness: http-get http://:8080/ delay=10s timeout=2s period=5s #success=1 #failure=3
Readiness: http-get http://:8080/health delay=10s timeout=1s period=3s #success=1 #failure=3
Startup: http-get http://:8080/alive delay=0s timeout=1s period=5s #success=1 #failure=12
Environment: <none>
Mounts:
Supprimer les ressources
kubectl delete deployment myboot