Comment changer rapidement de contexte Kubernetes avec Kubectx et Kubens
Agence web » Actualités du digital » Comment utiliser les crochets Kubernetes pour suivre les cycles de vie des conteneurs

Comment utiliser les crochets Kubernetes pour suivre les cycles de vie des conteneurs

Les hooks de cycle de vie des conteneurs Kubernetes vous permettent de répondre aux créations et aux résiliations de conteneurs. Vous pouvez gérer les événements en exécutant une commande à l’intérieur du conteneur ou en envoyant une requête HTTP à un point de terminaison qu’il expose.

Les crochets sont couramment utilisés pour consigner les événements de conteneur, implémenter des scripts de nettoyage et exécuter des tâches asynchrones après qu’un nouveau pod a rejoint votre cluster. Dans cet article, nous montrerons comment attacher des gestionnaires de crochets à vos pods et mieux contrôler les cycles de vie des conteneurs.

Les deux crochets disponibles

Les versions actuelles de Kubernetes prennent en charge deux hooks de cycle de vie de conteneur :

  • PostStart – Les gestionnaires de ce crochet sont appelés immédiatement après la création d’un nouveau conteneur.
  • PreStop – Ce crochet est appelé immédiatement avant que Kubernetes ne termine un conteneur.

Ils peuvent être manipulés à l’aide de deux mécanismes différents :

  • Exec – Exécute une commande spécifiée à l’intérieur du conteneur.
  • HTTP – Envoie une requête HTTP à une URL à l’intérieur du conteneur.

Aucun des crochets ne fournit d’arguments à leurs gestionnaires. Chaque conteneur prend en charge un seul gestionnaire par crochet ; il n’est pas possible d’appeler plusieurs points de terminaison ou de combiner une commande exec avec une requête HTTP.

Définition des gestionnaires de hook

Vous définissez les gestionnaires de hook pour les pods en utilisant leur containers.lifecycle champ manifeste. Dans ce champ, définissez le postStart et preStop properties pour implémenter un ou les deux crochets disponibles.

Voici un pod simple qui enregistre un message lorsqu’il démarre :

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        postStart:
          exec:
            command: ["/bin/sh", "-c", "echo STARTED > /startup_message"]

Appliquez le pod à votre cluster à l’aide de Kubectl :

$ kubectl apply -f pod.yaml

Obtenez maintenant un shell pour le conteneur en cours d’exécution à l’intérieur du pod :

$ kubectl exec --stdin --tty pod/pod-with-hooks -- sh

Lire le contenu du /startup_message dossier:

$ cat /startup_message
STARTED

Cela démontre que le crochet a été appelé avec succès. Un hook exec est considéré comme réussi si sa commande se termine avec un code d’état zéro.

Gestionnaires HTTP

Vous pouvez configurer un gestionnaire HTTP en remplaçant le exec champ avec httpGet. Uniquement HTTP GET les requêtes sont prises en charge (il n’y a pas httpPost champ).

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        postStart:
          httpGet:
            path: /startup
            port: 80

Dans cet exemple, Kubernetes fait un GET demande à /startup sur le port 80 du conteneur. httpGet champ accepte également scheme et host properties pour configurer davantage la demande.

Voici un Pod où /shutdown est appelé via HTTPS avant l’arrêt du conteneur :

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        preStop:
          httpGet:
            path: /startup
            scheme: HTTPS

Les gestionnaires de hook HTTP sont réputés avoir réussi si le code de réponse HTTP se situe dans la plage 200-299.

Débogage de vos gestionnaires

Les gestionnaires de crochets sont gérés indépendamment des pods auxquels ils sont attachés. Leurs journaux ne sont ni collectés ni stockés avec les journaux de pod normaux, vous ne verrez donc pas de commandes exec telles que echo Started lors de la course kubectl logs pod/pod-with-hooks.

Vous pouvez déboguer les crochets en affichant l’historique des événements d’un pod. Les appels échoués seront signalés comme FailedPostStartHook et FailedPreStophook événements. Le message d’erreur comprend une description de ce qui a provoqué l’erreur.

Essayez d’ajouter ce pod à votre cluster :

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        postStart:
          exec:
            command: ["missing-command"]

Le hook PostStart cassé entraînera l’échec du démarrage du pod. Utilisation kubectl describe pour accéder à son historique d’événements :

