希望部屬能夠自動保持運行,並且保持健康,無須任何手動干涉。要做到這點,你幾乎不會直接建立pod,而是建立ReplicationController或Deployment這樣的資源,由他們來建立並管理實際的pod。

保持pod健康

只要pod調度到某個節點,該節點上的kubelet就會運行pod的容器,從此只要該pod存在,就會保持運行。如果容器的主程序崩壞,kubelet將重啟容器。 如果應用程式中有一個導致它每隔一段時間就會崩潰的bug,k8s會自動啟動應用程式,所以即使應用程式本身沒有做任何特殊的事,在k8s中運行也能自動獲得自我修復的能力。

即使程序沒有崩潰,有時應用程式也會停止正常工作。例如:發生記憶體流失的Java應用程式將開始拋出OutOfMemoryErrors,但JVM程序會持續運行。如果有一種方法,能讓應用程式向k8s發出訊號,告訴k8s它執行異常並讓k8s重新啟動。

一個崩潰的容器會自動重啟,也許你會想到,可以在應用程式中捕捉這些錯誤,並且在錯誤發生時退出該程序。當然可以這樣做,但這樣不能解決所有問題。

例如:你的應用程式因為無限迴圈的錯誤或死鎖而停止回應。為確保應用程式在這類情況下可以重新啟動,必須從外部檢查應用程式的運行狀況,而不是依賴於應用程式的內部檢測。

介紹存活探針(liveness probes)

k8s可以透過存活探針(liveness probe)檢查容器是否還在運行。可以為pod中的每個容器單獨指定存活探針。k8s將定期執行探針,如果探測失敗將重新起動容器。

k8s有以下三種探測容器的機制:

1. 建立一個有存活探針的pod

為了要測試的存活探針功能,我們需要一個經過一段時間就發生異常的服務,因此需要改造之前的程式碼,打包後推送到dockerhub(方法可以參考 02-心得 Docker ),程式內容如下: 以下程式碼,代表意思是在第五次請求之後,服務將開始回應500 error錯誤網頁。

const http = require('http');
const os = require('os');

console.log("Kubia server starting...");

var requestCount = 0;

var handler = function(request, response) {
  console.log("Received request from " + request.connection.remoteAddress);
  requestCount++;
  if (requestCount > 5) {
    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);

建立 kubia-liveness-probe.yaml

建立一個存活探針的pod,定期在port 8080的路徑 / 上執行HTTP GET請求,以確保容器是否健康,這些請求會在容器運行後立即開始。

apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
  - name: kubia
    image: luksa/kubia-unhealthy        # 這個容器映像檔案 會讓服務異常
    # 以下為 HTTP GET存活探針的設定
    livenessProbe:
      httpGet:
        path: /
        port: 8080

2. 建立一個有 存活探針 的pod (這個pod過段時間會自動回應http 500錯誤)

[root@cp200 ch4]# kubectl create -f kubia-liveness-probe.yaml
pod/kubia-liveness created