从零开始学习k8s-05让容器复活
背景
我们在部署业务的时候经常会遇到一个问题,程序因为非预期的原因挂了,或者一些运行环境原因导致不可用了。在传统的方式,一般是写一个监控脚本来监控,有异常了告警。
在k8s
的机制下,这个功能可以几行配置就搞定。
文件探测
常见的一个方式就是文件探测,服务启动的时候会生成一个pid
文件,服务挂的时候这个pid
就会消失。那么我们可以用这个方式来让容器复活。
这里依然采用官方文档的示例来看。
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这个命令在进行启动的时候,就会执行
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
在启动的时候前30秒,在/tmp/healthy
会有一个文件,而超过30秒之后,则会删除,这种方式即可模拟服务存活和挂掉的情况。
执行命令:kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
过了35秒之后可以看到容器探测失败了
kubectl describe pod liveness-exec
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 40s default-scheduler Successfully assigned default/liveness-exec to minikube
Normal Pulling 40s kubelet Pulling image "k8s.gcr.io/busybox"
Normal Pulled 35s kubelet Successfully pulled image "k8s.gcr.io/busybox" in 5.029668556s
Normal Created 35s kubelet Created container liveness
Normal Started 35s kubelet Started container liveness
Warning Unhealthy 0s kubelet Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
2
3
4
5
6
7
8
9
10
11
12
当容器发生重建之后,我们查看容器的状态
kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 (25s ago) 105s
2
3
可以看到,重建次数变成1了。这表示容器已经被重建了。
其他支持方式
除了文件探测之外,常用的方式还有http
探测,tcp
探测等常见的方式。
//HTTP
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
//TCP
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
慢启动保护
有时候我们的服务可能启动的比较慢,比如大型系统可能要读取很多数据之后才能正常的启动。这个时候如果直接这样探测,可能会出现服务还没起来,但是探针已经到了,就会导致探针检失败,重启服务,重启后探针又失败的死循环里面,技巧就是使用一个命令来设置启动探测,针对HTTP
或者 TCP
检测,可以通过设置 failureThreshold * periodSeconds
参数来保证有足够长的时间应对糟糕情况下的启动时间。
就绪检查
就绪检查跟存活探测的方式一样,差异点就只是运行阶段不一样,存活探测存在于容器运行的时候,而就绪检查会在容器正式对外提供能力之前调度一次,保证容器在对外提供服务的时候是真的能够提供服务
一些深入的内容
容器探测的结果一共有三种:成功、失败和未知,成功和失败很好理解,出现未知状态的时候,其实是诊断失败,这个时候k8s不会采取任何措施。
基于k8s的机制,可以保证我们的容器时刻保持的存活的状态,但是有一点要注意,这种方式可能会出现偶发性的重建,因此必须要保证容器启动的时候服务就能对外,而不需要手工进行某些配置的修改才能对外服务。否则就会出现容器重建导致服务一直不可用的状态。