Pod 健康检查(探针)
Posted 奋斗的蜗牛灬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pod 健康检查(探针)相关的知识,希望对你有一定的参考价值。
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
学习目标:
- 探针有哪些规则
- 通过什么方法检查
- 探针运行的方式
一、健康检查(探针)
健康检查:又称为探针( Probe),探针是由 kubelet 对容器执行的定期诊断。
官网示例:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
1.1 探针的三种规则
liveness Probe
- liveness Probe:存活探针:判断容器是否正在运行。如果探测失败,则 kubelet 会杀死容器,并且容器将根据 restartPolicy 来设置 pod状态。如果容器不提供存活探针,则默认状态为 Success。
readiness Probe
- readiness Probe:可读性探针:判断容器是否准备好接受请求。如果探测失败,端点控制器将从与 Pod 匹配的所有 service endpoints 中 剔除删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
startup Probe
- startup Probe(1.17版本增加的):**判断容器内的应用程序是否已启动,主要针对于不能确定具体启动时间的应用。**如果配置了 startupProbe 探测,在则在 startupProbe 状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。如果 startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe,则默认状态为Success。
注:以上规则可以同时定义。在 readinessProbe 检测成功之前,Pod 的 running 状态是不会变成 ready 状态的。
1.2 Probe 支持三种检查方法
- exec:在容器内执行 指定一段命令。如果命令退出时 返回码为 0 则认为诊断成功。
- tcpSocket:对指定端口上的容器的IP地址 进行TCP检查(三次握手)。如果端口打开,TCP 连接成功,则诊断被认为是成功的。
- httpGet:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码在 200~400 之间,则诊断被认为是成功的。监测的是 路径上的文件在不在。
每次探测都将获得以下三种结果之一:
● 成功:容器通过了诊断。
● 失败:容器未通过诊断。
● 未知:诊断失败,因此不会采取任何行动。
二、探针测试
2.1 exec 探测方式
//示例1: exec 方式
apiVersion: v1
kind: Pod #自主式pod类型
metadata:
labels:
trest: 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 60
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
failureThreshold: 1
initialDelayseconds: 5
periodSeconds: 5
//initialDelaySeconds:容器启动,探针延后工作,默认是0s。
指定 kubelet在执行第一次探测前 应延迟等待X秒后开始探测,即第一次探测是在容器启动后的第6秒才开始执行。默认是0秒,最小值是0。
//periodSeconds:探针探测周期,指定了kubelet应该每5秒执行一次存活探测。默认是10秒。最小值是1。
#failureThreshold:当探测失败时,Kubernetes将在放弃之前重试的次数。
存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是3。最小值是1。
#timeoutSeconds:探测的超时后等待多少秒。默认值是1秒。最小值是1。(在Kubernetes 1.20版本之前,exec 探针会忽略timeoutSeconds探针会无限期地持续运行,甚至可能超过所配置的限期,直到返回结果为止。)
可以看到Pod 中只有一个容器。kubelet 在执行第一次探测前需要等待5秒,kubelet 会每5秒执行一次存活探测。kubelet 在容器内执行命令 cat /tmp/healthy来进行探测。如果命令执行成功并且返回值为 0,kubelet就会认为这个容器是健康存活的。
vim exec.yaml
apiversion: v1
kind: Pod
metadata:
name: liveness-exec
namespace: default
spec:
containers:
- name: liveness-exec-container
image: busybox
imagePullPolicy: .IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live ; sleep 30; rm -rf /tmp/live; sleep 3600"]
livenessProbe : #设置存活探针
exec: #exec 检查方法
command: [ "test" , "-e", "/tmp/live"] #检查文件目录是否存在
initialDelayseconds: 1 #容器启动,探针延后1秒工作
periodSeconds: 3 #kubelet应该每3秒执行一次存活探测
#保存后,创建资源
kubectl create -f exec.yaml
kubectl describe pods liveness-exec
2.2 httpGet 方式
//示例2:httpGet方式
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
在这个配置文件中,可以看到 Pod 也只有一个容器。initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。kubelet 会向容器内运行的服务(服务会监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。
任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败。
vim httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: soscscs/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
kubectl create -f httpget.yaml
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-httpget 1/1 Running 1 2m44s
2.3 tcpSocket 方式
//示例3:tcpSocket方式
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
这个例子同时使用 readinessProbe 和 livenessProbe 探测。kubelet 会在容器启动 5 秒后发送第一个 readinessProbe 探测。这会尝试连接 goproxy 容器的 8080 端口。如果探测成功,kubelet 将继续每隔 10 秒运行一次检测。除了 readinessProbe 探测,这个配置包括了一个 livenessProbe 探测。kubelet 会在容器启动 15 秒后进行第一次 livenessProbe 探测。就像 readinessProbe 探测一样,会尝试连接 goproxy 容器的 8080 端口。如果 livenessProbe 探测失败,这个容器会被重新启动。
vim tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: soscscs/myapp:v1
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 8080
periodSeconds: 3
kubectl create -f tcpsocket.yaml
kubectl exec -it probe-tcp -- netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
probe-tcp 1/1 Running 0 4s
probe-tcp 1/1 Running 1 14s
probe-tcp 1/1 Running 2 26s
2.4 就绪检测
//示例4:就绪检测
vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: soscscs/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
kubectl create -f readiness-httpget.yaml
//readiness探测失败,无法进入READY状态
kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget 0/1 Running 0 18s
kubectl exec -it readiness-httpget sh
# cd /usr/share/nginx/html/
# ls
50x.html index.html
# echo 123 > index1.html
# exit
kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget 1/1 Running 0 2m31s
kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
readiness-httpget 1/1 Running 0 4m10s
readiness-httpget 0/1 Running 1 4m15s
//示例5:就绪检测2
vim readiness-myapp.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp1
labels:
app: myapp
spec:
containers:
- name: myapp
image: soscscs/myapp:v1
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:
name: myapp2
labels:
app: myapp
spec:
containers:
- name: myapp
image: soscscs/myapp:v1
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:
name: myapp3
labels:
app: myapp
spec:
containers:
- name: myapp
image: soscscs/myapp:v1
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
kubectl create -f readiness-myapp.yaml
kubectl get pods,svc,endpoints -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp1 1/1 Running 0 3m42s 10.244.2.13 node02 <none> <none>
pod/myapp2 1/1 Running 0 3m42s 10.244.1.15 node01 <none> <none>
pod/myapp3 1/1 Running 0 3m42s 10.244.2.14 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
......
service/myapp ClusterIP 10.96.138.13 <none> 80/TCP 3m42s app=myapp
NAME ENDPOINTS AGE
......
endpoints/myapp 10.244.1.15:80,10.244.2.13:80,10.244.2.14:80 3m42s
kubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html
//readiness探测失败,Pod 无法进入READY状态,且端点控制器将从 endpoints 中剔除删除该 Pod 的 IP 地址
kubectl get pods,svc,endpoints -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp1 0/1 Running 0 5m17s 10.244.2.13 node02 <none> <none>
pod/myapp2 1/1 Running 0 5m17s 10.244.1.15 node01 <none> <none>
pod/myapp3 1/1 Running 0 5m17s 10.244.2.14 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
......
service/myapp ClusterIP 10.96.138.13 <none> 80/TCP 5m17s app=myapp
NAME ENDPOINTS AGE
......
endpoints/myapp 10.244.1.15Pod 健康检查(探针)
pod健康检查(LivenessProbe和ReadinessProbe)
pod健康检查详解(liveness,readiness,滚动更新)