iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
Kubernetes

Kubernetes學習心得分享系列 第 4

Day 04:【核心】最小部署單位:Pod 的概念與 YAML 撰寫基礎

  • 分享至 

  • xImage
  •  

前言

寫這篇想要分享的重點:
深入理解 Kubernetes 為什麼不直接拿 Container 作為最小調度單位,並掌握 Pod 的底層資源共享機制、生命週期狀態(Status),以及如何透過指令快速生成結構正確的 YAML 設定檔。

這篇想要講什麼:

  1. 為什麼是 Pod 而非 Container?(共享 Network Namespace 與 Volume 機制)。
  2. Pod 的生命週期與常見狀態解讀(Pending, Running, CrashLoopBackOff)。
  3. Pod YAML 基礎四大區塊與 Imperative 快捷指令生成技巧。

為何要寫這篇:
前三天我們搞懂了 Control Plane、Worker Node 架構以及底層 Container Runtime 的演進。今天我們介紹 K8s 最重要的工作組件——Pod,這是每一位 DevOps 與雲端工程師一定都要碰到的組件。


名詞對應

Namespace (Linux): 命名空間 / 隔離空間
Network Namespace: 網路命名空間
Sidecar Pattern: Sidecar 模式 / 邊車模式
Declarative / Imperative: 宣告式(聲明式) / 命令式(指令式)
pull: 拉取


1. 為什麼不是直接運行 Container?

許多初學者剛接觸 K8s 時最常問:「既然 Docker 已經有 Container 了,為什麼 K8s 還要多包一層 Pod?」

答案在於:現實中的應用程式往往需要『緊密耦合(Tightly Coupled)』的彈性互動運作。

+-----------------------------------------------------------------------+
|  POD (獨立運作的專案小組 / 獨立工作桌)                                     |
|                                                                       |
|   - 共享 IP 位址 (例如: 10.244.1.15)                                    |
|   - 共享 Loopback (localhost 互相通訊)                                  |
|   - 共享 Volume (公用硬碟 / 資料共用區)                                   |
|                                                                       |
|   +--------------------------+      +-----------------------------+   |
|   | Main Container           |      | Sidecar Container           |   |
|   | (主要工程師: Nginx Web)   |      | (助理工程師: Log Collector)   |   |
|   | 負責主要業務邏輯 (Port 80) |      | 負責收集與搬運 Log             |   |
|   +--------------------------+      +-----------------------------+   |
|                                                                       |
+-----------------------------------------------------------------------+

💡 一個Pod裡面可以跑多個Containers!

Pod 的底層實現:共享資源的關鍵

如果把容器想像成「單一員工」,那 Pod 就是「為了同一個目標組成的專案小組」。K8s 永遠是把整個專案小組(Pod)一起打包放到同一台機器上。

  1. 共用網路(Network Namespace)

    • 同一個 Pod 內的所有容器共享同一個 IP 位址。
    • 就像兩位工程師面對面坐在同一張工作桌,可以用 localhost:Port 隨時對話(例如 Main App 跑在 localhost:8080,Log Agent 直接連 localhost:8080 抓資料),不需要經過外網轉發。
  2. 共用儲存(Volume)

    • 只要在 Pod 層級設定了 Volume,就像在工作桌中間放了一個「公用硬碟」,小組裡的成員(Container)都能直接讀寫同一個目錄。

智慧工廠比喻:

如果 Container 是廠房裡的單一機件,Pod 就是一組完整整合好的標準生產機台。廠長(kubelet)在派工時,永遠是把整個機台一起搬到合適的工作間(Worker Node)。主機件(Main Container)與附帶的監測感測器(Sidecar Container)共用同一個電源插座(共享 IP/Port)與內部運料管道(共享 Volume),確保機件之間合作無間。


2. Pod 的生命週期與常見 Status(除錯必備)

當你透過 K8s 跑起來 Pod 時,Pod 會經歷一系列的生命週期狀態(Phase)。學會看懂 kubectl get pods 輸出的 Status 是現場除錯的第一步:

+-----------+      綁定 Node      +-----------+     拉取 Image      +-----------+
|  Pending  | -----------------> | Container | -----------------> |  Running  |
| (等待排程) |                    | Creating  |                    | (正常運作) |
+-----------+                    +-----------+                    +-----------+
      |                                                                    |
      | 資源不足 / Taints 阻擋                                               | 應用程式 Crash
      v                                                                    v
+-----------+                                                       +--------------------+
| Failed /  |                                                       | CrashLoopBackOff   |
|  Unknown  |                                                       | (重複掛掉與重啟)     |
+-----------+                                                       +--------------------+

