Kubernates Pod无法启动问题分析排查
一、问题背景近期遇到一个特别奇怪的事就是关于 K8s Pod 无法启动的问题,因为平时通过 Jenkins 打包成 Docker 后,再自动触发已经建好的 Pipline 就可以部署到 Kubernates 平台,但这次打包后发现部署应用到 Kubernates 时 Pod 总无法创建成功,然后 Pod 自动重新部署。二、原因排查排查问题的路径有:通过查看 Kubernates 容器组中事件排查
一、问题背景
近期遇到一个特别奇怪的事就是关于 K8s Pod 无法启动的问题,因为平时通过 Jenkins
打包成 Docker 后,再自动触发已经建好的 Pipline
就可以部署到 Kubernates 平台,但这次打包后发现部署应用到 Kubernates 时 Pod 总无法创建成功,然后 Pod 自动重新部署。
二、原因排查
排查问题的路径有:
- 通过查看 Kubernates 容器组中事件排查 Pod 无法起来的原因,类似于下面这张图
- 通过查看应用的最后打印日志排查问题;在这要说一句,在通过Pod 打印的日志排查问题是,有时应用日志刷的时快时慢,看不到最后打印的日志信息(Pod 重启后会将上一次日志清掉)需要有耐心,不可太急躁,觉得实在太慢可以将 Pod 资源限制的 CPU 调大些;
可能存在的问题:
-
Pod 无法起来时应该最先想到的是配置文件是否正常拉取,配置是否正确,少配置项、配置格式错误或编码错误等等;
-
应用程序本身是否编写正确,例如包冲突导致应用无法启动;
-
应用程序依赖组件是否正常,例如 RabbitMQ、Mongodb、Reids、数据库、第三方应用等等等;
-
Pod 内存不足(因为加上了资源限制),类似于下面的容器配置定义:
"resources": {
"limits": {
"cpu": "1",
"memory": "1Gi"
},
"requests": {
"cpu": "500m",
"memory": "500Mi"
}
}
5. 检查 liveness
的健康检查探针配置参数,因为这个探针配置也会影响到 Pod 的启动,如下配置,大概意思是 liveness
探针使用 HTTP
协议,地址 /actuator/health
+ port=8080
,Pod 创建 300s
后开始检测,超时是 1s
,每 10s
执行一次探测,连续失败3
次即失败,失败后成功1
次即成功;这里说一嘴 readiness
探针,和liveness
类似,两者的主要区别在于 liveness
主要用来确定何时重启容器,默认成功;readiness
主要来确定容器是否已经就绪,默认失败,不可相互替代。而是相互协作的关系。
"livenessProbe": {
"httpGet": {
"path": "/actuator/health",
"port": 8080,
"scheme": "HTTP"
},
"initialDelaySeconds": 300,
"timeoutSeconds": 1,
"periodSeconds": 10,
"successThreshold": 1,
"failureThreshold": 3
},
"readinessProbe": {
"httpGet": {
"path": "/actuator/health",
"port": 8080,
"scheme": "HTTP"
},
"initialDelaySeconds": 60,
"timeoutSeconds": 1,
"periodSeconds": 10,
"successThreshold": 1,
"failureThreshold": 3
}
三、排查过程记录
一条一条对着上述可能存在的问题排查,发现通过将 Pod
资源限制加至 cpu=2,memory=4Gi
时应用偶尔能够正常启动,但还存在不能启动的情况,然后在本机通过 VisualVM 工具监测到应用启动后 heap 内存用了不到 500M
,另外通过查看 Pod 日志时,发现应用程序启动时所带的参数(如下图)得出结论,不是内存问题。
exec java -Xmx512m -XX:ParallelGCThreads=1 -XX:ConcGCThreads=1
下图为 Pod 日志,可以看出 最大堆内存为 512M。
然后应用将资源限制还原,发现 liveness
探针的 initialDelaySeconds=0
,于是修改 liveness
探针的 initialDelaySeconds=300
解决问题。
四、原因分析
我这原因是因为第 5
条原因导致。因为应用启动时间比较长,在资源限制不变得情况下正常启动需要耗时60s,加上之前 liveness
的配置不合理,如下:
"livenessProbe": {
"httpGet": {
"path": "/actuator/health",
"port": 8080,
"scheme": "HTTP"
},
"initialDelaySeconds": 0,
"timeoutSeconds": 1,
"periodSeconds": 10,
"successThreshold": 1,
"failureThreshold": 3
},
因为 initialDelaySeconds
设置的是0,导致连续3次健康检查失败(理论是在重启 Pod 30s 后)就会自动重启 Pod。
更多推荐
所有评论(0)