Wie behebe ich Probleme mit der Verfügbarkeit und der Bereitschaftsprüfung mit meinen Amazon-EKS-Clustern?

Lesedauer: 7 Minute
0

Ich möchte Probleme im Zusammenhang mit den Verfügbarkeits- und Bereitschaftstests in meinem Amazon-Elastic-Kubernetes-Service-Cluster (Amazon EKS) beheben.

Kurzbeschreibung

Kubelets, die auf den Worker-Knoten ausgeführt werden, verwenden Sonden, um den Pod-Status regelmäßig zu überprüfen. Kubernetes unterstützt derzeit drei Testzustände: erfolgreich, fehlgeschlagen und unbekannt. Kubelet betrachtet den Pod unter den folgenden Bedingungen als erfolgreich oder fehlerfrei:

  • Die Anwendung, die im Container ausgeführt wird, ist bereit.
  • Die Anwendung akzeptiert Datenverkehr und reagiert auf Tests, die im Pod-Manifest definiert sind.

Kubelet betrachtet einen Anwendungs-Pod als ausgefallen oder fehlerhaft, wenn die Sonde nicht reagiert. Kubelet markiert diesen Pod dann als fehlerhaft und sendet SIGTERM an den Pod. Je nach der Lifecycle-Richtlinie und der restartPolicy, die für die Bereitstellung definiert sind, geschieht eines der folgenden Ereignisse:

  • Der Pod wird sofort beendet.
  • Der Pod wird ordnungsgemäß heruntergefahren, nachdem er angehalten hat, um Verkehr anzunehmen.

Beispiel:

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

Wenn in diesem Beispiel der Example-Container, der in Example-Pod ausgeführt wird, nicht mehr funktionsfähig wird, weil er nicht auf Tests reagiert, nimmt der Pod innerhalb von 10 Sekunden keinen Verkehr mehr an. Dann fährt Kubelet den Pod elegant herunter. Wenn der Pod auch nach 30 Sekunden nicht beendet wird, entfernt Kubelet den Pod gewaltsam. Kubelet betrachtet den Anwendungs-Pod als unbekannt, wenn Kubelet den Status des Pods nicht mithilfe von Sonden ermitteln kann, die im Bereitstellungsmanifest definiert sind. In diesem Fall führt Kubelet zusätzliche Prüfungen durch, um den Pod-Status zu ermitteln.

Kubernetes bietet Testprüfungen für den Liveness-Test, Readiness-Test und Startup-Test.

  • Kubelet verwendet Liveness-Tests, um den Status der Anwendung zu ermitteln, die in Ihrem Pod ausgeführt wird.
  • Kubelet verwendet Bereitschaftstests, um festzustellen, wann Ihre Anwendung bereit ist, den eingehenden Datenverkehr zu verarbeiten.
  • Kubelet verwendet Startproben für langsam startende Anwendungen innerhalb des Pods. Wenn ein Startup-Test konfiguriert ist, überprüfen die Tests für Verfügbarkeit und Bereitschaft den Pod erst, wenn der Startup als erfolgreich angesehen wird.

Wenn keine dieser Tests im Pod-Manifest definiert ist, markiert Kubelet die Pods auf unbestimmte Zeit als erfolgreich oder fehlerfrei. Sie können einen der folgenden Tests konfigurieren, um den Zustand des Pods zu überprüfen:

  • HTTP-Sonde
  • Befehlssonde
  • TCP-Socket-Sonde
  • gRPC-Sonde

Lösung

Fehler bei der Anwendungszustandsprüfung aufgrund von Client-Timeouts

Wenn Ihre Liveness- oder Readiness-Tests fehlschlagen, erhalten Sie die folgenden Fehlermeldungen:

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)

Gehen Sie wie folgt vor, um diese Fehler zu beheben:

Überprüfen Sie, ob Sie die Liveness- und Readiness-Tests für die Anwendungs-Pods korrekt konfiguriert haben.

Wenn Sie die Amazon Virtual Private Cloud (Amazon VPC) CNI Version 1.11.0 oder höher verwenden, stellen Sie sicher, dass POD_SECURITY_GROUP_ENFORCING_MODE im AWS-Node-DaemonSet auf Standard gesetzt ist. Wenn diese Einstellung falsch ist, führen Sie den folgenden Befehl aus:

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