關鍵狀態說明

  • Pending:API Server 已接收到請求並寫入 etcd,但 kube-scheduler 還沒找到合適的 Node 指派給它,或是 kubelet 正準備開始拉取 Image。

    • 常見原因:Cluster 資源(CPU/Memory)不足、沒有符合 NodeSelector/Affinity 的Node、Node 被加上了 Taint(污點),但 Pod 沒有設定對應的 Toleration(容忍)。
  • ContainerCreating:Node 已選定,kubelet 正透過 CRI 指揮 containerd 拉取 Image、建立網路與設定掛載。

  • Running:Pod 已經成功綁定到 Node 上了,且裡面的 Container 都已被成功建立並至少有一個正在運行中。

  • CrashLoopBackOff最常見的異常狀態,容器啟動後因為某些原因不斷崩潰(Crash)退出,K8s 觸發重啟機制後再次掛掉,導致重啟間隔時間被不斷拉長(Back-off)。

    • 常見原因:程式碼有 Bug 拋出 Exception、環境變數帶錯、DB 連線失敗、記憶體 OOM(Out Of Memory)。

3. Pod YAML 四大區塊

在 K8s 中,我們習慣用 YAML 檔案 來宣告預期狀態(Desired State)。不管是任何 K8s 物件,YAML 一定包含以下四大結構

apiVersion: v1             # 1. API 版本(這個物件屬於哪個 API 群組)
kind: Pod                  # 2. 物件類型(Pod, Service, Deployment...)
metadata:                  # 3. metadata(大家都只用英文講他), (囊括: 名稱、標籤 Namespace、Label)
  name: my-web-pod
  labels:
    app: web
spec:                      # 4. 規格細節(最多設定都放這邊)
  containers:
    - name: nginx-container
      image: nginx:1.25
      ports:
        - containerPort: 80

四大區塊詳細說明

  1. apiVersion:指定這個物件在 K8s API 中的版本(例如 Pod 是 v1,Deployment 是 apps/v1)。
  2. kind:告訴 K8s 你現在要建立的是什麼種類的物件。
  3. metadata:用來識別該物件的資料,包含 name(名稱)、namespace(所屬命名空間)與 labels(用來做篩選的比對標籤)。
  4. spec最重要的一區! 宣告這個物件的「預期狀態」,如要跑什麼 Image、開什麼 Port、環境變數與資源限制(Limits/Requests)。

實用技巧:使用 Imperative 指令快速生成 YAML 範本

在日常維運,手敲 YAML 容易出錯(特別是 YAML 嚴格要求的縮排)。常用以下指令快速產生 YAML 範本:

# 產生一個名為 nginx-pod 的 Pod YAML 檔(--dry-run=client: 不實際建立物件)
kubectl run nginx-pod --image=nginx:1.25 --dry-run=client -o yaml > pod.yaml
  • --dry-run=client:告訴 API Server 只在 Client 端測試驗證,不要真正發送到叢集建立
  • -o yaml:將預計產生的物件以標準 YAML 格式輸出到 Terminal,配合 > 即可直接存成yaml檔案。

output:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx-pod
  name: nginx-pod
spec:
  containers:
  - image: nginx:1.25
    name: nginx-pod
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

這樣就可以快速生成一個yaml範本然後再修改裡面內容就好了


結語

  • 本篇總結:
    Pod 是 K8s 最小的作業組件,透過讓容器共用 Network Namespace 與 Volume,解決了多容器緊密耦合的情境;學會解讀 Pod 生命週期狀態(如 PendingCrashLoopBackOff),並熟練四大 YAML 架構與快捷指令生成,是進入 K8s 實務開發的基石。

  • 下一篇預告:
    掌握了基礎 Pod 部署與 YAML 撰寫後,明天 Day 05 我們將深入剖析 【指令】聲明式 vs 命令式:Imperative vs Declarative 操作哲學!重點比較 kubectl run/createkubectl apply 的差異、Three-way Merge 合併機制,以及如何善用 kubectl explain 技巧

Takeaway

  • Pod 的本質:容器的載體,內部容器共用 IP、Port 與 Volume,適合 Sidecar 輔助模式。
  • 常見 StatusPending(排程排不下去/資源不夠)、Running(正常運作)、CrashLoopBackOff(程式出錯或環境變數設定錯誤導致重啟循環)。
  • YAML四大結構apiVersion(API 版本)、kind(物件種類)、metadata(名稱與 Label)、spec(核心規格宣告)。
  • 好用招式:使用 kubectl run ... --dry-run=client -o yaml 快速長出標準 YAML 範本,省去手打縮排的時間。

上一篇
Day 03:【底層】Container Runtime 的演進:Docker vs. containerd
下一篇
Day 05:【指令】聲明式 vs 命令式:Imperative vs Declarative 操作
系列文
Kubernetes學習心得分享6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言