保持 pod 健康 P84
只要 pod 调度到某个节点,该节点上的 Kubelet 就会运行 pod 的容器,从此只要该 pod 存在,就会保持运行。如果容器的主进程奔溃, Kubelet 就会自动重启容器;如果应用程序奔溃, Kubelet 就会自动重启应用程序。 P84
应用程序也可能因为无限循环或死锁等情况而停止响应。为确保应用在这种情况下可以重新启动,必须从外部检查应用程序的运行状况,而不是依赖于应用的内部检测。 P84
介绍存活探测器 P84Kubernetes 可以通过存活探测器 (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 4m9skubectl 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 :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