健康檢查
在前面講解容器的時候,講到了容器的自動重啟特性,K8S也提供了該特性,並做了加強。Pod使用健康檢查來保證容器的可用性,健康檢查可以保證Pod保持可用性,能使業務達到幾乎無間斷使用。下面我們通過實驗給大家展示該特性。
參考前面章節,創建兩節點K8S集群。1個作為控制節點,1個作為主節點。
Dockerfile配置如下:
FROM node:7ADD app.js /app.jsENTRYPOINT ["node", "app.js"]
app.js文件內容如下:
const http = require('http');const os = require('os');console.log("server starting...");var requestCount = 0;var handler = function(request, response) { console.log("Received request from " + request.connection.remoteAddress); requestCount++; if (requestCount > 3) { response.writeHead(500); response.end("I'm not well. Please restart me!"); return; } response.writeHead(200); response.end("You've hit " + os.hostname() + "\n");};var www = http.createServer(handler);www.listen(8080);
上面的程序當訪問超過3次時,報500錯誤。
構建鏡像,名字為health_image:latest,記得推送到自己的倉庫。
注意:由於現在是兩節點K8S集群,如果想要測試比較順暢,建議在兩個節點都構建鏡像。
配置Pod yaml文件,內容為:
apiVersion: v1kind: Podmetadata: name: health1spec: containers: - image: huqianakls/health_image:latest name: health1 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 protocol: TCP livenessProbe: httpGet: path: / port: 8080
配置說明:
livenessProbe下就是健康檢查配置,它也被叫做存儲探針。httpGet表示使用http的方式檢查容器是否健康,path是訪問路徑。從配置可以看出,健康檢查會訪問app.js文件中接口,該接口在訪問3次以後,會返回500錯誤,此時容器會處於不正常狀態。
運行該Pod,觀察健康檢查如何發生作用。
觀察步驟如下:
1、運行起來以後,等待容器狀態變為Runing;
2、等待一段時間後,使用kubectl describe 和 kubectl get pod命令查看Pod;
注意RESTARTS列,表示重啟次數,大概在1分鐘的時候,容器重啟了一次。
查詢詳情,結果如下:
[root@K8S001 test]success=1 success=1 kubectl describe pod health2Name: health2Namespace: defaultNode: k8s002/172.18.152.17Start Time: Wed, 25 Sep 2019 18:44:41 +0800Labels: <none>Annotations: <none>Status: RunningIP: 192.168.3.71Containers: health2: Container ID: docker://c6046bf54f46b7b1ac786b77afa17be4122594644ca1f7383e5ad8f1d25eb4ba Image: httpd Image ID: docker-pullable://httpd@sha256:39d7d9a3ab93c0ad68ee7ea237722ed1b0016ff6974d80581022a53ec1e58797 Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 25 Sep 2019 18:51:13 +0800 Last State: Terminated Reason: Completed Exit Code: 0 Started: Wed, 25 Sep 2019 18:50:33 +0800 Finished: Wed, 25 Sep 2019 18:51:13 +0800 Ready: True Restart Count: 5 Liveness: tcp-socket :8080 delay=15s timeout=1s period=20s failure=3 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-6fqw2 (ro)Conditions: Type Status Initialized True Ready True PodScheduled True Volumes: default-token-6fqw2: Type: Secret (a volume populated by a Secret) SecretName: default-token-6fqw2 Optional: falseQoS Class: BestEffortNode-Selectors: <none>Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300sEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 6m default-scheduler Successfully assigned health2 to k8s002 Normal SuccessfulMountVolume 6m kubelet, k8s002 MountVolume.SetUp succeeded for volume "default-token-6fqw2" Normal Pulling 6m kubelet, k8s002 pulling image "httpd" Normal Pulled 3m kubelet, k8s002 Successfully pulled image "httpd" Normal Created 1m (x4 over 3m) kubelet, k8s002 Created container Normal Started 1m (x4 over 3m) kubelet, k8s002 Started container Normal Killing 1m (x3 over 2m) kubelet, k8s002 Killing container with id docker://health2:Container failed liveness probe.. Container will be killed and recreated. Normal Pulled 1m (x3 over 2m) kubelet, k8s002 Container image "httpd" already present on machine Warning Unhealthy 44s (x9 over 3m) kubelet, k8s002 Liveness probe failed: dial tcp 192.168.3.71:8080: getsockopt: connection refused
從Event屬性可以看出,重啟原因是無法聯通8080埠。
Last State屬性內容為: Liveness: tcp-socket :8080 delay=15s timeout=1s period=20s failure=3
可以看出此時的健康檢查方式是tcp。
Kubelet是具體操控存活探針的系統組件,該組件在每個節點上都有,並且相互之間沒有直接聯繫。kubelet也會具體管理Pod的運行重啟等。每個節點管理的Pod是不同的。
下面們做個實驗,停止運行Pod的節點,看容器是否可以重啟。
上面我們的應用都被調度到k8s002工作節點,下面我們刪除該節點,大家可以在阿里雲上釋放該節點,之後,我們在在控制節點查看Pod,結果如下:
大家可以看到,health2重啟次數為7次,不管你隔多久時間查詢,你會發現這個次數不會變,仍舊是7,說明該Pod之後再也沒有重啟。原因是該Pod由k8s002節點上的Kubelet管理,現在該節點被刪除了,因此,不會再重啟該容器。
從這裡可以也可以看出,還需要更好的機制來解決這個問題,在節點出問題後,該節點上的容器能夠在其他節點運行起來。K8S提供了這種機制,即副本控制器。下節我們將進入該內容的學習。
1、創建Pod,使用存活探針;
2、觀察存活探針工作機制;