iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0

今天來介紹 Pod 相關的屬性及設置:

  • Commands and Arguments
  • Pod Lifecycle
  • Probes

Commands and Arguments

我們可以定義運行 Containers 時要跑的 Commands & Arguments,與 docker Dockerfile 中的 ENTRYPOINT & CMD 對應。

Dockerfile

FROM Ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]

Kubernetes configuration file


apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
	restartPolicy: Never
  containers:
  - name: busybox
    image: busybox
    command: ["sh", "-c"]
    args: ["echo $(date); sleep 1; echo 'Hello'; echo $(date)"]

這邊要注意 Dockerfile 中 CMD 在 kubernetes yaml 中的參數是 args。ENTRYPOINT 對應的是會執行的 command。

建立 pod 後利用 kubectl logs 查看 log,可以看到印出了時間1、Hello、時間2。

https://ithelp.ithome.com.tw/upload/images/20230920/20162795t5pokegJg9.png

因為用 busybox 這個 image 跑的 Container 執行完這些指令後就沒事做了,類似於 docker,如果主要 process 執行結束就會 Exit。因 kubernetes 預設 restartPolicy 是 Alwasys,如果 container exit,kubelet 會嘗試一直重啟這個 container,我這邊更動 restartPolicy 變成 Never,如果 exit 就 exit 了。

再利用 kubectl describe 查看 pod status & event -

https://ithelp.ithome.com.tw/upload/images/20230920/2016279553ARROjyG3.png

https://ithelp.ithome.com.tw/upload/images/20230920/20162795ddQiru6hlK.png

可以看到我們定義的 Command & Args,還有底下的 Events,有時如果 Pod 無法運行成功也可以透過 kubectl describe -n <namespace name> <type> <object name> 查看有沒有什麼錯誤訊息。

Lifecycle

從前面的圖可以看到列出 pods 也會一併列出 Pod Status -
https://ithelp.ithome.com.tw/upload/images/20230920/20162795SfxgMoW44N.png

kubectl describe 的 output 中也有列 Container State -
https://ithelp.ithome.com.tw/upload/images/20230920/20162795Whk6WZRQkQ.png

Pod 中跑著一個或多個 Container,這裡面就是要提供服務的應用,在管理上掌握 Pod 的生命週期、確認它是否健康、不健康要重啟就是很重要的事啦。接下來來看看 Pod 狀態、Container 狀態在 kubernetes 中是怎麼樣。

Pod Phases

Pod 的生命週期分成 Pending、Running、Succeeded/Failed、Unknown 這幾種 Phase。可以從 kubectl describe output 中觀察。

https://ithelp.ithome.com.tw/upload/images/20230920/20162795sC83TmKwc2.png

Source: https://bobcares.com/blog/kubernetes-pod-states/

使用 kubectl get pods 指令時,可以看到 Pod 在哪個階段。例如 Pod 還沒被分配到 Node 上會是 Pending、運行中會是 Running 。不過如果是錯誤的情況會顯示錯誤的原因,如果是完成階段性任務且 Container 終止,則會顯示 Completed。

Container States

Kubernetes 也會追蹤 Container 的狀態,Container states 有 Waiting、Running、Terminated 三種。

如果 State 是 Running,表示 Container 正在運行中;Terminated 則是這個容器已經終止,有可能是已經完成工作或是因為某些原因失敗;Waiting 則是當 Container 不是前述兩個狀態時,就會是 Waiting。

Container State 一樣可以從kubectl describe output 中觀察,包含為什麼會在這個 State 的原因。

Restart Policy

上一段也有提到 Pod spec 中我們有定義 restartPolicy ,可能的值有 AlwaysOnFailureNever 。這個重啟策略是適用於 Pod 中所有容器,會由 kubelet 重新啟動容器,重新啟動的間隔會越來越長,如 10s, 20s, 40s, … 最長等待的時間不會超過 5 分鐘。如果容器運行 10 分鐘都沒問題,kubelet 會重設這個容器的重啟時間的 timer。

Note: restartPolicy 是定義在 Pod level,但重啟的對象是 Container

Pod Conditions

kubectl describe output 中的 Conditions 區塊包含了下面四種類型:
https://ithelp.ithome.com.tw/upload/images/20230920/20162795axe8rsJHbN.png

  • Initialized: 所有 init containers 都成功啟動
  • Ready: Pod 可以接受 requests 了
  • ContainersReady: Pod 中的所有 Containers 都 Ready
  • PodScheduled: Pod 被安排到 Node 上

以剛才跑的 pod 為例,因為沒有 init container,所以 Initialized 這部份算是完成;PodScheduled 也完成,Pod 已經被分配到某一個 node 上;但因 Container 已經終止,所以 ContainersReady & Ready 這兩項都會是 False。

Probes

