一、序言
當你使用kuberentes的時候,有沒有遇到過Pod在啓動後一會就掛掉然後又重新啓動這樣的惡性循環?你有沒有想過kubernetes是如何檢測pod是否還存活?雖然容器已經啓動,但是kubernetes如何知道容器的進程是否準備好對外提供服務了呢?讓我們通過來一探究竟。首先pod在kubernetes中有5個狀態,我們大體瞭解一下這5個狀態,如下表:
名稱 | 描述 |
Pending | 系統已經接受pod實例的創建,但其中所包含容器的一個或者多個image還沒有創建成功。Pending包含調度計算與通過網絡創建image,所以此phase的時間可能會有點長。 |
Running | Pod已經被調度到某個node上,pod包含的所有容器已經創建完成,至少有一個容器正常運行或者處於啓動與重啓動過程。 |
Succeeded | Pod中的所有容器正常終止,並且不會再次啓動。 |
Failed | Pod中所有容器已終止運行,至少有一個容器非正常結束,比如退出碼非零,被系統強制殺死等。 |
Unknow | 無法取得pod狀態,一般是網絡問題引起。 |
我們可以通過kubectl describe pods {podName}來查看status狀態,瞭解到pod狀態以後,達到這個狀態的過程是如何呢?pod的生命週期到底是如何的呢?我們下面來一探究竟。
二、pod的生命週期
pod週期的過程如下5步:
1.初始化容器階段初始化pod中每一個容器,他們是串行執行的,執行完成後就退出了
2.啓動主容器main container
3.在main container剛剛啓動之後可以執行post start命令
4.在整個main container執行的過程中可以做兩類探測:liveness probe(存活探測)和readiness probe(就緒探測)
5.在main container結束前可以執行pre stop命令
如下圖:
其中liveness probe(存活探測)和readiness probe(就緒探測)、post start 、pre stop我們將詳細說明。
三、liveness probe和readiness
定義liveness probe探針
曾經的我在部署海量docker服務時遇到過這樣的問題,某臺服務器上跑了100個docker服務。有一天有1個docker宕機了,需要重新部署,這時候我花了很多時間找出問題節點並重新刪除、安裝,這時候我在想如果有一種方式能自動檢測並重啓,那該多好。
毫無疑問,liveness probe能幫我們解決這個問題,它的作用是確定何時重啓容器。例如,當應用程序處於運行狀態但無法做進一步操作,liveness探針將捕獲到deadlock,重啓處於該狀態下的容器,使應用程序在存在bug的情況下依然能夠繼續運行下去(誰的程序還沒幾個bug呢)。
在K8S中 我們只需在yaml文件中定義liveness probe字段便可解決。如下:
我們在運行容器時執行command命令 touch一個文件,再過60秒後,刪除這個文件
然後讓liveness probe 每隔5s檢測一次,我們將會看到容器在運行一段時間後,restart。
apiVersion: v1
kind: Pod
metadata :
name: liveness
namespace: default
spec:
containers:
- name: livenesscontainers
image: nginx
imagePullPolicy: IfNotPresent
command: ["/bin/bash","-c","touch /tmp/health;sleep 60;rm -rf /tmp/health;sleep 3600;"]
livenessProbe:
exec:
command: ["test","-e","/tmp/health"]
initialDelaySeconds: 1
periodSeconds: 3
其中command: ["test","-e","/tmp/health"] 爲探測的命令,如果命令執行成功,將返回0,kubelet就會認爲該容器是活着的並且很健康.。
initialDelaySeconds: X (代表開啓容器後X秒後再進行生命探測,如果結果爲0,kubelet就會殺掉這個容器並重啓它。)
periodSeconds: Y (代表每隔Y秒後探測一次)
定義一個liveness HTTP請求
該探針將向容器中的server的8080端口發送一個HTTP GET請求。如果server的/healthz
路徑的handler返回一個成功的返回碼,kubelet就會認定該容器是活着的並且很健康。如果返回失敗的返回碼,kubelet將殺掉該容器並重啓它。
apiVersion: v1
kind: Pod
metadata :
name: liveness
namespace: default
spec:
containers:
- name: livenesscontainers
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name:http
containersPort:8080
command: ["/bin/bash","-c","touch /tmp/health;sleep 60;rm -rf /tmp/health;sleep 3600;"]
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 3
periodSeconds: 3
定義readiness探針
有時,應用程序暫時無法對外部流量提供服務。 例如,應用程序可能需要在啓動期間加載大量數據或配置文件。 在這種情況下,你不想殺死應用程序,但你也不想發送請求。 Kubernetes提供了readiness probe來檢測和減輕這些情況。 Pod中的容器可以報告自己還沒有準備,不能處理Kubernetes服務發送過來的流量。
Readiness probe的配置跟liveness probe很像。唯一的不同是使用 readinessProbe
而不是livenessProbe
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
四、postStart和preStop(用的比較少)
如pod生命週期圖,當容器啓動以後Kubernetes會發送一個postStart事件,並且在容器退出之前理解發送一個preStop事件。這兩個鉤子,我們也可以運用起來,比如,您需要在下載github上的文件後再做一些事情....
下面是這個Pod的配置文件:
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
在這個配置文件裏面,可以看到postStart命令寫了一個message文件在容器的/usr/share目錄裏面。preStop命令優雅的退出nginx。如果容器因爲失敗而退出這是非常有用的。其中postStart是在執行完containers的command命令後再執行的,所以我們可以利用這個性質,做一些特定的事情。
現在我們已經學習完了pod的生命週期,瞭解到了pod的基本機制,下一節我們將繼續深入探討pod,感興趣的朋友,可以繼續更進,在此小編祝大家生活愉快。有技術交流的朋友請加微信:laughing_jk。
~~您身邊喜歡綠色的朋友
帥吉帥哥(Spring)