$ kubectl describe pod/pod-with-hooks
...
Events:
  Type     Reason               Age                From               Message
  ----     ------               ----               ----               -------
  Normal   Scheduled            30s                default-scheduler  Successfully assigned pod-with-hooks...
  Normal   Created              10s (x2 over 11s)  kubelet            Created container pod-hook-container
  Normal   Started              10s (x2 over 11s)  kubelet            Started container pod-hook-container
  Warning  FailedPostStartHook  10s (x2 over 11s)  kubelet            Exec lifecycle hook ([missing-command]) for Container "pod-hook-container" in Pod "pod-with-hooks" failed - error: command 'missing-command' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "missing-command": executable file not found in $PATH: unknownrn"
  Normal   Killing              10s (x2 over 11s)  kubelet            FailedPostStartHook
  Warning  BackOff              5s (x2 over 6s)    kubelet            Back-off restarting failed container

La FailedPostStartHook révèle que le gestionnaire a échoué car missing-command n’est pas un exécutable valide à l’intérieur du conteneur. Cela a entraîné la suppression et le redémarrage du conteneur dans une boucle de back-off. Ça va être coincé comme ça perpétuellement comme missing-command ne sera jamais exécutable.

Les pièges à surveiller

Les invocations de hook ont ​​quelques caractéristiques qui peuvent vous surprendre. Les garder à l’esprit peut aider à éviter les comportements étranges et les échecs inattendus.

  • Les crochets peuvent être appelés plus d’une fois. Kubernetes garantit votre PostStart et PreStop les manutentionnaires seront appelés « au moins » une fois pour chaque conteneur. Dans certaines situations, un hook peut être appelé plusieurs fois. Vos gestionnaires doivent être idempotents afin qu’ils puissent supporter cette possibilité.
  • Les crochets ratés tuent leur conteneur. Comme l’illustre l’exemple de débogage ci-dessus, les hooks défaillants tuent immédiatement leur conteneur. Vous devez vous assurer que vos commandes et vos points de terminaison HTTP sont exempts d’erreurs pour éviter les problèmes de démarrage inattendus du pod. Les gestionnaires de crochets doivent être légers et exempts de dépendances. N’essayez pas d’accéder à une ressource qui pourrait ne pas être disponible immédiatement après le démarrage de votre conteneur.
  • PostStart les crochets font la course ENTRYPOINT. PostStart se déclenche à peu près au même moment que le conteneur est créé. Kubernetes n’attend pas le crochet cependant – il sera appelé de manière asynchrone à côté du conteneur ENTRYPOINT, qui peut se terminer avant que votre gestionnaire de hook ne soit appelé. Cela signifie que le script de point d’entrée de votre conteneur sera commencer à s’exécuter même si votre gestionnaire signale une erreur et finit par tuer le conteneur.
  • PreStop les crochets bloqueront la terminaison du conteneur. Kubernetes garantit que vos conteneurs ne se termineront pas avant leur PreStop les crochets sont terminés, jusqu’à une durée maximale définie par la période de grâce de résiliation du pod. Le conteneur sera résilié, que le hook soit toujours en cours d’exécution à la fin de la période de grâce.
  • PreStop les crochets ne sont pas nécessaires complété Gousses. Celui-ci peut être particulièrement impactant selon votre cas d’utilisation. La mise en œuvre actuelle de PreStop ne se déclenche que lorsqu’un pod est résilié en raison d’une suppression, d’un épuisement des ressources, d’un échec de sonde ou d’un événement similaire. Le crochet ne sera pas appelé pour les conteneurs qui s’arrêtent naturellement parce que leur processus termine sa tâche et se termine avec un code d’erreur nul.

Les crochets ont un impact direct sur la progression du cycle de vie de vos pods. Les pods ne peuvent pas être marqués comme Running jusqu’à leur PostStart le crochet se termine ; de même, un Pod sera bloqué Terminating jusqu’à PreStop avoir fini.

Conclusion

Les événements de cycle de vie Kubernetes sont un moyen d’informer les conteneurs de leur propre création et de leur suppression imminente. En fournissant des commandes ou des points de terminaison d’API à l’intérieur de votre conteneur, vous pouvez suivre les étapes critiques du cycle de vie et les signaler aux autres composants de votre infrastructure.

Les événements du cycle de vie sont faciles à configurer, mais ils présentent également des pièges courants. Vous pouvez utiliser des mécanismes adjacents tels que des sondes de démarrage et de préparation si vous avez besoin d’un appel plus fiable. Il s’agit d’une meilleure option pour les scripts essentiels lors de la préparation de l’environnement d’un nouveau conteneur.

★★★★★