Probes 是 kubelet 檢查 Container 狀態的一個設計。為什麼會需要 Probes 呢?有些場景是 Web server 需要較長的暖機時間,雖然 Web UI 已經出現但可能還需要再幾秒 server 才能開始回應請求。但如果 Pod 被視為 Ready 的時候,就會被視為可接受請求。另外也有可能應用程式雖然在運行,但不一定能夠成功回應,這時會需要重新啟動。我們該怎麼偵測這種狀態以及讓 Pod 自動重啟?Kubernetes 有幾種 Probe 來監測 Pod 的健康程度:readinessProbe、livenessProbe、startupProbe。

先來看個 redis 的例子

apiVersion: v1
kind: Pod
metadata:
  name: redis-server
spec:
  containers:
    - name: redis
      image: redis:latest
      ports:
        - containerPort: 6379
      livenessProbe:
        tcpSocket:
          port: 6379
        initialDelaySeconds: 10
        periodSeconds: 5
        timeoutSeconds: 10
      readinessProbe:
        exec:
          command:
            - "redis-cli"
            - "ping"
        initialDelaySeconds: 10
        periodSeconds: 3
        timeoutSeconds: 5

使用 Probe 來檢查 Container 狀態有四種方法 -

  • exec - 在容器內執行指令
  • grpc
  • httpGet
  • tcpSocket

上面的例子 livenessProbe 是使用 tcpSocket 的方法來判斷 redis 這個 container 是否還活著,kubelet 能跟這個容器建立 TCP 連線則算成功。readinessProbe 則是利用 redis-cli 對 redis 發出 ping 這個請求,用這個方式來判斷 redis 是否能接收請求。

在 Probe 的配置上有不同的選項可以控制探測的頻率、怎樣算是成功等等。比較常用的有:

  • initialDelaySeconds: 等 container 啟動之後等待多久進行第一次檢查。而順序上 startup probe 會先於 liveness & readiness probe,因此 liveness & readiness probe 的 initial delay 會等到 startup probe 成功後才開始計算。
  • periodSeconds: 檢查的間隔,預設是 10 秒,最小可設為 1 秒。
  • timeoutSeconds: 多久才算是 timeout,預設 1 秒,最小可設為 1 秒。
  • successThreshold: Probe 檢查失敗後,被認為成功的最小連續請求成功次數。預設 1,對 liveness & startup probes 來說必須為 1 。
  • failureThreshold: 幾次失敗才將這個 container 視為還沒準備好接受請求/不健康。

readinessProbe

readinessProbe 從名稱可以猜到,這是來判斷 Pod 是否能被視為 Ready (能對請求做出回應) 的 Probe。如果 readinessProbe 的結果是成功的,則這個 Pod 就能接受請求。

livenessProbe

判斷 Container 是否正常運行,如果檢查失敗就視為不健康。會根據 Pod 設置的 restartPolicy 決定這個 Container 是否要重新啟動。

Readiness Probe & Liveness Probe 並沒有先後順序的關係,Liveness Probe 檢查成功不代表 Readiness Probe 成功。如果希望控制某些檢查的順序,可利用 initialDelaySeconds & Startup Probe。

startupProbe

判斷 Container 中的應用程式是否已經啟動。Startup Probe 如果成功後其他 Probes 才會開始作用。如果 Startup Probe 失敗,kubelet 會殺掉這個容器然後根據 restartPolicy 重啟。

Example - Liveness Probe HTTP request

這邊跟著官網來觀察下 http request 怎麼寫,還有 liveness probe 檢查失敗的話會怎麼樣。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

這邊利用 httpGet 來檢查,如果 HTTP 回應的 status code ≥ 200 並且 < 400 則視為成功。這個 image 的 source code 會讓 Container 啟動前 10 秒回應 200,但之後會回應 500。

利用 kubectl describe 可以看到 Event section 有成功紀錄、失敗重啟紀錄。

前十秒內沒有問題。
https://ithelp.ithome.com.tw/upload/images/20230920/20162795HAJ7BnZGVF.png

超過十秒,偵測到 Unhealthy,殺掉 Container 再重啟。
https://ithelp.ithome.com.tw/upload/images/20230920/20162795CLLBEOey2W.png

也可以透過 kubectl get pod -w 觀察 Pod 狀態的改變。-w 是 watch for changes 的意思。可以用這個指令觀察 k8s object 的變化。可以看到 Pod 每隔一段時間就會重啟,這邊 restartPolicy 是 Always,但重啟的間隔會越來越長。
https://ithelp.ithome.com.tw/upload/images/20230920/2016279561ScTCiNLY.png

實際使用上 Probes 該怎麼設呢?像 Redis、MySQL 這種應用在網路上應該都能找到合適的 check mechnism 做設置。如果是網頁的話可能就要看使用場景或商業邏輯去設 HTTP Get path。檢查的間隔及秒數在 https://blog.pichuang.com.tw/20230529-kubernetes-probe.html 有看到一些建議。

Reference
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
https://www.baeldung.com/linux/kubernetes-livenessprobe-readinessprobe


上一篇
Day 5 利用 Deployment 及 Service 部署服務 - 2
下一篇
Day 7 Resource
系列文
可能會迷路的航行 - 菜雞的kubernetes學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言