【问题解决】关于Kubernetes 健康检测 probe errored: rpc error: code = DeadlineExceeded desc = context deadline exceeded
说说为啥写本文
春节假前,生产环境(基于Kubernetes的PaaS平台OpenShift)出现使用健康检测探针报错,但应用Pod并未下线的情况,导致服务卡住(某一节点死锁,Service总是负载均衡到此节点)。
查了OpenShift官方文档对此并无提及,在 Kubernetes 官方仓库的 Issue列表 中有所收获,在这里简单记录下。(Kubernetes v1.15.12以上版本已解决)
简单说来,这可能是 Kubernetes 历史遗留的一个 Bug,不过值得肯定的是:问题根源在于Kubernetes对于健康检测方式不同,对于运行时的报错处理也不同,直接导致了健康检测的报错。
底层出错不应该影响上层,上层本应防住的为啥不防住呢?你说是吧。
健康检测基础知识
健康检测,顾名思义是对应用节点进行检测,判断该节点是否健康可提供服务。
在Kubernetes 提供了三种健康检测的探针(Probes):
- Liveness Probe 存活探针,检测Pod状态是否正常,如不正常则删除Pod,由Deployment自动创建新Pod
- Readiness Probe 就绪探针,检测Pod容器内应用服务是否可用,如不可用,从Service列表中移出,不再有流量进入
- Startup Probe 启动探针,Kubernetes 1.18开始出现的新探针,适用于应用启动慢的服务使用,防止在服务正常启动前被Liveness Probe判定为不健康状态删除Pod,与减少Readiness Probes频繁失败的问题
这三种探针都有相同的三种检测方式,只不过它们对检测结果的处理不同。三者均包含:
exec
容器执行命令方式httpGet
HTTP GET请求方式tcpSocket
创建套接字方式
这里就不继续展开了,参见文末官方文档地址吧。
问题描述
生产环境中,使用了相对灵活的 exec 容器执行命令:
curl http://localhost:8188/actuator/health/readiness,作为就绪探针(Readiness Probe),每10秒检测一下服务状态,在某个节点负载请求时,发生节点死锁,命令执行超时无响应,超过超时时间探针报错,但此节点未从Service列表中移出,导致集群其它节点没有流量进入,服务处于不可用状态。
报错信息为
Readiness probe errored: rpc error: code = DeadlineExceeded desc = context deadline exceeded
为什么会发生此问题?
参考了这个issue中某位热心网友提供的源码注释
即
exec容器内执行命令的探针遇到错误时并未变更Pod的状态,导致仍在负载均衡的列表中;其他探针中将检测过程中遇到的所有错误,都算作检测失败,变更Pod状态。
解决思路
问题本身出现在容器运行时上,但是问题反映在Kubernetes健康检测时,所以最简单的解决办法是 使用其他检测方式,如 httpGet
或 tcpSocket
。
除此之外,升级Kubernetes 版本至 v1.15.12以上也可以解决问题,当然,要去根的话,需要升级 Containerd 版本了,一般对应 Docker 版本变化即可(Docker 绑定了 Containerd 管理容器)。
看来docker v19.03.6没问题 😆
- Kubernetes v1.20以后移除Docker运行时这事和本文关系不大,因为错误出在底层Containerd上
- 我这边公司用的OpenShift对应的Kubernetes版本太低,Docker也不能升(平台运维团队是甲方……),所以只能改了httpGet方式检测,另外因为OpenShift限制了界面上的端口号,又改了Deployment的yaml才搞定……
使用 httpGet
方式示例
重点关注
spec.containers下的
livenessProbe处定义,如更换其它探针类型,只换下名称即可。
apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec: containers: - name: liveness image: k8s.gcr.io/liveness args: - /server livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 3 periodSeconds: 3
以上使用
httpGet方式,请求
http://localhost:8080/healthz,启动时间延迟3秒,容器启动3秒后,开始每隔3秒一次检测。
总结
使用第三方服务还是需要深入了解下它的机制、有没有什么坑等情况,以免出现碰到问题不知如何解决的被动局面。
路茫茫其修远兮,吾将上下而求所。
参考
- 关于Error:Error converting bytecode to dex问题解决
- kube-apiserver显示rpc error: code = 13 desc = transport is closing解决记录
- [模拟器问题] 关于ActivityManager: Error: Activity class {..} does not exist. 的解决
- 解决 LNK1318 Unexpected PDB error; RPC (23) 问题
- Eclipse出现:An internal error occurred during: "Retrieving archetypes:". GC overhead limit exceeded的问题解决
- 关于VS2005中的Code Snippets Manager的问题及解决
- 关于python下构建c模块出现error: Unable to find vcvarsall.bat问题的解决方法
- 关于es集群转换为单点后,主分片丢失的问题(健康检测状态为red)
- 关于HFSS中的:internal error:WebUpdate is missing require information问题解决办法!
- E: Sub-process /usr/bin/dpkg returned an error code 问题的解决办法
- 关于mysql error code 1005 errno135的问题
- 关于使用百度地图安卓SDK的过程中出现“Authentication Error errorcode: 230 uid: -1 appid -1 msg: APP Scode码校验失败”的一个解决方法
- 问题解决:error LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1800”不匹配值“1900”
- rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: container错误
- ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction的问题解决(转)
- 关于VS2005中的Code Snippets Manager的问题及解决
- 关于ora-00600 internal error code arguments [kokeeilx3],[3],[],[],[],[],[],[]的解决方法
- 关于在使用codeblocks+wxWidgets的过程中遇到的问题及解决
- Uubntu E: Sub-process /usr/bin/dpkg returned an error code问题的解决办法
- Xcode5中关于PBXcp-error:问题的解决方法