Kubernetes 系列(二):基礎篇 - Pod、Deployment 與 Service
前言
在上一篇文章中,我們認識了 Kubernetes 的核心架構與基本概念。本篇將深入探討 K8s 中最重要的三個資源類型:Pod、Deployment 與 Service。
這三個概念構成了 K8s 應用部署的基礎:
- Pod:容器運行的最小單位
- Deployment:管理 Pod 的部署與更新
- Service:為 Pod 提供穩定的存取端點
掌握這三個概念,你就能開始在 K8s 上部署和管理應用程式了。
Pod:最小部署單位
什麼是 Pod?
Pod 是 K8s 中最小的可部署單位,也是最基本的調度單位。一個 Pod 代表叢集中運行的一個進程。
graph TB
subgraph "Pod"
C1[Container 1<br/>Web Server]
C2[Container 2<br/>Sidecar]
V[Shared Volume]
N[Shared Network<br/>localhost]
end
C1 <--> N
C2 <--> N
C1 --> V
C2 --> V
Pod 的核心特性
| 特性 | 說明 |
|---|---|
| 共享網路 | 同一 Pod 內的容器共享 IP 地址和端口空間 |
| 共享儲存 | 可定義共享的 Volume,容器之間共享資料 |
| 共同調度 | 同一 Pod 的容器永遠在同一節點上運行 |
| 生命週期 | Pod 是臨時的(Ephemeral),不會被「修復」,只會被替換 |
為什麼不直接運行容器?
你可能會問:「為什麼不直接管理容器,而要多一層 Pod?」
原因在於 Pod 提供了容器之間協作的抽象:
graph LR
subgraph "傳統方式"
A[Container A] -.->|需要配置網路| B[Container B]
end
subgraph "Pod 方式"
C[Container A] <-->|localhost| D[Container B]
end
常見的多容器 Pod 模式:
Sidecar 模式
- 日誌收集器(Fluentd、Filebeat)
- 代理服務(Envoy、Istio Proxy)
Ambassador 模式
- 代理外部服務存取(資料庫 Proxy)
Adapter 模式
- 標準化輸出格式(Metrics Adapter)
Pod YAML 詳解
1 | apiVersion: v1 # API 版本 |
Pod 生命週期
stateDiagram-v2
[*] --> Pending: 創建 Pod
Pending --> Running: 調度成功且容器啟動
Pending --> Failed: 調度失敗
Running --> Succeeded: 所有容器正常終止
Running --> Failed: 容器異常終止
Running --> Unknown: 節點失聯
Succeeded --> [*]
Failed --> [*]
| 狀態 | 說明 |
|---|---|
| Pending | Pod 已被接受,但容器尚未創建 |
| Running | Pod 已綁定到節點,所有容器已創建 |
| Succeeded | 所有容器成功終止,不會重啟 |
| Failed | 所有容器終止,至少一個失敗 |
| Unknown | 無法取得 Pod 狀態 |
常用 Pod 操作
1 | # 查看 Pod 列表 |
Deployment:聲明式部署
為什麼需要 Deployment?
直接創建 Pod 有幾個問題:
- Pod 掛掉不會自動重建
- 無法方便地水平擴展
- 更新時需要手動刪除舊 Pod
Deployment 解決了這些問題,它提供:
- 自動維持期望的 Pod 副本數
- 滾動更新與回滾
- 擴縮容
Deployment、ReplicaSet 與 Pod 的關係
graph TD
DEP[Deployment<br/>nginx-deployment] --> RS1[ReplicaSet<br/>nginx-rs-abc123<br/>v1.20]
DEP --> RS2[ReplicaSet<br/>nginx-rs-def456<br/>v1.21]
RS1 --> P1[Pod 1]
RS1 --> P2[Pod 2]
RS1 --> P3[Pod 3]
RS2 --> P4[Pod 4<br/>新版本]
RS2 --> P5[Pod 5<br/>新版本]
style RS1 fill:#f0f0f0
style RS2 fill:#90EE90
- Deployment:管理 ReplicaSet,處理更新邏輯
- ReplicaSet:確保指定數量的 Pod 副本運行
- Pod:實際運行的容器實例
注意:通常不需要直接管理 ReplicaSet,讓 Deployment 來處理。
Deployment YAML 詳解
1 | apiVersion: apps/v1 |
更新策略詳解
RollingUpdate(滾動更新)
預設策略,逐步替換舊 Pod,確保服務不中斷。
graph LR
subgraph "初始狀態"
A1[v1 Pod] --> A2[v1 Pod] --> A3[v1 Pod]
end
subgraph "更新中"
B1[v1 Pod] --> B2[v1 Pod] --> B3[v2 Pod]
end
subgraph "更新完成"
C1[v2 Pod] --> C2[v2 Pod] --> C3[v2 Pod]
end
參數說明:
| 參數 | 說明 | 範例 |
|---|---|---|
maxSurge |
更新時可超出期望副本數的最大值 | 1 或 25% |
maxUnavailable |
更新時可不可用的最大 Pod 數 | 0 或 25% |
常見設定:
1 | # 零停機更新(保守策略) |
Recreate(重建)
先刪除所有舊 Pod,再創建新 Pod。會有短暫停機。
1 | strategy: |
適用場景:
- 不能同時運行兩個版本(如資料庫 Schema 不兼容)
- 開發/測試環境快速更新
Deployment 常用操作
1 | # 創建 Deployment |
實用技巧:記錄版本變更
1 | # 使用 --record 記錄變更命令 |
Service:服務發現與負載均衡
為什麼需要 Service?
Pod 有以下特點:
- IP 是動態的:Pod 重建後 IP 會改變
- Pod 是臨時的:隨時可能被替換
這意味著你不能直接用 Pod IP 存取服務。Service 提供穩定的存取端點。
graph LR
CLIENT[Client] --> SVC[Service<br/>my-svc<br/>ClusterIP: 10.0.0.10]
SVC --> P1[Pod 1<br/>10.244.1.5]
SVC --> P2[Pod 2<br/>10.244.2.8]
SVC --> P3[Pod 3<br/>10.244.3.12]
style SVC fill:#90EE90
Label 與 Selector
Service 使用 Label Selector 來選擇後端 Pod。
1 | # Deployment 中的 Pod 標籤 |
Service 四種類型
graph TD
subgraph "Service 類型比較"
CI[ClusterIP<br/>叢集內部存取]
NP[NodePort<br/>節點端口暴露]
LB[LoadBalancer<br/>外部負載均衡]
EN[ExternalName<br/>外部服務別名]
end
CI --> |預設類型| A[內部服務]
NP --> |開發測試| B[節點 IP:Port]
LB --> |生產環境| C[雲端 LB]
EN --> |外部整合| D[DNS 別名]
1. ClusterIP(預設)
僅叢集內部可存取。
1 | apiVersion: v1 |
1 | # 叢集內存取方式 |
2. NodePort
透過節點 IP 和指定端口存取,適合開發測試。
1 | apiVersion: v1 |
1 | # 存取方式 |
3. LoadBalancer
在雲端環境自動創建外部負載均衡器。
1 | apiVersion: v1 |
1 | # 查看外部 IP |
4. ExternalName
將 Service 映射到外部 DNS 名稱。
1 | apiVersion: v1 |
1 | # 存取時會解析到 db.example.com |
Service 類型選擇指南
| 類型 | 使用場景 | 優點 | 缺點 |
|---|---|---|---|
| ClusterIP | 內部服務通訊 | 簡單、安全 | 外部無法直接存取 |
| NodePort | 開發測試、臨時存取 | 不需額外設定 | 端口範圍限制 |
| LoadBalancer | 生產環境對外服務 | 自動配置 LB | 需雲端支援、成本較高 |
| ExternalName | 存取外部服務 | 統一服務發現 | 僅支援 DNS |
Headless Service
不分配 ClusterIP,直接返回 Pod IP,適用於 StatefulSet。
1 | apiVersion: v1 |
1 | # DNS 查詢會返回所有 Pod IP |
實戰範例:部署完整應用
讓我們結合 Deployment 和 Service 部署一個完整的應用。
應用架構
graph LR
USER[使用者] --> SVC[Service<br/>NodePort:30080]
SVC --> P1[Pod 1<br/>Web App]
SVC --> P2[Pod 2<br/>Web App]
SVC --> P3[Pod 3<br/>Web App]
完整配置
1 | # app-complete.yaml |
部署與測試
1 | # 部署應用 |
本章重點回顧
Pod 要點
- 最小部署單位:不是容器,是一組容器的抽象
- 共享資源:同一 Pod 內的容器共享網路和儲存
- 生命週期:臨時的(Ephemeral),不會被修復,只會被替換
- 不要直接管理:通常透過 Deployment 來管理
Deployment 要點
- 聲明式配置:描述期望狀態,K8s 自動達成
- 自動維護副本數:確保指定數量的 Pod 運行
- 滾動更新:無停機更新,支援回滾
- 與 ReplicaSet 關係:Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod
Service 要點
- 穩定端點:解決 Pod IP 動態變化問題
- 服務發現:透過 DNS 名稱存取服務
- 負載均衡:自動分配流量到多個 Pod
- 四種類型:ClusterIP、NodePort、LoadBalancer、ExternalName
下一篇預告
在下一篇文章中,我們將深入探討 K8s 網路:
- Kubernetes 網路模型
- 服務發現機制詳解
- Ingress Controller 與路由配置
- 網路策略(Network Policy)
系列文章導覽
- Part 1:入門篇 - 認識 K8s 與核心架構
- Part 2:基礎篇 - Pod、Deployment 與 Service(本篇)
- Part 3:網路篇 - 服務發現與流量管理
- Part 4:配置與存儲篇 - ConfigMap、Secret 與 Volume
- Part 5:進階篇 - 資源管理與自動擴展
- Part 6:實戰篇 - 部署完整微服務應用
參考資源
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments







