Health Check
健康檢查,直白點說就是防微杜漸,k8s是一個編排引擎我們通過k8s部署容器集群,如果說集群容器沒有健康檢查這個過程,我們無法預知我們生產環境會不會部署上錯誤的容器導致服務崩潰。好在k8s 幫我們考慮到了這個問題,健康檢查是k8s重要特性之一,默認有健康檢查,還可以主動設置一些健康檢查。
接下來我們一步步深入瞭解下k8s的健康檢查。
1. 默認的健康檢查
dockerfile製作鏡像的時候,我們CMD,ENTRYPOINT會指定運行命令,容器完成指令之後退出時返回碼非零,則判定發生故障,然後根據 restartPolicy 策略重啟容器。默認的重啟策略是Always 。
healthcheck.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: healthcheck
name: healthcheck
spec:
restartPolicy: OnFailure
containers:
- name: healthcheck
image: busybox
args:
- /bin/sh
- -c
- sleep 10; exit 1
參數解析
restartPolicy: OnFailure 重啟的策略是失敗便重啟
args 是容器啟動後運行的命令
資源管理
創建資源
kubectl apply -f healthy.yml
查看pod狀態
kubectl get pod healthcheck
可以發現RESTARTS已經重啟多次。
優缺點
優點:可以通過restartPolicy 的策略,解決一下重啟就能解決的問題
缺點:必須等到進程退出後的返回值是非零才會觸發重啟策略,不能直接監測容器是否是健康
2. liveness 探測的健康檢查
liveness 的功能就是我們可以自己定義判斷容器健康的條件,然後去監測容器是否滿足健康條件,不健康執行重啟自愈。
liveness.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness
spec:
restartPolicy: OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
參數解析
livenessProbe 定義判斷容器健康的條件
exec 交互輸入界面
command 命令行命令
initialDelaySeconds 設置容器啟動後多久執行liveness
periodSeconds 指定每隔多久執行一次liveness
如果三次liveness 探測都失敗了,容器就會重啟
資源管理
kubectl apply -f liveness.yml
kubectl get pod liveness
3. readiness 探測的健康檢查
判斷容器何時可以進入service 負載均衡池中,例如在滾動更新過程中,判斷更新的容器是否滿足條件能夠完成業務,不符合的暫停更新,保證有足夠多的業務容器能正常工作。
readiness.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: readiness
name: readiness
spec:
restartPolicy: OnFailure
containers:
- name: readiness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe 定義判斷容器健康的條件
這裡會經歷三個過程:
過程一:剛被創建時,pod不可用
過程二:15秒後第一次探測成功,pod設置可用
過程三:30秒後監測文件被刪除,連續三次的探測失敗之後,pod設置不可用
資源管理
kubectl apply -f readiness.yml
kubectl get pod readiness
4. Scale up中的運用Health Check
scaleupcheck.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
template:
metadata:
labels:
run: web
spec:
containers:
- name: web
image: httpd
ports:
- containerPort: 80
readinessProbe:
httpGet:
scheme: HTTP
port: 80
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
run: web
ports:
- protocol: TCP
port: 8080
targetPort: 80
參數說明
readinessProbe 定義判斷容器健康的條件
httpGet 一種探測方式,需要返回的代碼在200~400之間
scheme 指定協議,支持http和https
port 指定端口
path 指定路徑
由yml文件可知,我們設置pod容器端口80和服務端口8080綁定,實際監測的是容器的端口
資源管理
kubectl apply -f scaleupcheck.yml
kubectl get deployment
kubectl get pod web -o wide
kubectl get service
5. 滾動更新中運用Healthy Check
解決了副本正常運行需要準備時間,配置錯誤副本無法完成準備工作。
說白了就是更新的時候,默認的Healthy Check認為副本已經準備好了,逐步用新的副本替換舊的副本,直至完成所有的更新。配置錯誤的副本替換了舊副本這樣會導致生產環境中服務無法正常訪問。
rollingupdatecheckv1.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 3000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
rollingupdatecheckv2.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep 3000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
資源管理
kubectl apply -f rollingupdatecheckv1.yml --record
等待幾分鐘,待資源創建成功後,我們執行更新
kubectl apply -f rollingupdatecheckv2.yml --record
我們查看資源會發現
kubectl get deployment app
DESIRED 期望狀態是10個READY的副本
CURRENT 表示當前的副本總數是13
UP-TO-DATE 已完成的更新數是5個
AVAILABLE 表示當前處於READY狀態的副本數是8個
為什麼會這樣呢?13個副本是怎麼產生的?為什麼更新了5個副本,舊副本還要8個?
滾動更新時 maxSurge和 maxUnavailable 負責副本數替換
maxSurge
控制副本數的上限
roundUp向上取整
目標副本是10的話,默認情況下,maxSurge=roundUp(10+10*25%)=13
maxUnavailable
控制不可用副本數的上限
roundDown向下取整
目標副本是10的話,默認情況下,10 - roundDown(10*25)=8
所以滾動升級的過程是
過程一: 創建三個新副本,副本總是達到13
過程二: 銷燬兩個舊副本,可用的舊副本剩下8
過程三: 創建兩個新副本,總副本數為13,舊副本為8,新副本為5
過程四: readiness 探測成功之後,繼續替換副本,失敗便停止
過程五: 重複上述過程,直至所有舊副本被新副本替換
我們測試過程中,v2版本readiness是無法監測通過的,所有副本數保持13個,5個新副本,8個可以使用的舊副本。8箇舊副本將繼續提供服務,確保生產環境的穩定。
閱讀更多 崔格拉斯 的文章