一、探針原理
分布式系統和微服務體系結構的挑戰之一是自動檢測不正常的應用程序,并將請求(request)重新路由到其他可用系統,恢復損壞的組件。健康檢查是應對該挑戰的一種可靠方法。使用 Kubernetes,可以通過探針配置運行狀況檢查,以確定每個 Pod 的狀態。
二、探針類型
liveness探針:影響的是單個容器,如果檢查失敗,將殺死容器,根據pod的restartPolicy來操作。
readiness探針:影響的是整個pod,即如果pod中有多個容器,只要有一個容器的readiness探針診斷失敗,那么整個pod都會處于unready狀態。
startup探針:指示容器中的應用是否已經啟動。如果提供了啟動探針(startup probe),則禁用所有其他探針,直到它成功為止。如果啟動探針失敗,kubelet 將殺死容器,容器服從其重啟策略進行重啟。如果容器沒有提供啟動探針,則默認狀態為成功Success
三、探針參數
initialDelaySeconds:容器啟動后第一次執行探測是需要等待多少秒。
periodSeconds:執行探測的頻率。默認是10秒,最小1秒。
timeoutSeconds:探測超時時間。默認1秒,最小1秒。
successThreshold:探測失敗后,最少連續探測成功多少次才被認定為成功。默認是1。對于liveness必須是1。最小值是1。
failureThreshold:探測成功后,最少連續探測失敗多少次才被認定為失敗。默認是3。最小值是1
四、探測結果
Success:Container通過了檢查。
Failure:Container未通過檢查。
Unknown:未能執行檢查,因此不采取任何措施。
五、探測運行原理
liveness probe(存活探針)
用于判斷容器是否存活,即Pod是否為running狀態,如果LivenessProbe探針探測到容器不健康,則kubelet將kill掉容器,并根據容器的重啟策略是否重啟。 如果一個容器不包含LivenessProbe探針,則Kubelet認為容器的LivenessProbe探針的返回值永遠成功。
有時應用程序可能因為某些原因(后端服務故障等)導致暫時無法對外提供服務,但應用軟件沒有終止,導致K8S無法隔離有故障的pod,調用者可能會訪問到有故障的pod,導致業務不穩定。 K8S提供livenessProbe來檢測應用程序是否正常運行,并且對相應狀況進行相應的補救措施。
readiness probe(就緒探針)
用于判斷容器是否啟動完成,即容器的Ready是否為True,可以接收請求,如果ReadinessProbe探測失敗,
若容器的Ready將為False,控制器將此Pod的Endpoint從對應的service的Endpoint列表中移除,從此不再將任何請求調度此Pod上,直到下次探測成功。
通過使用Readiness探針,Kubernetes能夠等待應用程序完全啟動,然后才允許服務將流量發送到新副本。
關于 Readiness 探針有一點很重要,它會在容器的整個生命周期中運行。這意味著 Readiness 探針不僅會在啟動時運行,而且還會在 Pod 運行期間反復運行。這是為了處理應用程序暫時不可用的情況(比如加載大量數據、等待外部連接時)。在這種情況下,我們不一定要殺死應用程序,可以等待它恢復。Readiness 探針可用于檢測這種情況,并在 Pod 再次通過 Readiness 檢查后,將流量發送到這些 Pod。
Startup probe(啟動探針)
startup 探針與 Readiness 探針類似,但它僅在啟動時執行,能針對啟動緩慢的容器或在初始化過程中有不可預測行為的應用程序進行優化。借助 Readiness 探針,我們可以配置 initialDelaySeconds 來確定 Readiness 探測在準備就緒前要等待多長時間。
六、探測方式
exec通過執行shell命令的方式,判斷退出狀態碼是否是0,針對復雜檢測或無HTTP接口的服務,命令返回值為0則表示容器健康。
tcpSocket:通過容器的IP和Port執行TCP檢查,kubelet嘗試打開容器上的某個端口,如果能夠建立TCP連接,則表明容器健康。
httpGet通過發送http請求檢查服務是否正常,每進行一次HTTP健康檢查都會curl訪問一次指定的URL,返回200-399狀態碼則表明容器健康,否則認為容器運轉不正常。
HTTP:
kubelet 將 HTTP GET 請求發送到 endpoint,并檢查 2xx 或 3xx 響應。我們可以重復使用現有的 HTTP endpoint 或設置輕量級 HTTP 服務器以進行探測(例如,具有 /healthz endpoint 的 Express server)。HTTP 探針包含其他額外參數:
host:要連接的主機名(默認值:pod 的 IP)。
scheme:HTTP(默認)或 HTTPS。
path:HTTP/S 服務器上的路徑 。
httpHeaders:自定義標頭(如果需要標頭用于身份驗證、CORS 設置等) 。
port:訪問服務器的端口名稱或端口號。
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-httpgetnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports:- name: nginx-portcontainerPort: 80livenessProbe:httpGet: # 其實就是訪問http://127.0.0.1:80/hello scheme: HTTP #支持的協議,http或者httpsport: 80 #端口號path: /hello #URI地址
TCP
如果僅需要檢查是否可以建立 TCP 連接,則可以指定 TCP 探針。如果建立 TCP 連接,則將 Pod 標記為運行狀況良好。對于不適合使用 HTTP 探針的 gRPC 或 FTP 服務器,TCP 探針可能會有用。
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-tcpsocketnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports: - name: nginx-portcontainerPort: 80livenessProbe:tcpSocket:port: 8080 # 嘗試訪問8080端口
Command
可以將探針配置為運行 shell 命令。如果命令返回的退出代碼為 0,則檢查通過,否則 Pod 將被標記為不健康。如果不希望公開 HTTP 服務器與端口,或者希望通過命令檢查初始化步驟(例如,檢查是否已創建配置文件、運行 CLI 命令),這種類型的探針會很有用
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-execnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports: - name: nginx-portcontainerPort: 80livenessProbe:exec:command: ["/bin/cat","/tmp/hello.txt"] # 執行一個查看文件的命令