K8S集群1.24使用docker作为容器运行时出现就绪探针间歇性异常


1. 环境介绍

组件 版本
kubernetes 1.24.2
docker 18.03.1-ce
cri-docker 0.2.6

2. 异常信息

  最近监测到 kubernetes 集群上 calico-node Pod 运行 2 天后就挂了,重启 calico-node 所在的云主机节点后,服务恢复正常,但是过 2 天后又挂了。查看 calico-node 的事件信息,错误提示如下所示:

(combined from similar events): Readiness probe errored: rpc error: code = Unknown 
desc = failed to exec in container: failed to create exec "d926d9226559a6673c1dbb904262c...398387ad3b04420": 
cannot exec in a stopped state: unknown

  kubernetes 提示 calico-node 就绪检测失败。

3. 分析问题

3.1 kubernetes 健康检查

  Kubernetes 有三种常见的健康检查探针,分别是:

  • Liveness:存活探针
  • Readiness:就绪探针
  • Startup:启动探针,1.18版本后引入新功能

3.1.1 存活探针

  kubelet 使用存活探针来确定什么时候要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

3.1.2 就绪探针

  kubelet 使用就绪探针可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

3.1.3 启动探针

  kubelet 使用启动探针来了解应用容器何时启动。 如果配置了这类探针,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探针不会影响应用的启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

3.2 检测方法

  • httpGet:向容器内服务发送HTTP请求进行健康检测
  • exec :到容器执行命令,进行健康检测
  • tcpSocket:向容器内服务发送Socket(TCP协议)请求进行健康检测
  • grpc:向容器内服务发送GRPC请求进行健康检测

  本次kubernetes 集群的异常出现在就绪检测探针,使用 exec 检测 calico-node Pod 异常,calico-node 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量,导致 calico-node 一直处于 Running 状态,但是 Ready 实例为 0,造成服务不可用。

  通过查阅相关文档资料,猜测问题可能出现在容器运行时,由于 kubernetes 推行 CRI (Container Runtime Interface)标准的容器运行时接口,但是 docker 并不支持 CRI 标准接口,但是 kubernetes 早期为了兼容 docker,于是开发了 docker shim 来适配 docker 容器。 kubernetes 1.22 以后的版本中移除了 docker shim 相关代码,导致了 kubernetes 1.22 以后的版本如果想要继续使用 docker 作为容器运行时,需要额外的安装 cri-docker 服务。当前的 cri-docker 服务可能并不太稳定,所以,当服务运行几天后就会出现异常情况,导致 kubelet 使用就绪探针对 Pod 进行健康检查时异常。

4. 解决办法

  想要在 kubernetes 1.22 以后的集群中继续使用 docker,可能需要继续等待开源社区做更多的优化,所以,建议切换容器运行时,将 docker 容器运行时切换到 containerd。containerd 实际上也是 docker 共享给开源社区的一款非常优秀的容器运行时,并且 docker 本身也是基于 containerd 构建的更高层次应用的容器服务。
   docker 切换到 containerd 的操作步骤可参考:kubernetes 将容器运行时从docker升级到containerd。经过持续多天的观测,发现之前每隔2天就会异常的就绪探针报错问题没有复现,初步判断之前的猜测是对的,所以,在生产环境中尝试最新版本的 kubernetes 有一定的风险,升级需要谨慎,升级之前在测试环境中做持续性的观察。

猜你喜欢

转载自blog.csdn.net/hzwy23/article/details/129270220