前言

先上结论:

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。