如何判断为什么 Kubernetes 活性探测得到 HTTP 503 而日志显示 200 OK?

如何判断为什么 Kubernetes 活性探测得到 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 不会报告因超出内存限制而被终止的容器(根据文档的 lastState 报告) 对我来说仍是一个问题。
  • 日志可能不会显示任何 503 答案的输出,因为容器在将其写入 stdout/stderr 之前就被 Docker 守护进程杀死了。
  • 如果内存不足是原因,我仍然无法理解这里事件的顺序,因为它确实首先收到正常关闭信号,并且 kubelet 将响应记录为 503(而不是超时)。

即使这是原因,对于 Kubernetes 管理员来说,追查它也会是一个非常糟糕的用户体验。

相关内容