一、概述
在 spring boot 2.3 中引入了容器探針舆声,也就是增加了 /actuator/health/liveness
和 /actuator/health/readiness
這兩個健康檢查路徑端壳,對于部署在 k8s 中的應用,spring-boot-actuator 將通過這兩個路徑自動進行健康檢查志膀。本文主要根據(jù)官方文檔的描述實踐并記錄使用流程佑吝,從如下幾個方面進行介紹:
二坐昙、K8s 容器健康檢查
1、k8s 中的探針
kubernetes
提供了三種探針(支持exec迹蛤、tcp和http方式)來探測容器的狀態(tài):
-
LivenessProbe:容器存活性檢查民珍,用于判斷容器是否健康襟士,告訴
kubelet
一個容器什么時候處于不健康的狀態(tài)盗飒。如果LivenessProbe
探針探測到容器不健康,則kubelet
將刪除該容器陋桂,并根據(jù)容器的重啟策略做相應的處理逆趣。如果一個容器不包含LivenessProbe
探針,那么kubelet
認為該容器的LivenessProbe
探針返回的值永遠是 Success嗜历; -
ReadinessProbe:容器就緒性檢查宣渗,用于判斷容器是否啟動完成且準備接收請求抖所。如果
ReadinessProbe
探針探測到失敗,Endpoint Controller
將從Service
的Endpoint
中刪除包含該容器所在 Pod 的 IP 地址的Endpoint
條目痕囱。如果容器不提供就緒態(tài)探針田轧,則默認狀態(tài)為 Success。 -
startupProbe: 容器啟動檢查鞍恢,指示容器中的應用是否已經(jīng)啟動傻粘。如果提供了啟動探針,則所有其他探針都會被禁用帮掉,直到此探針成功為止弦悉。如果啟動探測失敗,
kubelet
將殺死容器蟆炊,而容器依其重啟策略進行重啟稽莉。 如果容器沒有提供啟動探測,則默認狀態(tài)為 Success涩搓。
startupProbe 是在k8s v1.16加入了alpha版污秆,官方對其作用的解釋是:
Indicates whether the application within the Container is started. All other probes are disabled if a startup probe is provided, until it succeeds. If the startup probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a startup probe, the default state is Success
2、k8s 的探針處理程序
Probe 探針檢查是由 kubelet 對容器執(zhí)行的定期診斷昧甘,kubelet 調(diào)用由容器實現(xiàn)的 Handler (處理程序)混狠,每一個探針都可以配置如下三種類型的處理程序:
- ExecAction: 在容器內(nèi)執(zhí)行指定命令,如果命令退出時返回碼為 0 則認為診斷成功疾层。
通過執(zhí)行命令的方式來檢查服務是否正常将饺,比如使用 cat 命令查看 pod 中的某個重要配置文件是否存在,若存在痛黎,則表示pod健康予弧,反之異常。Exec 探測方式的 yaml 文件語法如下:
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe: #選擇livenessProbe的探測機制
exec: #執(zhí)行以下命令湖饱,如果文件存在則探測成功
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5 #在容器運行五秒后開始探測
periodSeconds: 5 #檢查時間間隔為 5s 檢查一次
-
TCPSocketAction: 對容器的 IP 地址上的指定端口執(zhí)行 TCP 檢查掖蛤,如果端口打開,則診斷被認為是成功的井厌。
這種方式與HTTPget的探測機制有些類似蚓庭,tcpsocket健康檢查適用于TCP業(yè)務,tcpSocket探測方式的yaml文件語法如下:
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
#這里兩種探測機制都用上了仅仆,都是為了和容器的8080端口建立TCP連接
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5 # 容器啟動 5s 后開始第一次就緒性探測
periodSeconds: 10 # 每 10s 進行一次探測
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15 # 容器啟動 15s 后開始第一次就存活性探測
periodSeconds: 20 # 每 20s 進行一次探測
在上述的yaml配置文件中器赞,兩類探針都使用了,在容器啟動5秒后墓拜,kubelet將發(fā)送第一個readinessProbe探針港柜,這將連接容器的8080端口,如果探測成功,則該pod為健康夏醉,十秒后爽锥,kubelet將進行第二次連接。
除了readinessProbe探針外畔柔,在容器啟動15秒后氯夷,kubelet將發(fā)送第一個livenessProbe探針较店,仍然嘗試連接容器的8080端口平匈,如果連接失敗,則重啟容器阔加。
- HTTPGetAction: 對容器的 IP 地址上指定端口和路徑執(zhí)行 HTTP Get 請求奢啥,如果響應的狀態(tài)碼大于等于 200 且小于 400秸仙,則診斷被認為是成功的。
Httpget探測方式的yaml文件語法如下:
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
livenessProbe: #采用livenessProbe機制探測
httpGet: #采用httpget的方式
scheme: HTTP #指定協(xié)議桩盲,也支持https
path: /healthz #檢測是否可以訪問到網(wǎng)頁根目錄下的healthz網(wǎng)頁文件
port: 8080 #監(jiān)聽端口是8080
initialDelaySeconds: 3 #容器運行3秒后開始探測
periodSeconds: 3 #探測頻率為3秒
上述配置文件中寂纪,探測方式為項容器發(fā)送HTTP GET請求,請求的是 8080 端口下的 healthz 文件赌结,返回任何大于或等于200且小于400的狀態(tài)碼表示成功捞蛋,任何其他代碼表示異常。
每次探測都將獲得以下三種結果之一:
- Success(成功):容器通過了診斷柬姚。
- Failure(失斈馍肌):容器未通過診斷。
- Unknown(未知):診斷失敗量承,因此不會采取任何行動搬设。
3、k8s 探針的配置
Probe 有如下配置字段撕捍,可以使用這些字段精確的控制存活和就緒檢測的行為:
- initialDelaySeconds:容器啟動后要等待多少秒后存活和就緒探測器才被初始化拿穴,默認是 0 秒,最小值是 0忧风。
- periodSeconds:執(zhí)行探測的時間間隔(單位是秒)默色。默認是 10 秒。最小值是 1狮腿。
- timeoutSeconds:探測的超時后等待多少秒腿宰。默認值是 1 秒。最小值是 1缘厢。
- successThreshold:探測器在失敗后吃度,被視為成功的最小連續(xù)成功數(shù)。默認值是 1昧绣。 存活和啟動探測的這個值必須是 1规肴。最小值是 1捶闸。
- failureThreshold:當探測失敗時夜畴,Kubernetes 的重試次數(shù)拖刃。 存活探測情況下的放棄就意味著重新啟動容器。 就緒探測情況下的放棄 Pod 會被打上未就緒的標簽贪绘。默認值是 3兑牡。最小值是 1。
說明:在 Kubernetes 1.20 版本之前税灌,exec 探針會忽略 timeoutSeconds:探針會無限期地 持續(xù)運行均函,甚至可能超過所配置的限期,直到返回結果為止菱涤。這一缺陷在 Kubernetes v1.20 版本中得到修復苞也。
LivenessProbe配置例子:
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30 // 容器啟動30s后啟動第一次探測
periodSeconds: 10 // 每隔10s啟動一次探測
timeoutSeconds: 3 // 超時時間3s
successThreshold: 1 // 成功1次即表示容器健康
failureThreshold: 5 // 連續(xù)5次失敗,則判定容器不健康粘秆,默認3次
4如迟、何時使用
何時使用啟動探針
kubelet 使用啟動探測器可以知道應用程序容器什么時候啟動了。 如果配置了這類探測器攻走,就可以控制容器在啟動成功后再進行存活性和就緒檢查殷勘, 確保這些存活、就緒探測器不會影響應用程序的啟動昔搂。 這可以用于對慢啟動容器進行存活性檢測玲销,避免它們在啟動運行之前就被殺掉。
何時使用存活探針
kubelet 使用存活探測器來知道什么時候要重啟容器摘符。 例如贤斜,存活探測器可以捕捉到死鎖(應用程序在運行,但是無法繼續(xù)執(zhí)行后面的步驟)逛裤。 這樣的情況下重啟容器有助于讓應用程序在有問題的情況下更可用蠢古。
何時使用就緒探針
kubelet 使用就緒探測器可以知道容器什么時候準備好了并可以開始接受請求流量, 當一個 Pod 內(nèi)的所有容器都準備好了别凹,才能把這個 Pod 看作就緒了草讶。 這種信號的一個用途就是控制哪個 Pod 作為 Service 的后端。 在 Pod 還沒有準備好的時候炉菲,會從 Service 的負載均衡器中被剔除的堕战。
5、使用啟動探測器保護慢啟動容器
有時候拍霜,會有一些現(xiàn)有的應用程序在啟動時需要較多的初始化時間嘱丢。 要不影響對引起探測死鎖的快速響應,這種情況下祠饺,設置存活探測參數(shù)是要技巧的越驻。 技巧就是使用一個命令來設置啟動探測,針對HTTP 或者 TCP 檢測,可以通過設置 failureThreshold * periodSeconds
參數(shù)來保證有足夠長的時間應對糟糕情況下的啟動時間缀旁。
所以记劈,前面的例子就變成了:
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
幸虧有啟動探測,應用程序?qū)凶疃?5 分鐘(30 * 10 = 300s) 的時間來完成它的啟動并巍。 一旦啟動探測成功一次目木,存活探測任務就會接管對容器的探測,對容器死鎖可以快速響應懊渡。 如果啟動探測一直沒有成功刽射,容器會在 300 秒后被殺死,并且根據(jù) restartPolicy 來設置 Pod 狀態(tài)剃执。
參考文章: