205 lines
7.6 KiB
Markdown
205 lines
7.6 KiB
Markdown
|
<h1><center>Kubernetes健康检查机制</center></h1>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
------
|
|||
|
|
|||
|
## 一:检查恢复机制
|
|||
|
|
|||
|
#### 1.容器健康检查和恢复机制
|
|||
|
|
|||
|
在 k8s 中,可以为 Pod 里的容器定义一个健康检查"探针"。kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器是否运行作为依据。这种机制,是生产环境中保证应用健康存活的重要手段。
|
|||
|
|
|||
|
#### 2.命令模式探针
|
|||
|
|
|||
|
```shell
|
|||
|
apiVersion: v1
|
|||
|
kind: Pod
|
|||
|
metadata:
|
|||
|
labels:
|
|||
|
test: liveness
|
|||
|
name: test-liveness-exec
|
|||
|
spec:
|
|||
|
containers:
|
|||
|
- name: liveness
|
|||
|
image: daocloud.io/library/nginx
|
|||
|
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
|
|||
|
```
|
|||
|
|
|||
|
它在启动之后做的第一件事是在 /tmp 目录下创建了一个 healthy 文件,以此作为自己已经正常运行的标志。而 30 s 过后,它会把这个文件删除掉
|
|||
|
|
|||
|
与此同时,定义了一个这样的 livenessProbe(健康检查)。它的类型是 exec,它会在容器启动后,在容器里面执行一句我们指定的命令,比如:"cat /tmp/healthy"。这时,如果这个文件存在,这条命令的返回值就是 0,Pod 就会认为这个容器不仅已经启动,而且是健康的。这个健康检查,在容器启动 5 s 后开始执行(initialDelaySeconds: 5),每 5 s 执行一次(periodSeconds: 5)
|
|||
|
|
|||
|
创建Pod:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl create -f test-liveness-exec.yaml
|
|||
|
```
|
|||
|
|
|||
|
查看 Pod 的状态:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl get pod
|
|||
|
NAME READY STATUS RESTARTS AGE
|
|||
|
test-liveness-exec 1/1 Running 0 10s
|
|||
|
```
|
|||
|
|
|||
|
由于已经通过了健康检查,这个 Pod 就进入了 Running 状态
|
|||
|
|
|||
|
30 s 之后,再查看一下 Pod 的 Events:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl describe pod test-liveness-exec
|
|||
|
```
|
|||
|
|
|||
|
发现,这个 Pod 在 Events 报告了一个异常:
|
|||
|
|
|||
|
```shell
|
|||
|
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
|||
|
--------- -------- ----- ---- ------------- -------- ------ -------
|
|||
|
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
|
|||
|
```
|
|||
|
|
|||
|
显然,这个健康检查探查到 /tmp/healthy 已经不存在了,所以它报告容器是不健康的。那么接下来会发生什么呢?
|
|||
|
|
|||
|
再次查看一下这个 Pod 的状态:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl get pod test-liveness-exec
|
|||
|
NAME READY STATUS RESTARTS AGE
|
|||
|
liveness-exec 1/1 Running 1 1m
|
|||
|
```
|
|||
|
|
|||
|
这时发现,Pod 并没有进入 Failed 状态,而是保持了 Running 状态。这是为什么呢?
|
|||
|
|
|||
|
RESTARTS 字段从 0 到 1 的变化,就明白原因了:这个异常的容器已经被 Kubernetes 重启了。在这个过程中,Pod 保持 Running 状态不变
|
|||
|
|
|||
|
注意:
|
|||
|
|
|||
|
Kubernetes 中并没有 Docker 的 Stop 语义。所以虽然是 Restart(重启),但实际却是重新创建了容器
|
|||
|
|
|||
|
这个功能就是 Kubernetes 里的Pod 恢复机制,也叫 restartPolicy。它是 Pod 的 Spec 部分的一个标准字段(pod.spec.restartPolicy),默认值是 Always,即:任何时候这个容器发生了异常,它一定会被重新创建
|
|||
|
|
|||
|
小提示:
|
|||
|
|
|||
|
Pod 的恢复过程,永远都是发生在当前节点上,而不会跑到别的节点上去。事实上,一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点。这也就意味着,如果这个宿主机宕机了,这个 Pod 也不会主动迁移到其他节点上去。
|
|||
|
|
|||
|
而如果你想让 Pod 出现在其他的可用节点上,就必须使用 Deployment 这样的"控制器"来管理 Pod,哪怕你只需要一个 Pod 副本。这就是一个单 Pod 的 Deployment 与一个 Pod 最主要的区别。
|
|||
|
|
|||
|
#### 3.http get方式探针
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# vim liveness-httpget.yaml
|
|||
|
apiVersion: v1
|
|||
|
kind: Pod
|
|||
|
metadata:
|
|||
|
name: liveness-httpget-pod
|
|||
|
namespace: default
|
|||
|
spec:
|
|||
|
containers:
|
|||
|
- name: liveness-exec-container
|
|||
|
image: daocloud.io/library/nginx
|
|||
|
imagePullPolicy: IfNotPresent
|
|||
|
ports:
|
|||
|
- name: http
|
|||
|
containerPort: 80
|
|||
|
livenessProbe:
|
|||
|
httpGet:
|
|||
|
port: http
|
|||
|
path: /index.html
|
|||
|
initialDelaySeconds: 1
|
|||
|
periodSeconds: 3
|
|||
|
```
|
|||
|
|
|||
|
创建该pod:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl create -f liveness-httpget.yaml
|
|||
|
pod/liveness-httpget-pod created
|
|||
|
```
|
|||
|
|
|||
|
查看当前pod的状态:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl describe pod liveness-httpget-pod
|
|||
|
...
|
|||
|
Liveness: http-get http://:http/index.html delay=1s timeout=1s period=3s #success=1 #failure=3
|
|||
|
...
|
|||
|
```
|
|||
|
|
|||
|
测试将容器内的index.html删除掉:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl exec liveness-httpget-pod -c liveness-exec-container -it -- /bin/sh
|
|||
|
/ # ls
|
|||
|
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
|
|||
|
/ # mv /usr/share/nginx/html/index.html index.html
|
|||
|
/ # command terminated with exit code 137
|
|||
|
```
|
|||
|
|
|||
|
可以看到,当把index.html移走后,这个容器立马就退出了
|
|||
|
|
|||
|
查看pod的信息:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl describe pod liveness-httpget-pod
|
|||
|
...
|
|||
|
Normal Killing 1m kubelet, node02 Killing container with id docker://liveness-exec-container:Container failed liveness probe.. Container will be killed and recreated.
|
|||
|
...
|
|||
|
```
|
|||
|
|
|||
|
看输出,容器由于健康检查未通过,pod会被杀掉,并重新创建:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl get pods
|
|||
|
NAME READY STATUS RESTARTS AGE
|
|||
|
liveness-httpget-pod 1/1 Running 1 33m
|
|||
|
restarts 为 1
|
|||
|
```
|
|||
|
|
|||
|
重新登陆容器查看:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl exec liveness-httpget-pod -c liveness-exec-container -it -- /bin/sh
|
|||
|
/ # cat /usr/share/nginx/html/index.html
|
|||
|
```
|
|||
|
|
|||
|
新登陆容器,发现index.html又出现了,证明容器是被重拉了
|
|||
|
|
|||
|
#### 4.Pod 的恢复策略
|
|||
|
|
|||
|
可以通过设置 restartPolicy,改变 Pod 的恢复策略。一共有3种:
|
|||
|
|
|||
|
Always:在任何情况下,只要容器不在运行状态,就自动重启容器
|
|||
|
|
|||
|
OnFailure:只在容器异常时才自动重启容器
|
|||
|
|
|||
|
Never: 从来不重启容器
|
|||
|
|
|||
|
注意:
|
|||
|
|
|||
|
官方文档把 restartPolicy 和 Pod 里容器的状态,以及 Pod 状态的对应关系,总结了非常复杂的一大堆情况。实际上,你根本不需要死记硬背这些对应关系,只要记住如下两个基本的设计原理即可:
|
|||
|
|
|||
|
只要 Pod 的 restartPolicy 指定的策略允许重启异常的容器(比如:Always),那么这个 Pod 就会保持 Running 状态,并进行容器重启。否则,Pod 就会进入 Failed 状态
|
|||
|
|
|||
|
对于包含多个容器的 Pod,只有它里面所有的容器都进入异常状态后,Pod 才会进入 Failed 状态。在此之前,Pod 都是 Running 状态。此时,Pod 的 READY 字段会显示正常容器的个数
|
|||
|
|
|||
|
例如:
|
|||
|
|
|||
|
```shell
|
|||
|
[root@master diandian]# kubectl get pod test-liveness-exec
|
|||
|
NAME READY STATUS RESTARTS AGE
|
|||
|
liveness-exec 0/1 Running 1 1m
|
|||
|
```
|
|||
|
|