如何判斷為什麼 Kubernetes liveness 探針會收到 HTTP 503 而日誌顯示 200 OK?

如何判斷為什麼 Kubernetes liveness 探針會收到 HTTP 503 而日誌顯示 200 OK?

我已經使用 Apache httpd 部署了一個 pod(官方圖片,標籤 2.4.41),在端口 8082 上提供 HTTP/2.0 純文本,並且工作“正常”,但我看到每隔幾個小時就會重新啟動一次(kubectl get pod/mypod,顯示 5 天內重新啟動 60 次)。

日誌總是顯示“捕捉到 SIGWINCH,優雅地關閉”-p,對於之前的 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

SIGWINCH 訊號可能來自 Docker 的停止訊號(根據官方 Dockerfile),例如 Kubernetes 活躍度探針? GET 請求是 / 上配置的活性探針,但正如您所看到的,Apache 返回 200 OK 就好了。

Kubernetes kubelet 似乎不同意 Apache 的 200 OK,並有意重新啟動 pod:

$ 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

我不知道該如何判斷這該歸咎於什麼。我使用的是 Kubernetes 1.16.4,使用 kubeadm 和 Calico CNI 部署。

答案1

經過深入研究後發現,Docker 守護程序正在終止容器,因為它超出了系統日誌中記錄的記憶體限制:

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
  • 為什麼 httpd 突然超過記憶體限制仍然是一個問題,但超出了這裡的範圍。
  • 為什麼 Kubernetes 不報告容器因超出記憶體限製而終止(根據文件進行最後狀態報告)對我來說仍然是一個問題。
  • 日誌可能不會顯示任何 503 答案的輸出,因為容器在將其寫入 stdout/stderr 之前就被 Docker 守護程序殺死了。
  • 如果記憶體不足是原因,我仍然無法理解這裡的事件順序,因為它確實首先收到一個正常關閉訊號,並且回應被 kubelet 記錄為 503(不是超時)。

即使這是原因,對於 Kubernetes 管理員來說,尋找它也是一個非常糟糕的使用者體驗。

相關內容