保持 pod 健康 P84
只要 pod 调度到某个节点,该节点上的 Kubelet 就会运行 pod 的容器,从此只要该 pod 存在,就会保持运行。如果容器的主进程奔溃, Kubelet 就会自动重启容器;如果应用程序奔溃, Kubelet 就会自动重启应用程序。 P84
应用程序也可能因为无限循环或死锁等情况而停止响应。为确保应用在这种情况下可以重新启动,必须从外部检查应用程序的运行状况,而不是依赖于应用的内部检测。 P84
介绍存活探测器 P84
Kubernetes 可以通过存活探测器 (liveness probe) 检查容器是否还在运行。可以为 pod 中的每个容器单独指定存活探测器。 Kubernetes 将定期执行探测器,如果探测失败,就会自动重启容器。 P84
注意:Kubernetes 还支持就绪探测器 (readiness probe) ,两者适用于两种不同的场景。 P84
Kubernetes 有三种探测容器的机制: P84
HTTP GET
探测器:对容器的 IP 地址(指定的端口和路径)执行HTTP GET
请求。如果探测器收到响应,并且响应状态码不代表错误(状态码为 2xx 或 3xx ),则认为探测成功。如果服务器返回错误响应状态码或者没有响应,那么探测就被认为是失败的,容器将被重启。TCP Socket
探测器:尝试与容器指定端口建立 TCP 连接。如果连接成功建立,则探测成功。否则,容器将被重启。Exec
探测器:在容器内执行任意命令,并检查命令的退出状态码。如果状态码是 0 ,则探测成功。所有其他状态码都被认为失败,容器将被重启。
创建基于 HTTP 的存活探测器 P85
为了让 HTTP GET
探测器探测失败,我们需要修改 kubia 源码,使得其从第五次访问之后开始一直返回 500 状态码 (Internal Server Error) 。 P85
然后我们可以通过以下描述文件 kubia-liveness-probe.yaml
创建一个包含 HTTP GET
存活探测器的 pod 。 P85
# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Pod
kind: Pod
metadata:
# pod 的名称
name: kubia-liveness
spec:
containers:
# 创建容器所使用的镜像
- image: idealism/kubia-unhealthy
# 容器的名称
name: kubia
ports:
# 应用监听的端口
- containerPort: 8080
protocol: TCP
# 开启一个存活探测器
livenessProbe:
# 存活探测器的类型为 HTTP GET
httpGet:
# 探测器连接的网络端口
port: 8080
# 探测器请求的路径
path: /
使用存活探测器 P86
使用 kubectl create -f kubia-liveness-probe.yaml
创建完 pod 后,等待一段时间后,容器将会重启。可以通过 kubectl get pod kubia-liveness
看到容器会重启,并且无限循环下去: 86
NAME READY STATUS RESTARTS AGE
kubia-liveness 1/1 Running 2 4m9s
kubectl logs kubia-liveness --previous
: 查看前一个容器的日志,可以了解前一个容器停止的原因。 P86
kubectl describe pod kubia-liveness
: 查看 pod 详情。可以发现在 Containers 和 Events 里面有终止的相关信息。 P86
...
Containers:
kubia:
...
State: Running # 容器目前正常运行
Started: Sun, 07 Jun 2020 17:59:35 +0800
Last State: Terminated # 前一个容器由于错误被终止,错误码是 137
Reason: Error
Exit Code: 137
Started: Sun, 07 Jun 2020 17:57:44 +0800
Finished: Sun, 07 Jun 2020 17:59:27 +0800
Ready: True
Restart Count: 2 # 该容器已被重启 2 次
Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/kubia-liveness to minikube-m02
Warning Unhealthy 48s (x6 over 2m58s) kubelet, minikube-m02 Liveness probe failed: HTTP probe failed with statuscode: 500 # 发现容器不健康
Normal Killing 48s (x2 over 2m38s) kubelet, minikube-m02 Container kubia failed liveness probe, will be restarted # 终止该容器
...
错误码 137 是两个数字的总和: 128 + x , x 是终止进程的信号编号。 P86
- x=9 表示是
SIGKILL
的信号编号,意味着这个进程被强行终止,这个信号不能被捕获或忽略,并且在接收过程中不能执行任何清理在接收到该信号 - x=15 表示是
SIGTERM
的信号编号,意味着这个进程被终止,先进行询问进程终止,让其清理文件和关闭,可以被捕获和解释或忽略
底部列出的事件显示了 Kubernetes 发现容器不健康,所以终止并重新创建。 P86
注意:当容器被强行终止时,会创建一个全新的容器,而不是重启原来的容器。 P86
配置存活探测器的附加属性 P87
可以使用 kubectl explain pod.spec.containers.livenessProbe
查看存活探测器能使用的自定义附加参数。
基于 kubia-liveness-probe.yaml
创建一个新的描述文件 kubia-liveness-probe-initial-delay.yaml
,并添加 pod.spec.containers.livenessProbe.initialDelaySeconds
属性,值为 15 ,表示在第一次探测器等待 15 秒。
...
spec:
containers:
# 创建容器所使用的镜像
- image: idealism/kubia-unhealthy
...
# 开启一个存活探测器
livenessProbe:
...
# 第一次探测前等待 15 秒
initialDelaySeconds: 15
这样可以在应用程序准备好之后再进行探测,以免应用程序启动时间过长导致一直探测失败而无限重启。
创建有效的存活探测器 P88
- 存活探测器应该检查什么:简易的存活探测器可以仅检查服务器是否响应,但为了更好地进行存活检查,需要将探测器配置为请求特定的 URL 路径&#x