kubernetes-x/MD/kubernetes健康检查机制.md

205 lines
7.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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"。这时,如果这个文件存在,这条命令的返回值就是 0Pod 就会认为这个容器不仅已经启动,而且是健康的。这个健康检查,在容器启动 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
```