Kubernetes 容器健康检查和优雅终止
目录
在 Kubernetes 中启用容器健康检查和优雅终止,并结合应用自身特点进行配置,可以提升生产环境的应用稳定性,减少上线事故和误报。
参数
相关配置项解释如下:
terminationGracePeriodSeconds
: 全局配置项,Pod 终止的宽限期,必须大于 lifecycle.preStop,如果 Pod 中的容器在达到宽限期时仍未关闭,Pod 将被强制终止lifecycle.preStop
: 在容器停止之前执行命令的钩子,可用于延迟容器停止时间,为仍未完成的请求提供更多的时间释放连接startupProbe
: 检查容器的启动状态,可用于为容器内的应用启动提供更多的准备时间livenessProbe
: 检查容器是否存活,如果检查失败,kubelet 会杀死容器,然后重启容器readinessProbe
: 检查容器是否已经准备好接受流量,只有通过检查,kubelet 才会将 Pod 加入 Service 的负载均衡池
实践配置
启用 容器健康检查
和 优雅终止
的 Kubernetes Deployment 实践配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
# 默认值: 30
terminationGracePeriodSeconds: 120
imagePullSecrets:
- name: mysecret
containers:
- name: myapp
image: registry.example.com/myapp:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
startupProbe:
tcpSocket:
port: 8080
# 默认值: 0
initialDelaySeconds: 30
# 默认值: 10
periodSeconds: 30
# 默认值: 3
failureThreshold: 10
# 默认值: 1
successThreshold: 2
# 默认值: 1
timeoutSeconds: 2
livenessProbe:
tcpSocket:
port: 8080
# 默认值: 0
initialDelaySeconds: 30
# 默认值: 10
periodSeconds: 30
# 默认值: 3
failureThreshold: 3
# 默认值: 1 且设计目的和工作原理决定了只能设置为: 1
successThreshold: 1
# 默认值: 1
timeoutSeconds: 2
readinessProbe:
tcpSocket:
port: 8080
# 默认值: 0
initialDelaySeconds: 30
# 默认值: 10
periodSeconds: 30
# 默认值: 3
failureThreshold: 3
# 默认值: 1
successThreshold: 2
# 默认值: 1
timeoutSeconds: 2
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 60"]
env:
- name: TZ
value: Asia/Shanghai
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 500m
memory: 1Gi
实践配置详解
Kubernetes 默认配置:
- 启动检查:
无
- 容器上线: 最短
0
秒 - 容器状态:
异常判定23
-33
秒failureThreshold(3) * timeoutSeconds(1) + ( failureThreshold(3) - 1 ) * periodSeconds(10)
恢复判定0
-10
秒periodSeconds(10)
- 容器关闭: 最短
0
秒,最长30
秒terminationGracePeriodSeconds(30)
实践配置:
- 启动检查:
最短60
秒initialDelaySeconds(30) + periodSeconds(30) * ( successThreshold(2) - 1 )
最长320
秒initialDelaySeconds(30) + failureThreshold(10) * timeoutSeconds(2) + ( failureThreshold(10) - 1 ) * periodSeconds(30)
- 容器上线:
最短120
秒启动检查(最短60秒)
+initialDelaySeconds(30) + periodSeconds(30) * ( readinessProbe.successThreshold(2) - 1 )
注意: 设计目的和工作原理决定了livenessProbe.successThreshold
只能设置为1
- 容器状态:
异常判定66
-96
秒failureThreshold(3) * timeoutSeconds(2) + ( failureThreshold(3) - 1 ) * periodSeconds(30)
恢复判定30
-60
秒periodSeconds(30) * ( successThreshold(2) - 1 )
- 容器关闭:
最短60
秒sleep 60
最长120
秒terminationGracePeriodSeconds(120)
实践总结
与 Kubernetes 默认配置相比,以上实践配置进行了如下优化:
- 增加启动检查,结合应用自身特点,为容器内的应用启动提供 60-320 秒的准备时间
- 容器上线时间延长 120 秒,在生产上线过程中可作为适当的缓冲时间
- 容器状态的异常判定延长 66-96 秒,恢复判定延长 30-60 秒,可确保判定结果更加准确,避免不稳定的新容器被误判为可以正常提供服务而替换了旧的正常容器
- 容器关闭时间延长 60 秒,可确保仍未完成的请求有更多的时间释放连接,避免用户尚未完成的请求被异常中断
进一步优化
- 对于 Web 类应用,通过应用代码判断自身业务状态,生成
/healthz
健康检查页面 - 将基于
tcpSocket
的健康检查升级为基于httpGet
,通过获取健康检查页面的返回结果进行精准判断
优化后的配置
启用 /healthz
健康检查页面的 Kubernetes Deployment 实践配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
# 默认值: 30
terminationGracePeriodSeconds: 120
imagePullSecrets:
- name: mysecret
containers:
- name: myapp
image: myapp:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
startupProbe:
tcpSocket:
port: 8080
# 默认值: 0
initialDelaySeconds: 30
# 默认值: 10
periodSeconds: 30
# 默认值: 3
failureThreshold: 10
# 默认值: 1
successThreshold: 2
# 默认值: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /healthz
port: 8080
# 默认值: 0
initialDelaySeconds: 30
# 默认值: 10
periodSeconds: 30
# 默认值: 3
failureThreshold: 3
# 默认值: 1 且设计目的和工作原理决定了只能设置为: 1
successThreshold: 1
# 默认值: 1
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /healthz
port: 8080
# 默认值: 0
initialDelaySeconds: 30
# 默认值: 10
periodSeconds: 30
failureThreshold: 3
# 默认值: 3
successThreshold: 2
# 默认值: 1
timeoutSeconds: 2
# 默认值: 1
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 60"]
env:
- name: TZ
value: Asia/Shanghai
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 500m
memory: 1Gi