目錄
- 簡介
- 什麼是探針
- Liveness Probe(存活探針)
- Readiness Probe(就緒探針)
- Startup Probe(啟動探針)
- 什麼時候使用探針?
- 何時使用存活探針(Liveness Probe)
- 何時使用就緒探針(Read iness Probe)
- 何時使用啟動探針(Startup Probe)
- 容器探測方法
- exec
- httpGet
- tcpSocket
- 容器探測使用
- livenessProbe使用
- exec使用
- httpGet使用
- tcpSocket
- readinessProbe使用
- exec使用
- httpGet使用
- tcpSocket使用
- startupProbe使用
- httpGet使用
- tcpSocket使用
- livenessProbe使用
簡介
在Pod的生命週期中,可以執行多種操作如下圖:
- 初始化容器:主容器啟動前,可以先執行一個或多個初始化容器。初始化容器是序列執行的,必須全部成功完成後才會啟動主容器。初始化容器執行結束後即退出,不再佔用資源。
- Post Start鉤子:主容器啟動後,可以指定一個Post Start鉤子,用於在主容器啟動後執行一些額外的操作。
- Pre Stop鉤子:在主容器終止之前,可以指定一個Pre Stop鉤子,用於在主容器結束前執行必要的清理或其他操作。
- 健康探針:Pod啟動後,其健康狀態由以下幾類探針進行檢測:
- Startup Probe(啟動探針):用於確保容器成功啟動,在啟動完成前其他探針不會干擾容器的啟動過程。
- Liveness Probe(存活探針):用於檢測容器是否存活。如果探測失敗,Kubernetes會重啟該容器。
- Readiness Probe(就緒探針):用於檢測容器是否已準備好接收流量。如果探測失敗,該Pod將暫時從服務端點中移除,直到其恢復就緒狀態。
什麼是探針
在Kubernetes中,探針(Probe)用於管理容器的生命週期,主要包括以下三種型別:
Liveness Probe(存活探針)
- 作用:判斷容器是否處於執行狀態(即容器是否存活)。
- 行為:
- 如果Liveness Probe探測到容器處於非健康狀態,kubelet會殺掉該容器,並根據容器的重啟策略進行處理。
- 如果未配置Liveness Probe,kubelet會預設認為容器始終處於“成功”狀態。
- 場景:Liveness Probe用於捕捉容器死鎖等問題。例如,當應用程式雖然執行但無法處理請求時,探針會檢測到這個問題,並重啟容器,使應用在存在bug的情況下依然能夠繼續執行。
Readiness Probe(就緒探針)
- 作用:判斷容器是否已啟動完成並準備好接受請求。
- 行為:
- 如果Readiness Probe探測失敗,Pod的狀態會被修改,Endpoint Controller會將該Pod從Service的Endpoint中移除。
- 如果未配置Readiness Probe,kubelet會預設認為容器處於“成功”狀態。
- 場景:Readiness Probe用於控制哪些Pod可以作為Service的後端。如果Pod處於非就緒狀態,它將被從Service的負載均衡中移除。
Startup Probe(啟動探針)
- 作用:檢測應用程式是否已完全啟動。
- 行為:
- 在Startup Probe成功之前,其他探針(Liveness和Readiness)將被禁用。
- 如果Startup Probe探測失敗,kubelet將終止容器並根據重啟策略重啟它。
- 如果未配置Startup Probe,kubelet會預設認為容器已成功啟動。
- 場景:Startup Probe適用於啟動時間較長的應用程式,確保應用完全啟動後再啟用其他探針。
透過合理配置這三類探針,可以確保Kubernetes中的容器在生命週期的各個階段都處於健康狀態,並能夠及時處理異常情況。
什麼時候使用探針?
何時使用存活探針(Liveness Probe)
- 容器可能卡死或無響應:如果你的應用程式在遇到問題時可能卡死或進入無響應狀態,而不會自行崩潰,那麼就應該使用存活探針。Liveness Probe 可以檢測到這些狀態,並觸發 kubelet 終止並重啟容器。
- 確保自動重啟:如果你希望容器在探測失敗時被殺死並重新啟動,以確保應用的持續可用性,那麼應配置存活探針。此時,可以將
restartPolicy
設定為Always
或OnFailure
,以確保在探針檢測到問題時容器能夠自動重啟。
何時使用就緒探針(Read iness Probe)
- 控制流量路由:如果你希望只有在探測成功時才開始向 Pod 傳送請求流量,就需要指定就緒探針。就緒探針常與存活探針相同,但它確保 Pod 在啟動階段不會接收任何資料,只有探測成功後才開始接收流量。
- 維護狀態:如果希望容器能自行進入維護狀態,可以使用就緒探針,檢查與存活探針不同的特定端點。對於依賴於後端服務的應用程式,可以同時使用存活探針和就緒探針。存活探針檢測容器本身的健康狀況,而就緒探針則確保所需的後端服務可用,避免將流量導向出錯的 Pod。
- Pod 刪除:注意,如果只是想在 Pod 被刪除時排空請求,通常不需要使用就緒探針。Pod 在刪除時會自動進入未就緒狀態,無論是否有就緒探針,直到容器停止為止。
何時使用啟動探針(Startup Probe)
- 應用啟動慢:如果容器在啟動期間需要載入大型資料或配置檔案,可以使用啟動探針。它確保在啟動完成前不會觸發其他探針。
容器探測方法
exec
執行一段命令,根據返回值判斷執行結果。
返回值為0, 非0兩種結果,可以理解為"echo $?"。
httpGet
透過發起HTTTP協議的GET請求檢測某個http請求的返回狀態碼,從而判斷服務是否正常。
常見的狀態碼分為很多類,比如: "2xx,3xx"正常, "4xx,5xx"錯誤。
200: 返回狀態碼成功。
301: 永久跳轉,會將跳轉資訊快取到瀏覽器本地。
302: 臨時跳轉,並不會將本次跳轉快取到本地。
401: 驗證失敗。
403: 許可權被拒絕。
404: 檔案找不到。
413: 檔案上傳過大。
500: 伺服器內部錯誤。
502: 無效的請求。
504: 後端應用閘道器相應超時。
tcpSocket
測試某個TCP埠是否能夠連線,類似於telnet這樣的工具。
每次探測都將獲得以下三種結果之一:
- Success(成功):容器透過了診斷。
- Failure(失敗):容器未透過診斷。
- Unknown(未知):診斷失敗,因此不會採取任何行動。
容器探測使用
livenessProbe使用
exec使用
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-exec
spec:
containers:
- name: nginx
image: nginx:1.18
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600
# 定義健康檢查探針
livenessProbe:
# 指定探針的檢測方法為exec。
exec:
# 指定exec要執行的命令
command:
- cat
- /tmp/healthy
# 指定第一次進行健康檢查的秒數,該值在生產環境中應該確保這個延遲時間內容器可以正常啟動執行。
initialDelaySeconds: 15
# 指定每次週期的健康檢查的間隔時間。
periodSeconds: 5
# 指定執行exec定義命令的超時的秒數。
timeoutSeconds: 1
# 檢查1次成功就認為服務是健康的。
successThreshold: 1
# 檢查連續3次失敗就認為服務是不健康的。
failureThreshold: 3
httpGet使用
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-httpGet
spec:
containers:
- name: nginx
image: nginx:1.18
ports:
- containerPort: 80
# 定義健康檢查探針
livenessProbe:
httpGet: # 指定探針的檢測方法為httpGet。
path: /index.html # 指定訪問的檔案路徑資訊即可,無需指定IP地址,因為預設就是訪問本機,可以理解為127.0.0.1。
port: 80 # 指定對容器的哪個埠傳送GET請求。
initialDelaySeconds: 15
# 指定每次週期的健康檢查的間隔時間。
periodSeconds: 5
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
tcpSocket
apiVersion: apps/v1
kind: Deployment
metadata:
name: livenessprobe-tcpsocket
spec:
replicas: 1
selector:
matchLabels:
app: livenessprobe-tcpsocket
template:
metadata:
labels:
app: livenessprobe-tcpsocket
spec:
containers:
- name: nginx
image: registry.cn-guangzhou.aliyuncs.com/jiajia-k8s/nginx:1.21
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- tail -f /etc/hosts
livenessProbe:
tcpSocket:
port: 80 # 檢測80埠是否可以連通,若連不通則會丟擲檢查容器出現問題,而後重啟容器。
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
failureThreshold: 2
很明顯,上述案例暴露了80埠,由於啟動容器時並沒有啟動nginx,而是去使用tail指令去檢視一個檔案內容達到阻塞容器的目的,因此在容器啟動10後就開始第一次檢查,而後每個3秒檢查1次,達到指定次數後會觸發重啟操作,可以看到55秒內探測了4次,52秒內重啟了兩次
readinessProbe使用
exec使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: readinessProbe-exec
labels:
apps: nginx
spec:
replicas: 3
selector:
matchLabels:
apps: nginx
template:
metadata:
name: nginx
labels:
apps: nginx
spec:
containers:
- name: nginx
image: nginx:1.18
command:
- /bin/bash
- -c
- touch /tmp/nginx-healthy; sleep 60; rm -f /tmp/nginx-healthy; sleep 60;
livenessProbe:
exec:
command:
- cat
- /tmp/nginx-healthy
failureThreshold: 3
initialDelaySeconds: 15
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
exec:
command:
- cat
- /tmp/nginx-healthy-2023
failureThreshold: 3
initialDelaySeconds: 15
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
從事件日誌來看,Liveness Probe
和 Readiness Probe
都因為無法找到 /tmp/nginx-healthy
檔案而失敗。這是由於容器中的命令在 60 秒後刪除了該檔案,導致探針在檢查時無法訪問該檔案。
- Liveness Probe 失敗觸發了容器重啟。此探針用於檢測容器是否健康,不健康時會重啟容器。
- Readiness Probe 失敗使得 Pod 從 Service 的 Endpoints 列表中移除,導致 Pod 無法接收流量。這表示 Pod 當前無法處理請求。
httpGet使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: readinessprobe-httpget
spec:
replicas: 1
selector:
matchLabels:
app: readinessprobe-httpget
template:
metadata:
labels:
app: readinessprobe-httpget
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /healthz # HTTP 請求的路徑
port: 80 # 容器內服務的埠
initialDelaySeconds: 15
periodSeconds: 5
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
tcpSocket使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: readinessprobe-tcpsocket
spec:
replicas: 1
selector:
matchLabels:
app: readinessprobe-tcpsocket
template:
metadata:
labels:
app: readinessprobe-tcpsocket
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
livenessProbe:
tcpSocket:
port: 80
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 15
periodSeconds: 5
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
startupProbe使用
httpGet使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: startupprobe-httpget
spec:
replicas: 1
selector:
matchLabels:
app: startupprobe-httpget
template:
metadata:
labels:
app: startupprobe-httpget
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /startup
port: 80
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 5
tcpSocket使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: startupprobe-tcpsocket
spec:
replicas: 1
selector:
matchLabels:
app: startupprobe-tcpsocket
template:
metadata:
labels:
app: startupprobe-tcpsocket
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
startupProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 5