Wie kann man feststellen, warum die Kubernetes-Livetest-Messung HTTP 503 erhält, während die Protokolle 200 OK anzeigen?

Wie kann man feststellen, warum die Kubernetes-Livetest-Messung HTTP 503 erhält, während die Protokolle 200 OK anzeigen?

Ich habe einen Pod mit Apache httpd bereitgestellt (offizielles Bild, Tag 2.4.41), stellt HTTP/2.0-Klartext auf Port 8082 bereit und funktioniert „gut“, aber ich sehe alle paar Stunden Neustarts ( kubectl get pod/mypod, zeigt 60 Neustarts in 5 Tagen).

Die Protokolle zeigen immer„SIGWINCH erwischt, wird ordnungsgemäß heruntergefahren“( -p, für vorherigen Pod):

$ kubectl logs -c httpdcontainer -p pod/mypod
  [...]
  127.0.0.1 - - [15/Jan/2020:11:12:27 +0000] "GET / HTTP/2.0" 200 9578
  [Wed Jan 15 11:12:40.433582 2020] [mpm_event:notice] [pid 1:tid 139963289400448] AH00492: caught SIGWINCH, shutting down gracefully
  127.0.0.1 - - [15/Jan/2020:11:12:37 +0000] "GET / HTTP/2.0" 200 9578

Das SIGWINCH-Signal kommt wahrscheinlich von einem Stoppsignal über Docker (gemäß offiziellem Dockerfile), z. B. Kubernetes-Liveness-Test? Die GET-Anfragen sind die konfigurierten Liveness-Tests auf /, aber wie Sie sehen, gibt Apache problemlos 200 OK zurück.

Kubernetes Kubelet scheint mit dem 200 OK von Apache nicht einverstanden zu sein und startet den Pod absichtlich neu:

$ kubectl describe pod/mypod
[...]
Type     Reason     Age                       From                                    Message
----     ------     ----                      ----                                    -------
Warning  Unhealthy  38m (x208 over 5d)        kubelet, node01.kube.mydomain.tld  Readiness probe failed: Get http://192.168.87.178:8082/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Normal   Killing    38m (x60 over 4d23h)      kubelet, node01.kube.mydomain.tld  Container docs failed liveness probe, will be restarted
Warning  Unhealthy  38m (x221 over 5d)        kubelet, node01.kube.mydomain.tld  Liveness probe failed: Get http://192.168.87.178:8082/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Normal   Pulled     38m (x60 over 4d23h)      kubelet, node01.kube.mydomain.tld  Container image "myregistry.mydomain.tld/foo/bar/myimage@sha256:<checksum>" already present on machine
Normal   Created    38m (x61 over 5d19h)      kubelet, node01.kube.mydomain.tld  Created container docs
Normal   Started    38m (x61 over 5d19h)      kubelet, node01.kube.mydomain.tld  Started container docs
Warning  Unhealthy  13m (x1644 over 5d19h)    kubelet, node01.kube.mydomain.tld  Readiness probe failed: HTTP probe failed with statuscode: 503
Warning  Unhealthy  3m16s (x1717 over 5d19h)  kubelet, node01.kube.mydomain.tld  Liveness probe failed: HTTP probe failed with statuscode: 503

Ich habe keine Ahnung, wie ich feststellen soll, was hier schuld ist. Ich verwende Kubernetes 1.16.4, bereitgestellt mit kubeadm und Calico CNI.

Antwort1

Bei genauerem Hinsehen stellt sich heraus, dass der Docker-Daemon den Container beendet hat, weil er das Speicherlimit überschritten hat, wie in den Systemprotokollen vermerkt:

Jan 15 12:12:40 node01 kernel: [2411297.634996] httpd invoked oom-killer: gfp_mask=0x14200ca(GFP_HIGHUSER_MOVABLE), nodemask=(null), order=0, oom_score_adj=998
[...]
Jan 15 12:12:40 node01 kernel: [2411297.672084] oom_reaper: reaped process 519 (httpd), now anon-rss:0kB, file-rss:0kB, shmem-rss:68kB
  • Warum httpd plötzlich das Speicherlimit überschreitet, bleibt eine Frage, die hier jedoch nicht Gegenstand des Artikels ist.
  • Warum Kubernetes nicht meldet, dass der Container beendet wird, weil er das Speicherlimit überschritten hat (lastState-Bericht gemäß Dokumenten) bleibt für mich eine Frage.
  • In den Protokollen wird wahrscheinlich die Ausgabe einer 503-Antwort nicht angezeigt, da der Container vom Docker-Daemon beendet wird, bevor er ihn in stdout/stderr geschrieben hat.
  • Ich verstehe immer noch nicht die Abfolge der Ereignisse, wenn nicht genügend Arbeitsspeicher die Ursache ist, da zuerst ein Signal zum ordnungsgemäßen Herunterfahren empfangen wird und die Antwort von Kubelet als 503 protokolliert wird (kein Timeout).

Selbst wenn dies die Ursache ist, ist es für den Kubernetes-Administrator eine sehr schlechte UX, danach zu suchen.

verwandte Informationen