Comment résoudre les problèmes de réactivité et de disponibilité des sondes liées à mes clusters Amazon EKS ?

Lecture de 7 minute(s)
0

Je souhaite résoudre les problèmes liés aux sondes de réactivité et de disponibilité dans mon cluster Amazon Elastic Kubernetes Service (Amazon EKS).

Brève description

Les kubelets qui s'exécutent sur les composants master utilisent des sondes pour vérifier régulièrement l'état des pods. Kubernetes prend actuellement en charge trois états dans les enquêtes : réussite, échec et inconnu. Kubelet considère que le pod est réussi ou sain dans les conditions suivantes :

  • L'application exécutée dans le conteneur est prête.
  • L'application accepte le trafic et répond aux sondes définies dans le manifeste du pod.

Kubelet considère qu'un pod d'application est défaillant ou défectueux lorsque la sonde ne répond pas. Kubelet marque alors ce pod comme étant défectueux et envoie SIGTERM au pod. L'une des situations suivantes se produit en fonction de la politique de cycle de vie et de la politique de redémarrage définies lors du déploiement :

  • Le module se termine immédiatement.
  • Le module s'arrête automatiquement après son arrêt pour accepter le trafic.

Exemple :

spec:
 containers:
 - name: "example-container"
  image: "example-image"
  lifecycle:
   preStop:
    exec:
     command: ["sh", "-c", "sleep 10"]

Dans cet exemple, si le container d'exemple qui s'exécute dans example-pod devient défectueux en ne répondant pas aux sondes, le pod cesse d'accepter le trafic en 10 secondes. Ensuite, Kubelet arrête gracieusement le pod. Si le pod n'est pas arrêté même après 30 secondes, kubelet retire le pod avec force. Kubelet considère le pod de l'application comme inconnu lorsque kubelet ne peut pas déterminer l'état du pod à l'aide des sondes définies dans le manifeste de déploiement. Dans ce cas, kubelet effectue des vérifications supplémentaires pour déterminer l'état du pod.

Kubernetes fournit des vérifications sur la sonde de réactivité, la sonde de préparation et la sonde de démarrage.

  • Kubelet utilise des sondes de réactivité pour connaître l'état de l'application qui s'exécute dans votre pod.
  • Kubelet utilise des sondes de disponibilité pour savoir quand votre application est prête à commencer à traiter le trafic entrant.
  • Kubelet utilise des sondes de démarrage pour les applications qui démarrent lentement à l'intérieur du pod. Lorsqu'une sonde de démarrage est configurée, les sondes de réactivité et de disponibilité ne vérifient pas le pod tant que le démarrage n'est pas considéré comme réussi.

Si aucune de ces sondes n'est définie sur le manifeste du pod, kubelet marque indéfiniment les pods comme étant réussis ou sains. Vous pouvez configurer l'une des sondes suivantes pour vérifier l'état du pod :

  • Sonde HTTP
  • Sonde de commande
  • Sonde à prise TCP
  • Sonde gRPC

Résolution

Erreurs d'échec du contrôle de santé de l'application dues à des délais d'attente du client

Lorsque vos sondes de réactivité ou de disponibilité échouent, les messages d'erreur suivants s'affichent :

Liveness probe failed: Get "http://podIP:8080/health ": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Readiness probe failed: Get "http://podIP:8080/health ": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Pour résoudre ces erreurs, procédez comme suit :

Vérifiez si vous avez correctement configuré les sondes de réactivité et de disponibilité pour les modules d'application.

Si vous utilisez la version 1.11.0 ou ultérieure du CNI Amazon Virtual Private Cloud (Amazon VPC), assurez-vous que POD_SECURITY_GROUP_ENFORCING_MODE est défini en standard dans le aws-node DaemonSet. Si ce paramètre est incorrect, exécutez la commande suivante :

kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard

Assurez-vous de définir DISABLE_TCP_EARLY_DEMUX sur true pour amazon-k8s-cni-init, qui est le conteneur sous initcontainers lorsque les conditions suivantes sont remplies :

  • Vous utilisez une version CNI d'Amazon VPC antérieure à la version 1.11.0.
  • Vos pods sont configurés avec des groupes de sécurité.
  • ENABLE_POD_ENI est défini sur true.
kubectl patch daemonset aws-node -n kube-system \
-p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

Erreurs de défaillance du CNI Amazon VPC

Votre aws-node DaemonSet peut échouer avec les erreurs suivantes :

Liveness probe failed: OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: read init-p: connection reset by peer: unknown
Warning  Unhealthy  11m (x3 over 12m)    kubelet            Liveness probe failed:
Normal   Killing    11m                  kubelet            Container aws-node failed liveness probe, will be restarted

