一、概述
RestartPolicy
默認情況下,容器啟動的時候會執行一個主進程,如果進程退出碼不是0,則k8s會認為該容器異常,而此時k8s會根據事先設置的restartPolicy策略來選擇如何處理容器。目前常用的restartPolicy有以下三種:
Always:當容器終止退出后,總是重啟容器,默認策略
Onfailure:當容器異常退出時(退出碼為非0),重啟容器
Never:當容器終止退出時,不重啟容器
健康檢查機制
如上述所述,restartpolicy的觸發條件是容器退出的返回值為非零,然后被認為是容器故障,需要重啟。但是,很多時候容器pod本身的啟動沒有異常,而卻出現了應用層面上的錯誤,如資源資源鎖死,進程OOM等等,此時服務依舊是啟動失敗,但是容器並沒有觸發重啟操作,這種情況下就需要k8s的健康檢查機制出手了。
k8s的健康檢查(Health Check)常用於檢測容器中的應用實例是否處於正常工作中,是一種用於保障業務可用性的機制。在負載均衡的情況下,如果實例的狀態不符合預期,則會把該實例“踢”下線,不承擔相應的業務流量,等待其重啟恢復正常。
k8s的健康檢查有主要以探針的方式來進行,目前有以下三種探針:
Liveness probes
Readiness probes
Startup probes
而通過結合Restartpolicy和健康檢查機制,k8s可以實現以下需求:
異常實例自動剔除並重啟相關實例
多種類型探針檢查,保證異常的pod不接受業務流量
無感發布,可用性更高的滾動升級
二、探針的探測方式及參數
上述描述的三類探針目前支持的探測方式包括以下三種方式:
httpGet
tcpSocket
exec
除了上述方式以外,探針還支持很多配置參數,通過這些參數能夠精確地控制指針的檢測行為:
#全局參數
initialDelaySeconds:容器啟動后要等待多少秒后存活和就緒探測器才被初始化,默認是 0 秒,最小值是 0。
periodSeconds:執行探測的時間間隔(單位是秒)。默認是 10 秒。最小值是 1。
timeoutSeconds:探測的超時后等待多少秒。默認值是 1 秒。最小值是 1。
successThreshold:探測器在失敗后,被視為成功的最小連續成功數。默認值是 1。存活探測的這個值必須是 1。最小值是 1。
failureThreshold:當探測失敗時,Kubernetes 的重試次數。存活探測情況下的放棄就意味着重新啟動容器。就緒探測情況下的放棄 Pod 會被打上未就緒的標簽。默認值是 3。最小值是 1。
#對於http檢測方式的指針,可以在httpGet上配置額外的參數字段
host:連接使用的主機名,默認是 Pod 的 IP。也可以在 HTTP 頭中設置 “Host” 來代替。
scheme :用於設置連接主機的方式(HTTP 還是 HTTPS)。默認是 HTTP。
path:訪問 HTTP 服務的路徑。
httpHeaders:請求中自定義的 HTTP 頭。HTTP 頭字段允許重復。
port:訪問容器的端口號或者端口名。如果數字必須在 1 ~ 65535 之間。
三、livenessProbe
Liveness probes(存活性探針)用於檢查容器pod中的應用程序是否存活,當pod中的應用程序被檢查為不存活時,k8s會刪除pod並按照設定的restartpolicy處理pod。
配置exec方式的Liveness probes
apiVersion: v1
kind: Pod
metadata:
labels:
test: tomcat
name: tomcat-example
spec:
containers:
- name: tomcat
image: dockerhub.kungeek.com/csp/ftsp-api-test:11111
ports:
- containerPort: 8080
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 5
這種方式的存活檢測,kubelet 在容器內執行命令 cat /tmp/healthy 來進行探測。如果命令執行成功並且返回值為 0,kubelet 就會認為這個容器是健康存活的。如果這個命令返回非 0 值,kubelet 會殺死這個容器並重新啟動它。
配置TCP方式的Liveness probes
apiVersion: v1
kind: Pod
metadata:
labels:
test: tomcat
name: tomcat-example
spec:
containers:
- name: tomcat
image: dockerhub.kungeek.com/csp/ftsp-api-test:11111
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 5
這種方式的存活探測是使用 TCP 套接字。通過配置,kubelet 會嘗試在指定端口和容器建立套接字鏈接。如果能建立鏈接,這個容器就被看作是健康的,如果不能則這個容器就被看作是有問題的。
配置http方式的Liveness probes
apiVersion: v1
kind: Pod
metadata:
labels:
test: tomcat
name: tomcat-example
spec:
containers:
- name: tomcat
image: dockerhub.kungeek.com/csp/ftsp-api-test:11111
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
這種存活探測方式是使用 HTTP GET 請求得到請求的返回碼,任何大於或等於 200 並且小於 400 的返回碼標示成功,其它返回碼都標示失敗。
四、readinessProbe
Readiness Probes又名為就緒探測器,用於在容器啟動后探測應用程序是否已經啟動完成並做好處理業務流量的准備。
Readiness Probes與Liveness Probes的配置類似,唯一的區別就是使用readinessProbe
關鍵字來替換到livenessProbe
關鍵字。
示例:
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe與livenessProbe可在同一個容器上並行使用,可以確保流量不會被發給還沒准備好的容器,並且在容器出現異常失敗的時候將其重新啟動。
五、startupProbe
在某些情況下,容器中的應用程序啟動的時候有可能需要較多的初始化時間,這時候為了得出正確的健康檢查結果,我們需要靈活地根據初始化時間來調整相關的健康檢查參數(如:
initialDelaySeconds),除此之外K8S在1.16版本之后提供了一個新的關鍵字startupProbe
來應對這種啟動時間過長的情況。在startupProbe
檢測中,通過設置failureThreshold * periodSeconds
參數來保證有足夠長的時間來應對這種慢啟動的情況。
示例:
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
如此一來,應用程序將會有最多 5 分鍾(30 * 10 = 300s) 的時間來完成它的啟動。 一旦啟動探測成功一次,存活探測任務就會接管對容器的探測,對容器死鎖可以快速響應。 如果啟動探測一直沒有成功,容器會在 300 秒后被殺死,並且根據 restartPolicy 來設置 Pod 狀態。