前言
先上結論:
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。