liveness和readiness的区别
前言
先上结论:
liveness探针检测失败后,pod会被终止或重启(依据重启策略),而readiness探针检测失败后,pod不会终止,但ready状态为0
测试
liveness
清单文件 liveness-exec-pod.yaml :
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/healthy; sleep 20; rm -rf /tmp/healthy; sleep 3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/healthy"]
initialDelaySeconds: 1
periodSeconds: 10
应用清单
kubectl apply -f liveness-exec-pod.yaml
查看pod状态
# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
liveness-exec-pod 1/1 Running 0 3s
liveness-exec-pod 1/1 Running 1 80s
liveness-exec-pod 1/1 Running 2 2m40s
liveness-exec-pod 1/1 Running 3 4m
可以看到每隔一段时间pod会重启一次。
readness
清单文件 readiness-httpget-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: readness-exec-pod
namespace: default
labels:
app: nginx
spec:
containers:
- name: readness-exec-container
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe: #readiness类型的探针不会触发容器重启,和readiness探针不一样
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3 #每隔3秒检测一次
failureThreshold: 3 #连续检测3次
---
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: default
spec:
selector: #指定标签选择器选择的标签范围.
app: nginx
clusterIP: "10.96.96.96"
type: NodePort
ports:
- name: http
port: 8100 #设定Serivce对外提供服务的端口,当service类型为headless时,不需要该配置
targetPort: 80 #设定容器(Pod)的端口,即Pod网络的端口。
nodePort: 32001 #它仅在type为NodePort时才需要指定.
应用清单
kubectl apply -f readness-exec-pod.yaml
查看iptables规则,在node节点执行:
iptables -t nat -nvL |grep 'web-service' |grep 'DNAT'
输出:
431 25860 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/web-service:http */ tcp to:10.244.0.17:80
可以看到web-serviced的http端口绑定了10.244.0.17这个pod的80端口
接下来在任意pod里执行:
while true ; do wget -q -O - http://10.96.96.96:8100 ;sleep 1; done
输出:
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
...
此时在 readness-exec-pod
这个pod里删除usr/share/nginx/html/index.html这个文件,上面会继续输出如下部分内容:
wget: server returned error: HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden
wget: can't connect to remote host (10.96.96.96): Connection refused
wget: can't connect to remote host (10.96.96.96): Connection refused
wget: can't connect to remote host (10.96.96.96): Connection refused
...
前7行的报错是因为就绪探针需要连续3次检测失败才会终止容器,所以在这期间请求还是会进来,由于index.html文件被删除了,所以报403。
接下来报Connection refused的错误是因为就绪探针连续3次检测都失败后容器终止,同时service与endpoint解绑,导致连接被拒绝。我们可以查看iptables规则来验证下:
在node节点执行:
iptables -t nat -nvL |grep 'web-service' |grep 'DNAT'
发现里面没有任何关于这个service的DNAT规则。
查看pod状态:
kubectl get pods
NAME READY STATUS RESTARTS AGE
readness-exec-pod 0/1 Running 0 82m
可以看到pod的状态为running,但ready为0,说明就绪探针检测失败后,容器不会终止,但service也不会再关联到该pod。