Stellen Sie sicher, dass DISABLE_TCP_EARLY_DEMUX für amazon-k8s-cni-init, das ist der Container unter initcontainers, auf wahr gesetzt ist, wenn die folgenden Bedingungen zutreffen:

  • Sie verwenden eine Amazon-VPC-CNI-Version, die älter als Version 1.11.0 ist.
  • Ihre Pods sind mit Sicherheitsgruppen konfiguriert.
  • ENABLE_POD_ENI ist auf wahr gesetzt.
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"}]}}}}'

Amazon-VPC-CNI-Ausfallfehler

Ihr AWS-Node-DaemonSet schlägt möglicherweise mit den folgenden Fehlern fehl:

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:

Sie können diese Fehler beheben, indem Sie den Wert von timeoutSeconds auf 60 Sekunden auf dem AWS-Node-DaemonSet erhöhen.

Führen Sie den folgenden Befehl aus, um die aktuellen Werte der Felder im VPC CNI anzuzeigen:

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

Die Ausgabe sieht wie folgt aus:

"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

Verbindungsfehler der Anwendung

Wenn Sie den Befehl describe auf benutzerdefinierten Anwendungs-Pods ausführen, erhalten Sie die folgenden Fehler, wenn die Pods die Prüfungen für die Verfügbarkeit und Bereitschaft nicht bestehen:

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

Gehen Sie wie folgt vor, um diesen Fehler zu beheben:

1.    Ruft den Pfad zur Gesundheitsprüfung, der im Pod-Manifest definiert ist, manuell vom Worker-Knoten aus.

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

2.    Führen Sie den Anwendungs-Pod aus, der die Liveness- oder Readiness-Tests nicht bestanden hat. Dann curlen Sie den Pfad zur Gesundheitsprüfung, der im Pod-Manifest definiert ist:

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

3.    Überprüfen Sie die Kubelet-Protokolle des Worker-Knotens, auf dem der Pod läuft, auf etwaige Fehler:

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

4.    Führen Sie den Befehl describe pod auf dem Pod aus und überprüfen Sie den aktuellen Status der Container, die im Pod ausgeführt werden. Überprüfen Sie auch die Pod-Protokolle:

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

$ kubectl logs <pod name>

5.    Wenn Sie immer noch keine Informationen zu dem Fehler haben, sollten Sie erwägen, die Ausführlichkeit des zugrunde liegenden Kubelets, das auf dem Worker-Knoten läuft, zu erhöhen:

$ 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'

Ändern Sie in der Konfigurationsdatei --v=2 in --v=9 und speichern Sie dann die Datei.

Starten Sie den Kubelet neu, damit die Änderungen wirksam werden:

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

Führen Sie den folgenden Befehl aus, um die Ausführlichkeit des Kubelets zu überprüfen:

$ systemctl status kubelet -l

Die Ausgabe muss wie folgt aussehen:

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

Starten Sie den Pod neu, der mit den Verfügbarkeits- oder Bereitschaftsprüfungen fehlschlägt. Stellen Sie dann sicher, dass dieser Pod auf dem Amazon-EKS-Worker-Knoten bereitgestellt wird, auf dem die vorherigen Änderungen vorgenommen wurden. Sie können die Kubelet-Protokolle überprüfen, indem Sie den folgenden Befehl ausführen:

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

6.    Führen Sie dasselbe Container-Image auf dem Bastion Host aus und prüfen Sie, ob Sie den Zustandsprüfpfad, der auf den Sonden in Manifest definiert ist, einschränken können. Überprüfen Sie auch die Container-Protokolle.

7.    Überprüfen Sie bei HTTP-Sonden, ob der benutzerdefinierte HTTP-Header korrekt konfiguriert ist. Kubelet verwendet den Golang-Code, der curl entspricht, um Ihren Pod auf HTTP zu testen.

Beispiel:

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

8.    Wenn Sie eine Exec-Sonde verwenden, überprüfen Sie, ob Ihr Pod richtig konfiguriert ist. Im folgenden Beispiel dauert der Pod 30 Sekunden und schlägt dann fehl:

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 OFFICIAL
AWS OFFICIALAktualisiert vor einem Jahr