Назад | Перейти на главную страницу

Как узнать, почему зонд живучести Kubernetes получает HTTP 503, а в журналах отображается 200 OK?

Я развернул модуль с Apache httpd (официальное изображение, тег 2.4.41), обслуживающий открытый текст HTTP / 2.0 на порту 8082, и он работает "нормально", но я вижу перезапуски каждые несколько часов (kubectl get pod/mypod, показывающее 60 перезапусков за 5 дней).

Журналы всегда показывают "поймал SIGWINCH, изящно выключился" (-p, для предыдущего пакета):

$ 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, похоже, не согласен с 200 OK от Apache и намеренно перезапускает под:

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

После того, как вы все больше и больше копаетесь в этом, кажется, что демон 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, потому что контейнер уничтожается демоном Docker до того, как он записал его в stdout / stderr.
  • Я все еще не могу понять последовательность событий здесь, если причиной является нехватка памяти, потому что сначала он получает сигнал плавного выключения, а ответ регистрируется как 503 с помощью kubelet (не по таймауту).

Даже если это причина, для администратора Kubernetes это очень плохой UX, чтобы выследить его.