前言
Pod的探测用于检测容器中的应用实例是否可以正常的工作。如果不能正常工作应该去重启,或者不将流量引入该实例。K8s给我们提供了三种探测方式。
LivenessProbe,ReadinessProbe,StartupProbe
可以通过官网查看 https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
Pod的重启策略
在讲解探针之前先了解下Pod的重启策略。Pod的重启策略包括三种,Always,OnFailure和 Never 默认就是 Always
- Always: 当容器不能正常工作时,kubelet会自动重启该容器
- OnFailure: 当容器终止运行且退出码不为0时,由kubelet自动启动该容器。
- Never: 不论容器运行状态如何,都不重启。
如果容器重启之后还是不可用需要继续重启。为了不频繁重启,K8s给重启时间间隔设置了规律,每次间隔时间乘以2,最长达到五分钟。成功重启后的十分钟后重置时间间隔
重启策略与Pod控制器关系
重启策略跟Pod控制器有着莫大的关联
- 对于RC、RS、Deployment、DaemonSet 就得设置 Always
- 对于 Job 设置为OnFailure或者Never,确保容器执行完成后不再重启
- Kubelet:与重启策略无关。Pod失效自动重启。
探针的检查机制
常用的检查方式有三种
- exec 通过命令执行的方式检测,我们知道linux的一条命令执行成功返回的状态是 0,exec 也是根据命令执行返回的状态码是不是0来表示服务是否存活
- httpGet 通过一个http请求访问,如果响应的状态码大于等于 200 且小于 400 ,表示服务正常
- tcpSocket 对容器指定的端口进行Tcp检查,如果端口能打开,表示成功。
LivenessProbe
探测容器是否正在运行(Running),如果探测失败,Kubelet将会杀死该容器,然后根据容器的重启策略判断是否需要重启,如果没有提供该类探针,默认返回Success
下面使用 exec 来演示LivenessProbe的使用(每种检查机制都可以使用),创建 kube-nginx.yml 内容如下
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent #用于设置镜像拉取策略
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
exec: # exec方式
command:
- cat
- /root/livenessProbe.txt
initialDelaySeconds: 10 # 容器启动后多长时间开始探测
timeoutSeconds: 1 # 探测超时时间
failureThreshold: 1 # 连续出现多少次失败后认为是不可用,默认3
periodSeconds: 1 # 1秒钟探测一次,默认10
启动,观察Pod状态
[root@master probe]# kubectl apply -f kube-nginx.yml
pod/nginx created
# 查看Pod
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 9s
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 1 (1s ago) 11s
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 2 (2s ago) 22s
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 3 (1s ago) 31s
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 0/1 CrashLoopBackOff 3 (1s ago) 41s
# 查看nginx的创建过程
[root@master probe]# kubectl describe pod nginx|grep -A 100 Events
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 14s default-scheduler Successfully assigned default/nginx to node01
Normal Pulled 2s (x2 over 13s) kubelet Container image "nginx" already present on machine
Normal Created 2s (x2 over 13s) kubelet Created container nginx
Normal Started 2s (x2 over 13s) kubelet Started container nginx
Warning Unhealthy 2s kubelet Liveness probe failed: cat: /root/livenessProbe.txt: No such file or directory
Normal Killing 2s kubelet Container nginx failed liveness probe, will be restarted
分析
从上面查看Pod的情况来看, Liveness probe failed 原因是文件不存在,然后接着就是重启nginx
Container nginx failed liveness probe, will be restarted
观察Pod RESTARTS的时间,由于我们都是设置的1,容器启动后10秒中开始探测,立马探测失败于是重启。所以大概每10秒钟就会看到重启一次,重启三次后状态变为 CrashLoopBackOff
CrashLoopBackOff 本身并不是一个错误 ,只是说由于我们循环重启造成的,等待一段时间,容器又会变为Running
解决
既然是没有找到这个文件造成的,那么我们手动创建一个。delete该容器,重新启动。10秒后我们手动创建文件 /root/livenessProbe.txt 再次观察容器状态。
[root@master probe]# kubectl create -f kube-nginx.yml
pod/nginx created
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 1 (2s ago) 13s
[root@master probe]# kubectl exec nginx -- touch /root/livenessProbe.txt
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 1 (14s ago) 25s
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 1 (76s ago) 87s
从上面结果可以看出,刚开始由于没有该文件探测失败,造成RESTARTS,后面手动创建后就再也没RESTARTS了
ReadinessProbe
表示服务是否已经是就绪状态(Ready),可不可以对外提供服务。一样的如果没有配置永远返回Success,上面例子我们没有配置,可以看到READY立马就是1/1 。
下面使用tcpSocket方式(每种检查机制都可以使用)来应用 readinessProbe,修改 kube-nginx.yml 内容如下
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent #用于设置镜像拉取策略
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 20 # 容器启动后多长时间开始探测
timeoutSeconds: 1 # 探测超时时间
启动
[root@master probe]# kubectl apply -f kube-nginx.yml
pod/nginx created
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 0 12s
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 34s
与LivenessProbe不同的是 ReadinessProbe 对Pod 的处置方式不同 LivenessProbe 探测失败希望的是重启Pod,ReadinessProbe失败后 kube-proxy 就不会把流量引入此Pod并且从对应的 EndPoint 列表中删除,如果Pod恢复为Ready,再重新添加回来,生产上一般两者都配置,探测可以一样。
StartupProbe
在1.6版本之后加入的,主要是解决上面两种探测存在的问题,比如一个服务启动需要六十秒,那么上面的探测就会失败很多次导致重启,重启还是需要60秒才能起好,然后又是探测失败,这样就陷入了循环,虽然可以使用initialDelaySeconds来表示容器启动后多久才开始探测,但是万一下次启动需要100秒呢。那么你的initialDelaySeconds timeoutSeconds periodSeconds又该怎么设计呢。而且ReadinessProbe是一直需要探测的,最好这些参数不要设置的过大,不然服务宕掉了不能及时发现。
总之使用前面两种探测,经过调试其实也可以满足需求。只是复杂程序中没那么好用。
所以K8s就设计出了StartupProbe。
三个探针都存在时先执行StartupProbe,其它两个为禁用状态 直到StartupProbe成功,其他两个探测才开始。StartupProbe满足一次后便不再执行。
下面我们来使用一下StartupProbe,相信你会体会到它的好处 修改kube-nginx.yml内容如下
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent #用于设置镜像拉取策略
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /data.html
port: 80
timeoutSeconds: 1 # 探测超时时间
failureThreshold: 1 # 连续出现多少次古装后认为是失败,默认3
periodSeconds: 1 # 1秒钟探测一次,默认10
readinessProbe:
httpGet:
path: /data.html
port: 80
timeoutSeconds: 1 # 探测超时时间
failureThreshold: 1 # 连续出现多少次古装后认为是失败,默认3
periodSeconds: 1 # 1秒钟探测一次,默认10
startupProbe:
httpGet:
path: /data.html
port: 80
failureThreshold: 300 # 连续出现多少次失败后认为是不可用,默认3
periodSeconds: 2 # 2秒钟探测一次,默认10
这里我们可以将连续失败数设置大一点但是探测间隔设置小一点,那么只要服务启动成功就会立马探测到,从而启用readinessProbe与livenessProbe。如果说换做是livenessProbe配置这样的参数,那服务挂了都探测不出来。
下面启动该Pod,观察状态。
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 0 34s
[root@master probe]# kubectl exec nginx -- touch /usr/share/nginx/html/data.html
[root@master probe]# kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 37s
从上面可以看出,34秒时还是失败,我们立马创建请求需要的文件data.html,再次查看发现服务已经正常了。也体现出来服务一旦启用成功会立刻执行readinessProbe探测。
Pod的健康检查就介绍到这里。下期介绍Pod的生命周期。
欢迎关注,学习不迷路!