【Kubernetes in Action读书笔记】4.1 保持Pod健康
”健康的Pod“可能是个比较模糊的概念。
首先,Pod是什么样的Pod,是手动创建的(=未托管的)Pod,还是由ReplicationController或Deployment等资源创建的(=托管的)Pod。
其次,如何算是健康。
- 容器(Pod)内的主进程(pid = 1)存活就算健康?
- 在主进程存活的前提下,容器(Pod)内的Web服务没有连续返回5xx(存活探针探活成功)算健康?
- 在主进程存活且Web服务正常的前提下,容器(Pod)的数量与预期一致算健康?
k8s的不同组件从不同的角度提供了修复“不健康”Pod的能力。与“Pod健康”相关的组件包括:
- Kubelet:如果pid = 1的进程退出,Kubelet将重启容器(还是Pod?)
- 存活探针:确保Pod内的服务正常运行
实验1. 对于未托管的Pod,如果(Pod中)容器崩溃,Kubelet将重启容器(还是Pod?)
- 手动创建Pod
apiVersion: v1
kind: Pod
metadata:
name: kubia-manual
spec:
containers:
- image: luksa/kubia
name: kubia
ports:
- containerPort: 8080
protocol: TCP
$ kubectl create -f kubia-manual.yaml
pod/kubia-manual created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-manual 1/1 Running 0 7m33s
- 通过kill -9破坏Pod内的容器(=pid为1的进程)
root@kubia-manual:/# curl http://127.0.0.1:8080
You've hit kubia-manual
root@kubia-manual:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:01 ? 00:00:00 node app.js
root 12 0 0 09:30 pts/0 00:00:00 bash
root 45 12 0 09:39 pts/0 00:00:00 ps -ef
root@kubia-manual:/# curl http://127.0.0.1:8080
You've hit kubia-manual
root@kubia-manual:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:01 ? 00:00:00 node app.js
root 12 0 0 09:30 pts/0 00:00:00 bash
root 47 12 0 09:43 pts/0 00:00:00 ps -ef
root@kubia-manual:/# kill -9 1
root@kubia-manual:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:01 ? 00:00:00 node app.js
root 12 0 0 09:30 pts/0 00:00:00 bash
root 48 12 0 09:43 pts/0 00:00:00 ps -ef
看起来,pid = 1的进程node app.js无法被杀掉。这可能是因为pid = 1的进程很特殊,不会处理SIGINT或SIGTERM这两个信号。参考Why do you need an init process inside your Docker container (PID 1)
所以需要换一种方法验证“容器崩溃,Kubelet将重启容器”的结论。
实验2. 如果存活探针探活失败,Kubernets将重启容器(还是Pod?)
- 手动创建Pod
apiVersion: v1
kind: Pod
metadata:
name: kubia-liveness
spec:
containers:
- image: luksa/kubia-unhealthy
name: kubia
livenessProbe:
httpGet:
path: /
port: 8080
$ kubectl create -f kubia-unhealthy.yaml
pod/kubia-liveness created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-liveness 0/1 ContainerCreating 0 58s
- 反复执行
kubectl get pods,等待探活失败后,Pod重启
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-liveness 1/1 Running 0 2m57s
# Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-liveness 1/1 Running 1 (106s ago) 6m7s
- 对存活探针进行抓包
先安装Kubeshark(docs.kubeshark.co/en/install)
$ kubeshark tap kubia-liveness
限定Pod抓包
连续3次500后重启,连续5次200后又开始响应500。
手动创建的(=未托管的)Pod的缺点
即使配置了探针,手动创建的(=未托管的)Pod依然有以下缺点
- Pod所在的节点挂了,Pod无法自动恢复