[Kubernetes] Kubernetes 基礎(二) Pod 操作
前言

延續上一篇[Kubernetes] Kubernetes 基礎(ㄧ) 架構及元件討論 Kubernetes 的架構與元件後,接著來探討如何操作 Kubernetes 的 Pod 元件吧!
以下簡稱 Kubernetes 為 K8s。
在正式操作前,先認識一下什麼是 kubectl
Kubectl
kubectl 是 Kubernetes 的命令列工具(Command Line tool),透過指令的方式來管理整個 Kubernetes Cluster,如:取得 Cluster 各種不同資源資訊, 配置運行資源等,使用 Kubectl 前要先了解幾個常用的參數:
- Namespace
- Completion
命名空間 (Namespace)
透過命名空間在 Cluster 內將不同資源(Container, storage, Network 等)區分開來
自動補全 (Completion)
Kubernetes 提供自動補全 bash 指令的功能,透過 Tab 鍵幫助我們在使用 Kubectl 指令時,快速地把指令補完,執行下述指令就能啟用這項功能
1 | |
讀取 Kubernetes 資源的相關指令 - Get
讀取某個 NameSpace 下的所有 Pods 資訊
1 | |
讀取某個 NameSpace 下特定的 Pods 資訊
1 | |
若想看更詳細的資訊(e.g. NODE, IP..),可以在指令後方加上參數
-o=wide
1 | |
也可改以 yaml 的形式描述 container ,參數改為 -o=yaml or JSON 形式: -o=json
Kubernetes 有提供 json path 做較為複雜的輸出方式,如
-0=jsonpath='...'
監聽 Pod - Watch
監聽 container 的變動,在部署的時候,可透過 watch 的方式去看某些 container 的變化是否如預期。
在指令裡加上參數 -w 即可
1 | |
讀取 Kubernetes 資源的相關指令 - Describe
用更上層的角度去看待資源,將多個事件、資源的資訊整合在一起,統一回傳給使用者,在 debug 時挺好用的指令
1 | |
Kubeconfig 的管理
Kubeconfig 包含各式各樣的資訊 e.g. Cluster(一個 or 多個), user,可藉由 kubectl 來幫助我們管理這些資訊,kubectl 是一支用來與 k8s 叢集溝通的二進位 (binary) 工具。
我們可以運用 kubectl 來,除此之外,Kubeconfig 有個重要概念: Context
Context
以怎樣的身份(user)、基於預設的 Namespaces 去存取特定的 Cluster資訊,是 Kubeconfig 的最小單元,故操作 Kubeconfig 時都是以 Context 作為最小原件去操作。
Kubeconfig 範例格式
主要分三大類別: Cluster, Context, User
1 | |
Kubeconfig 相關指令
部署 Service 到 K8s Cluster 時,可把相關部署資源等資訊先定義於 yaml 上,再透過 kubectl 的指令建立所需資源
對 Pod 操作 (Imperative Management; 命令式管理)
通過這種方法告訴Kubernetes API你要創建,替換或刪除的內容
建立&查看 Pod
要在 K8s 上部署一項資源到 Pod 上,可以對事先定義好的 yaml 檔案執行 kubectl 的指令,yaml 檔照下方範例,部署一個 Nginx 服務到 Pod 上:pod.yaml
1 | |
搭配 kubectl create 指令加上參數 -f,後面接定義好的檔案部署資源:
1 | |
如果要查看 Pod 狀態,可以下 get pod 指令,後面接剛剛件好的 Pod 名稱
1 | |
output
1 | |
想看更細部的資訊(name space, Node, Label, Containers等等)可以用 describe pod 的指令
1 | |
刪除 Pod
若不需要這個 Pod 了,要將其移除可下 delete pod,或是 delete -f 接定義好的 yaml 檔
1 | |
編輯 Pod
透過 edit pod 針對當前運作中的資源進行更新/替換,不需重新部署
1 | |
雖然上面定義好的 pod.yaml 很簡短,但實際部署到系統時, K8s 的 API Server 會自動補上其他資訊,大部分都是系統預設值 e.g. DNS 設定、重啟政策
對 Pod 操作 (Declarative Management; 聲明式管理)
根據配置文件裡面列出的内容進行資源部署、修改及刪除等操作,讓 K8s 幫你維護資源狀態,概念比較偏向是告訴 Kubernetes 希望擁有的資源及狀態,確認資源應該要長什麼樣子,相較於 create 單純是創造的概念。 故根據資源狀態產生兩個對應的動詞: apply, diff
kubectl apply
語法
1 | |
or
1 | |
透過 apply 指令根據已經定義好的一個 or 多個 yaml 檔,也可針對資料夾用遞迴的方式,把資料夾內的所有 yaml 檔送到 Kubernetes 裡面,告訴 Kubernetes 確保 yaml 描述的狀態與 Kubernetes 裡面完全一致。
kubectl diff
diff 指令是在 apply 檔案時,跟目前 Kubernetes 檔案描述的狀態有哪些差異,修改哪些地方?有哪些變化?
Work Flow
接著看張圖理解 apply 的流程:
圖片上半部分:
左邊的 Config yaml 為定義 K8s 資源的 yaml 檔,描述 A ~ E 等多項資源,接著透過 apply 指令寫到 K8s 裡,K8s 會根據 yaml 檔描述的內容及預設值建立對應的資源,其中某個欄位會用於**記錄原始的檔案內容(用紅色的F標示)**,剩餘的部分(如 G ~ K)則是 K8s 根據本身的預設值自動建立資源。
圖片下半部分:
若對原始定義的 Config yaml 內容作修改(如圖中橘色的 B ~ C),經第二次 apply 後,K8s 會根據紀錄在F欄位的物件,將修改後的物件與原始存在K8s裡的物件進行比對。
如此一來,使用這變得方便許多,不需要取得完整的 yaml 檔內容(包含K8s 預設自動建立好的資源),即可針對變動的檔案內容更新 K8s 裡的資源,實務上都採此法更新 K8s 資源,故 apply 與 create 的含意不同。
kubectl create表創造資源,而kubectl apply則是維護資源狀態,希望狀態是一致的。
範例
將前面 create 的 Nginx 範例改用 apply 來執行
1 | |
output
1 | |
把 image 改為 httpd ,將部署的服務改為 Apache Server
1 | |
在 apply 之前,可以先透過 diff 指令來觀察資源變化
1 | |
或是透過 get 指令加上參數 -o yaml 以 yaml 形式列出檔案內容
1 | |
觀察一下 metadata 裡的 annotations 區塊,可發現有個欄位名稱: kubectl.kubernetes.io/last-applied-configuration,此欄位用於記錄先前的使用檔案內容
1 | |
重新 apply 一次
1 | |
output
1 | |
接著用 get 再次檢查annotations 區塊的 kubectl.kubernetes.io/last-applied-configuration 欄位:
1 | |
確認 image 資訊從 nginx 更新為 httpd。
當然也可以透過 describe 的方式來查看該 Pod 當前運行的 image 是哪個
1 | |
經過上述幾個範例實作後,大部分的情況下都會藉由 apply 的方式來維護描述 K8s 資源的檔案。另外列出使用聲明式管理的優劣
優:
- 直接對物件作修改,易於管理資源變化(可搭配 git 做版控)
- 支援整個資料夾
劣:
在開發環境較為缺乏彈性(並非所有環境都能拿到最初的 yaml 檔案做 apply)
總結聲明式管理
透過檔案的方式維護資源(下載、更新資源),有效搭配版控追蹤每次修改的紀錄,能更有系統地除錯、追蹤及部署。
Pod Controller (Workload Controller)
Pod 底下擁有多種類型的 Controller,每種 Controller 都有合適的應用場景:
- ReplicaSet: 管理多個 Pod 的副本
- Deployment: 提供聲明式的方法來更新 Pods
- Daemonset: 確保每一個 node 上都會有一個指定的 Pod 來運行特定的工作
- StatefulSet: 處理有狀態 Container
- Job: 在特定時間完成批次工作
- CronJob: 定期排程工作
之後會針對 Pod 底下不同的 Controller 分篇做紀錄,本篇只有先單純列出 Pod 底下不同類型的 Controller
總結
本篇記錄如何透過 Kubectl 來對 Pod 元件進行常見的操作,並比較 命令式管理與聲明式管理 兩者的差異,最後透過幾個範例實際演練,下一篇會針對 Pod 底下的 Controller - ReplicaSet 做討論。