Readiness probe failed: OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: process_linux.go:99: starting setns process caused: fork/exec /proc/self/exe: resource temporarily unavailable: unknown
Warning  Unhealthy  11m (x9 over 13m)    kubelet            Readiness probe failed:

Vous pouvez résoudre ces erreurs en augmentant la valeur de timeoutSeconds à 60 secondes sur le aws-node DaemonSet.

Pour afficher les valeurs actuelles des champs dans le VPC CNI, exécutez la commande suivante :

$kubectl get daemonset aws-node -n kube-system -o yaml

Le résultat est similaire à ce qui suit :

"livenessProbe":
          exec:
            command:
            - /app/grpc-health-probe
            -addr=:50051
            -connect-timeout=5s
            -rpc-timeout=5s
          failureThreshold: 3
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 60

Erreurs de connexion à l'application

Lorsque vous exécutez la commande describe sur des modules d'applications personnalisés, les erreurs suivantes s'affichent si les pods ne répondent pas aux tests de réactivité et de disponibilité :

2m 25s Warning  Unhealthy  Liveness probe failed: Get "http://podIP:8081/health ": dial tcp 192.168.187.28: 8081: connect: connection refused

2m 25s Warning  Unhealthy   Readiness probe failed: Get "http:// podIP:8081/health": dial tcp 192.168.187.28:8081: connect: connection refused

Warning  Unhealthy  39s (x4 over 2m19s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500

Warning  Unhealthy  29s (x5 over 2m19s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 500

Pour résoudre cette erreur, procédez comme suit :

1.    Décourbez manuellement le chemin de surveillance de l’état défini sur le manifeste du pod à partir du composant master.

[ec2-user@ip-10-0-0-11 ~]$ curl -ikv podIP:8081/health

2.    Exécutez dans le module d'application qui échoue aux sondes de réactivité ou de disponibilité. Ensuite, tracez le chemin de surveillance de l’état défini dans le manifeste du pod :

local@bastion-host ~ % kubectl exec <pod-name> -- curl  -ikv "http://localhost:8081/_cluster/health?"

3.    Vérifiez les journaux kubelet du composant master sur lequel le pod s'exécute pour détecter toute erreur :

[ec2-user@ip-10-0-0-11 ~]$ journalctl -u kubelet //optionally 'grep' with pod name

4.    Exécutez la commande describe pod sur le pod et vérifiez l'état actuel des conteneurs qui s'exécutent dans le pod. Consultez également les journaux du pod :

$ kubectl describe pod <pod name> -n <namespace>

$ kubectl logs <pod name>

5.    Si vous ne disposez toujours pas d'informations sur l'erreur, pensez à augmenter la verbosité du kubelet sous-jacent qui s'exécute sur le composant master :

$ sudo systemctl status kubelet
$ vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf 
   [Service]
   Environment='KUBELET_ARGS=--node-ip=192.168.31.211 --pod-infra-container-image=602401143452.dkr.ecr.us-east-2.amazonaws.com/eks/pause:3.5 --v=2'

Dans le fichier de configuration, remplacez --v=2 par --v=9, puis enregistrez le fichier.

Redémarrez les kubelets pour que les modifications prennent effet :

$ sudo systemctl daemon-reload && sudo systemctl restart kubelet && sudo systemctl enable kubelet

Exécutez la commande suivante pour vérifier la verbosité du kubelet :

$ systemctl status kubelet -l

La sortie doit ressembler à ce qui suit :

CGroup: /system.slice/kubelet.service 
       └─5909 /usr/bin/kubelet --cloud-provider aws --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --container-runtime docker --network-plugin cni --node-ip=10.0.0.11 --pod-infra-container-image=602401143452.dkr.ecr.us-east-1.amazonaws.com/eks/pause:3.1-eksbuild.1 --v=9

Redémarrez le pod défaillant en vérifiant son état de réactivité ou son état de préparation. Assurez-vous ensuite que ce module est déployé sur le composant master Amazon EKS où les modifications précédentes ont été apportées. Vous pouvez vérifier le journal kubelet en exécutant la commande suivante :

$ journalctl -u kubelet //optionally 'grep' with pod name

6.    Exécutez la même image de conteneur sur Bastion Host et vérifiez si vous pouvez incurver le chemin de surveillance de l’état défini sur les sondes dans le manifeste. Vérifiez également les journaux des conteneurs.

7.    Pour les sondes HTTP, vérifiez si l'en-tête http personnalisé est correctement configuré. Kubelet utilise le code golang équivalent à curl pour tester HTTP votre pod.

Exemple :

"livenessProbe":
   httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

8.    Si vous utilisez une sonde Exec, vérifiez si votre pod est correctement configuré. Dans l'exemple suivant, le module passe pendant 30 secondes, puis échoue :

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a un an