在Kubernetes
集羣當中,咱們能夠經過配置liveness probe
(存活探針)和readiness probe
(可讀性探針)來影響容器的生存週期。參考文檔:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/git
kubelet 經過使用 liveness probe 來肯定你的應用程序是否正在運行,通俗點將就是是否還活着。通常來講,若是你的程序一旦崩潰了, Kubernetes 就會馬上知道這個程序已經終止了,而後就會重啓這個程序。而咱們的 liveness probe 的目的就是來捕獲到當前應用程序尚未終止,尚未崩潰,若是出現了這些狀況,那麼就重啓處於該狀態下的容器,使應用程序在存在 bug 的狀況下依然可以繼續運行下去。 kubelet使用活躍度探頭知道何時從新啓動的容器。例如,liveness probe能夠捕獲死鎖,應用程序正在運行,但沒法取得進展。在這種狀態下從新啓動容器能夠繼續存活。
kubelet 使用 readiness probe 來肯定容器是否已經就緒能夠接收流量過來了。這個探針通俗點講就是說是否準備好了,如今能夠開始工做了。只有當 Pod 中的容器都處於就緒狀態的時候 kubelet 纔會認定該 Pod 處於就緒狀態,由於一個 Pod 下面可能會有多個容器。固然 Pod 若是處於非就緒狀態,那麼咱們就會將他從咱們的工做隊列(實際上就是咱們後面須要重點學習的 Service)中移除出來,這樣咱們的流量就不會被路由到這個 Pod 裏面來了。 使用readiness probe來了解容器什麼時候準備開始接受流量。當全部容器準備就緒時,Pod被認爲已準備就緒。此信號的一個用途是控制哪些Pod用做服務的後端。當Pod未就緒時,它將從服務負載平衡器中刪除。例如當一個應用服務有大文件加載時,這種狀況下不容許接受用戶訪問,readiness probe就不會對這類型的程序啓動服務。
許多運行很長時間的應用程序最終會轉換到損壞狀態,除非從新啓動,不然沒法恢復。Kubernetes提供活體探測器來檢測和糾正這種狀況。github
經過busybox來練習一下liveness probeshell
liveness-exec.yaml liveness-http.yaml pod-example.yaml poststart-hook.yaml prestop-hook.yaml apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-exec spec: 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: 5 periodSeconds: 5
在配置文件中,您能夠看到Pod具備單個Container。該periodSeconds
字段指定kubelet應每5秒執行一次活躍度探測。該initialDelaySeconds
字段告訴kubelet它應該在執行第一次探測以前等待5秒。要執行探測,kubelet將cat /tmp/healthy
在Container中執行命令。若是命令成功,則返回0,而且kubelet認爲Container是活動且健康的。若是該命令返回非零值,則kubelet會終止Container並從新啓動它。後端
當Container啓動時,它會執行如下命令:api
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
在Container的生命的前30秒,有一個/tmp/healthy
文件。所以,在前30秒內,該命令cat /tmp/healthy
返回成功代碼。30秒後,cat /tmp/healthy
返回失敗代碼。服務器
建立Pod:app
kubectl apply -f liveness-exec.yaml
在30秒內,查看Pod事件:tcp
kubectl describe pod liveness-exec
有消息指示活動探測失敗,而且容器已被殺死並從新建立。post
另外一種活動探測器使用HTTP GET請求學習
apiVersion: v1 kind: Pod metadata: name: liveness-http labels: app: liveness spec: containers: - name: liveness image: cnych/liveness args: - /server livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 3 periodSeconds: 3
在配置文件中,您能夠看到Pod具備單個Container。該periodSeconds
字段指定kubelet應每3秒執行一次活躍度探測。該initialDelaySeconds
字段告訴kubelet它應該在執行第一次探測以前等待3秒。爲了執行探測,kubelet向在Container中運行的服務器發送HTTP GET請求並偵聽端口8080.若是服務器/healthz
路徑的處理程序返回成功代碼,則kubelet認爲Container是活動且健康的。若是處理程序返回失敗代碼,則kubelet會終止Container並從新啓動它。
任何大於或等於200且小於400的代碼表示成功。任何其餘代碼表示失敗。
您能夠在server.go中查看服務器的源代碼 。
對於Container /healthz
處於活動狀態的前10秒,處理程序返回狀態200.以後,處理程序返回狀態500。
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { duration := time.Now().Sub(started) if duration.Seconds() > 10 { w.WriteHeader(500) w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds()))) } else { w.WriteHeader(200) w.Write([]byte("ok")) } })
在容器啓動3秒後,kubelet開始執行運行情況檢查。所以,前幾回健康檢查將成功。可是10秒後,運行情況檢查將失敗,而且kubelet將終止並從新啓動Container。
要嘗試HTTP活躍度檢查,請建立一個Pod:
kubectl apply -f liveness-http.yaml
10秒後,查看Pod事件以驗證活動探測失敗而且Container已從新啓動:
kubectl describe pod liveness-http
在v1.13以前的版本(包括v1.13)中,若是在運行pod的節點上設置了環境變量http_proxy(或HTTP_PROXY
),則HTTP活動探針將使用該代理。在v1.13以後的版本中,本地HTTP代理環境變量設置不會影響HTTP活動探測。
定義TCP活動探測
第三種類型的活動探測器使用TCP套接字。使用此配置,kubelet將嘗試在指定端口上打開容器的套接字。若是它能夠創建鏈接,則容器被認爲是健康的,若是它不能被認爲是失敗的話。
apiVersion: v1 kind: Pod metadata: name: goproxy labels: app: goproxy spec: containers: - name: goproxy image: cnych/goproxy ports: - containerPort: 8080 readinessProbe: tcpSocket: port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: tcpSocket: port: 8080 initialDelaySeconds: 15 periodSeconds: 20
咱們能夠看到,TCP 檢查的配置與 HTTP 檢查很是類似,只是將httpGet
替換成了tcpSocket
。 並且咱們同時使用了readiness probe
和liveness probe
兩種探針。 容器啓動後5秒後,kubelet
將發送第一個readiness probe
(可讀性探針)。 該探針會去鏈接容器的8080端,若是鏈接成功,則該 Pod 將被標記爲就緒狀態。而後Kubelet
將每隔10秒鐘執行一次該檢查。
除了readiness probe
以外,該配置還包括liveness probe
。 容器啓動15秒後,kubelet
將運行第一個 liveness probe
。 就像readiness probe
同樣,這將嘗試去鏈接到容器的8080端口。若是liveness probe
失敗,容器將從新啓動。
有的時候,應用程序可能暫時沒法對外提供服務,例如,應用程序可能須要在啓動期間加載大量數據或配置文件。 在這種狀況下,您不想殺死應用程序,也不想對外提供服務。 那麼這個時候咱們就可使用readiness probe
來檢測和減輕這些狀況。 Pod中的容器能夠報告本身尚未準備,不能處理Kubernetes服務發送過來的流量。
從上面的YAML
文件咱們能夠看出readiness probe
的配置跟liveness probe
很像,基本上一致的。惟一的不一樣是使用readinessProbe
而不是livenessProbe
。二者若是同時使用的話就能夠確保流量不會到達還未準備好的容器,準備好事後,若是應用程序出現了錯誤,則會從新啓動容器。
另外除了上面的initialDelaySeconds
和periodSeconds
屬性外,探針還能夠配置以下幾個參數:
[HTTP探針] 具備能夠設置的其餘字段httpGet
:
host
:要鏈接的主機名,默認爲pod IP。您可能但願在httpHeaders中設置「主機」。scheme
:用於鏈接主機的方案(HTTP或HTTPS)。默認爲HTTP。path
:HTTP服務器上的訪問路徑。httpHeaders
:要在請求中設置的自定義標頭。HTTP容許重複標頭。port
:容器上要訪問的端口的名稱或編號。數字必須在1到65535的範圍內。對於HTTP探測,kubelet將HTTP請求發送到指定的路徑和端口以執行檢查。kubelet將探測器發送到pod的IP地址,除非地址被可選host
字段覆蓋httpGet
。若是 scheme
字段設置爲HTTPS
,則kubelet會發送跳過證書驗證的HTTPS請求。在大多數狀況下,您不但願設置該host
字段。這是您設置它的一個場景。假設Container偵聽127.0.0.1而且Pod的hostNetwork
字段爲true。而後host
,在httpGet
,應設置爲127.0.0.1。若是您的pod依賴虛擬主機,這多是更常見的狀況,您不該該使用host
,而是設置Host
標頭httpHeaders
。
對於探測器,kubelet在節點處而不是在pod中進行探測鏈接,這意味着您沒法在host
參數中使用服務名稱,由於kubelet沒法解析它。