1. 程式人生 > 其它 >Kubernetes中Pod生命週期

Kubernetes中Pod生命週期

KubernetesPod是容器管理的最小單位, 有著各種各樣的Pod管理器. 那麼一個Pod從啟動到釋放, 在這期間經歷了哪些過程呢?

Pod自開始建立, 到正常執行, 再到釋放, 其時間跨度及經歷的階段大致如下:

說一下各個階段的作用以及是為了解決什麼問題. 容器排程和下載映象的過程就忽略了, 也沒什麼好說的.

init

Pod啟動一個容器時, 可以有一組init容器先行啟動(當然也可以沒有), 這些init容器會依次執行, 且前一個成功之後, 後一個才會執行. 同時還會監控init容器的退出狀態, 若init容器異常退出, 則會根據配置restartPolicy的重啟策略選擇重新啟動或退出(這裡的退出, 說明Pod

啟動失敗了). 通過配置檔案的pod.spec.initContainers進行配置, 其配置項與containers相同

init容器可應用與如下場景:

  • 可以將服務的建立和部署進行解耦. 以防止主容器過於臃腫
  • 檢測依賴. 比如服務 A 必須要等服務 B 啟動成功之後才能執行, 那麼就可以在服務 A 的 init 階段進行迴圈檢測等待, 直到服務 B 啟動成功了, 才開始啟動服務 A
  • 具有訪問Secret的許可權. Secret是用來儲存一些敏感資料的, 會進行加密處理. 主容器是沒有許可權訪問的, 這也很好理解, 如果一個容器被攻破了, 如果能夠拿到Secret的資料, 很可能會導致一串服務都被攻破. 而init
    容器在Pod提供服務之前就退出了, 可以提高資料的安全.
  • 等等

Podinit容器啟動完成之前, 是不會對外提供服務的, 其狀態一直為Pending

start/stop

容器啟動和釋放時執行的鉤子. 通過配置檔案的pod.spec.containers.lifecycle.postStartpod.spec.containers.lifecycle.preStop進行配置. 配置相同, 這裡用postStart舉例了. 具體配置可通過kubectl explain pod.spec.containers.lifecycle.postStart檢視, 官方文件很詳細.

# 執行一組命令
postStart: 
  command: ["/bin/sh", "-c", "sleep 1"]
---
# 呼叫 http 介面通知
postStart: 
  host: baidu.com
  path: /start
  port: 80

readiness

既就緒探針. 檢測容器中的服務是否已經啟動成功並可以對外提供訪問了. 只有檢測成功後, 才會將狀態改為就緒狀態(Running). 定義在配置檔案的pod.spec.containers.readinessProbe位置. 預設success

readiness是為了解決服務的啟動時間問題, 比如容器已經啟動成功了, 但是提供服務的程序還沒有啟動完畢, 此時對外提供服務的話就會有問題. Kubernetes提供瞭如下三種探針:

  • ExecAction: 在容器中執行指定命令. 若命令返回0, 則成功
  • TCPSocketAction: 對指定埠進行 TCP 檢查, 若埠開放, 則認為成功
  • HTTPGetAction: 對指定埠進行 HTTP Get 請求, 若響應碼區間為[200, 400), 則認為成功

其配置檔案大致如下:

# 命令探針
readinessProbe: 
  exec: 
    command: ["cat", "/tmp/file"]
  # 以下這些欄位為通用欄位, 下面不再重複
  
  # 探針失敗的最大重試次數, 超過這個次數則認為本次探測失敗, 容器啟動失敗. 預設3
  failureThreshold: 3
  # 探測的迴圈週期, n秒後進行下一次探測. 與 failureThreshold 配合確定啟動時間. 預設10s
  periodSeconds: 1
  # 執行第一次探測前需要等待5s. 預設0s
  initialDelaySeconds: 5
  # 探測超時時間. 預設1s
  timeoutSeconds: 1
  # 當探測失敗後, 需要連續探測成功3次才認為成功. 預設1
  successThreshold: 3
  # 當探測失敗後, 優雅釋放可等待的時間. 超過則會被強制釋放
  terminationGracePeriodSeconds: 5
---
# tcp 探針
readinessProbe: 
  tcpSocket: 
    host: baidu.com
    port: 80
---
# http 探針
readinessProbe: 
  httpGet: 
    host: baidu.com
    path: /
    port: 80
    # 設定請求的 header, 是個物件陣列
    httpHeaders: 
      - name: headerName
        value: headerValue
    # 請求方式. HTTP 或 HTTPS. 預設 HTTP
    scheme: HTTP

liveness

既存活探測, 在容器執行的這段時間, 探測容器是否存活, 若已經無法提供服務, 則需要重啟容器. 定義在配置檔案的pod.spec.containers.livenessProbe位置. 其配置項與readiness相同, 不再贅述. 預設success

在容器執行過程中, 可能容器還活著, 但裡面提供服務的程序已經死了(例如死鎖). 這時容器其實已經無法對外提供服務了. 需要這樣一種機制來檢測是否還能正常提供服務.

注意, liveness並不是在readiness探測完畢後才會啟動.而是幾乎同時啟動, 而liveness探測失敗後, 會導致容器重啟, 因此livenessinitialDelaySeconds配置就需要稍微花點心思了, 要延時一些時間, 等待服務啟動成功後再開始. 否則可能導致readiness還沒有完成探測任務, 就被liveness探測失敗而重啟了.

startup

上面說livenessreadiness是同時執行的, 通過配置livenessinitialDelaySeconds引數來等待. 但對於一些服務, 我們並不能確定其啟動需要多久呀, 如果一味延長等待時間就太不划算了.

startup就是為了解決livenessreadiness執行順序的問題, 將服務就緒探測和服務的存活探測徹底分開. 定義在配置檔案的pod.spec.containers.startupProbe位置, 探針項與readiness相同.

startup探針會在探測成功後, 再將探測任務交由後續的探測任務. 預設success

所以一般使用livenessstartup配合探測即可, readiness貌似沒有什麼用武之地了.

原文連結: https://hujingnb.com/archives/707