Kubernetes 核心物件完整教學:Pod、Deployment、Service 一次學會

Kubernetes 核心物件完整教學:Pod、Deployment、Service 一次學會
學 Kubernetes,最重要的是搞懂「物件」。
Pod、Deployment、Service⋯⋯這些名詞一開始很容易搞混。但只要理解它們各自的角色,Kubernetes 就會變得清晰很多。
這篇文章會帶你完整走過 Kubernetes 最重要的核心物件。
Kubernetes 的基本介紹,請參考 Kubernetes 完整指南。架構說明請參考 Kubernetes 架構完整解析。
Pod 完整解析
Pod 是 Kubernetes 最基本的部署單位。
Pod 是什麼
一句話說明: Pod 是一個或多個容器的組合,是 Kubernetes 調度的最小單位。
重點理解:
- 你不會直接部署容器,你部署的是 Pod
- Pod 裡的容器共享網路和儲存
- Pod 是短暫的,隨時可能被刪除重建
| 特性 | 說明 |
|---|---|
| 最小單位 | Kubernetes 不管理單個容器,管理 Pod |
| 共享網路 | 同 Pod 內的容器用 localhost 溝通 |
| 共享儲存 | 可以掛載同一個 Volume |
| 短暫性 | Pod 死了就死了,不會復活 |
單容器 vs 多容器 Pod
單容器 Pod(最常見):
一個 Pod 裡只有一個容器。90% 以上的情況都是這樣。
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
多容器 Pod:
當多個容器需要緊密協作時才使用。
| 模式 | 說明 | 範例 |
|---|---|---|
| Sidecar | 輔助主容器 | 日誌收集、代理 |
| Ambassador | 代理外部連線 | 資料庫代理 |
| Adapter | 標準化輸出 | 監控指標轉換 |
Sidecar 範例:
apiVersion: v1
kind: Pod
metadata:
name: app-with-logging
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: logs
mountPath: /var/log/app
- name: log-collector
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
volumes:
- name: logs
emptyDir: {}
主容器寫日誌,Sidecar 容器收集日誌。兩個容器共享同一個 Volume。
Pod 生命週期
Pod 有明確的生命週期狀態:
| 狀態 | 說明 |
|---|---|
| Pending | 已被接受,但容器還沒準備好 |
| Running | 至少有一個容器在執行 |
| Succeeded | 所有容器成功執行完畢 |
| Failed | 至少有一個容器失敗 |
| Unknown | 無法取得 Pod 狀態 |
生命週期流程:
建立 Pod
↓
Pending(調度中、下載映像檔)
↓
Running(容器執行中)
↓
Succeeded / Failed / 被刪除
重要觀念:
Pod 不會「修復」自己。如果 Pod 掛了,它就是掛了。新的 Pod 會被建立來取代它(如果你有用 Deployment)。
Pod YAML 完整範例
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
environment: production
spec:
containers:
- name: app
image: my-app:1.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
restartPolicy: Always
重要欄位說明:
| 欄位 | 用途 |
|---|---|
labels | 標籤,用於選擇和分類 |
resources | 資源請求和限制 |
env | 環境變數 |
livenessProbe | 存活檢查 |
readinessProbe | 就緒檢查 |
restartPolicy | 重啟策略 |
插圖:白板上繪製的 Pod 生命週期流程圖
場景描述: 白板上繪製的 Pod 生命週期流程圖,從左到右依序標示 Pending、Running、Succeeded/Failed 三個狀態方塊,中間有箭頭連接,每個狀態下方有簡短文字說明該狀態的含義。需要顯示的中文字:等待中、執行中、完成、失敗
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
kubernetes-pod-lifecycle-diagram
Deployment 深入解析
實際上你幾乎不會直接建立 Pod。你會建立 Deployment。
為什麼需要 Deployment
直接建立 Pod 的問題:
| 問題 | 說明 |
|---|---|
| 沒有自動重啟 | Pod 掛了就沒了 |
| 沒有擴展機制 | 無法輕鬆增減數量 |
| 更新很麻煩 | 要手動刪除舊的、建立新的 |
| 沒有版本控制 | 無法回滾 |
Deployment 解決這些問題:
| 功能 | 說明 |
|---|---|
| 自動維持數量 | 掛一個補一個 |
| 宣告式擴展 | 改個數字就好 |
| 滾動更新 | 零停機時間更新 |
| 版本歷史 | 可以快速回滾 |
ReplicaSet 的角色
Deployment 不直接管理 Pod,它管理 ReplicaSet,ReplicaSet 再管理 Pod。
Deployment
↓ 管理
ReplicaSet
↓ 管理
Pod, Pod, Pod
為什麼要這樣設計?
更新時,Deployment 會建立新的 ReplicaSet,逐步把 Pod 從舊 ReplicaSet 轉移到新 ReplicaSet。舊的 ReplicaSet 保留著,方便回滾。
Deployment YAML 範例
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
關鍵欄位:
| 欄位 | 說明 |
|---|---|
replicas | 要維持幾個 Pod |
selector | 用什麼標籤選擇 Pod |
template | Pod 的模板 |
strategy | 更新策略 |
滾動更新機制
當你更新 Deployment(例如換新的映像檔):
kubectl set image deployment/my-app app=my-app:2.0
滾動更新過程:
初始狀態:3 個 v1 Pod
第一步:建立 1 個 v2 Pod
v1: ●●●
v2: ●
第二步:v2 Ready 後,刪除 1 個 v1
v1: ●●
v2: ●
第三步:建立第 2 個 v2
v1: ●●
v2: ●●
第四步:刪除 1 個 v1
v1: ●
v2: ●●
第五步:建立第 3 個 v2
v1: ●
v2: ●●●
第六步:刪除最後 1 個 v1
v1:
v2: ●●●
完成!
策略參數:
| 參數 | 說明 | 範例值 |
|---|---|---|
maxSurge | 最多可以多幾個 Pod | 1 或 25% |
maxUnavailable | 最多可以少幾個 Pod | 0 或 25% |
回滾操作
更新出問題?可以快速回滾。
# 查看更新歷史
kubectl rollout history deployment/my-app
# 回滾到上一版
kubectl rollout undo deployment/my-app
# 回滾到指定版本
kubectl rollout undo deployment/my-app --to-revision=2
# 查看回滾狀態
kubectl rollout status deployment/my-app
🏗️ 需要 Kubernetes 架構規劃?
正確的物件設計影響系統的可維護性和穩定性。讓專家幫你規劃。
👉 預約架構諮詢
Service 網路存取
Pod 有了,但外界怎麼存取它?這就是 Service 的工作。
Service 的必要性
問題:Pod 的 IP 會變。
- Pod 重啟後 IP 會變
- Pod 被重新調度到其他 Node,IP 會變
- 擴展時新 Pod 有新的 IP
Service 提供穩定的存取點:
| 特性 | 說明 |
|---|---|
| 固定 IP | Service 的 ClusterIP 不會變 |
| DNS 名稱 | 可以用名稱存取,例如 my-service |
| 負載均衡 | 自動分配流量到後端 Pod |
ClusterIP、NodePort、LoadBalancer
Kubernetes 提供三種 Service 類型:
| 類型 | 存取方式 | 使用場景 |
|---|---|---|
| ClusterIP | 叢集內部 IP | 內部服務(預設) |
| NodePort | Node IP + Port | 測試、開發 |
| LoadBalancer | 外部負載均衡器 | 生產環境對外服務 |
ClusterIP 範例:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
type: ClusterIP
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
只能從叢集內部存取:http://my-app-service:80
NodePort 範例:
apiVersion: v1
kind: Service
metadata:
name: my-app-nodeport
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080
可以從外部存取:http://<node-ip>:30080
LoadBalancer 範例:
apiVersion: v1
kind: Service
metadata:
name: my-app-lb
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
雲端會自動建立負載均衡器,分配外部 IP。
Service 與 Endpoint
Service 怎麼知道要把流量送到哪些 Pod?
透過 Label Selector:
# Service
spec:
selector:
app: my-app # 選擇有這個 label 的 Pod
Endpoint 自動維護:
Kubernetes 會自動建立和維護 Endpoint 物件,記錄符合 selector 的 Pod IP。
# 查看 Endpoint
kubectl get endpoints my-app-service
輸出:
NAME ENDPOINTS AGE
my-app-service 10.1.0.5:8080,10.1.0.6:8080,10.1.0.7:8080 1h
流量路徑:
Client → Service IP → kube-proxy → Pod IP
插圖:三欄式比較圖
場景描述: 三欄式比較圖,分別標示 ClusterIP、NodePort、LoadBalancer 三種 Service 類型,每欄下方有簡單的網路流向示意,顯示流量從外部或內部如何到達 Pod,使用不同顏色區分內部和外部流量。需要顯示的中文字:叢集內部、外部存取、負載均衡
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
kubernetes-service-types-comparison
ConfigMap 與 Secret
應用程式需要設定。把設定寫死在容器裡不是好主意。
設定外部化
為什麼要外部化設定?
| 問題 | 說明 |
|---|---|
| 環境差異 | 開發、測試、生產的設定不同 |
| 安全性 | 密碼不該寫在程式碼裡 |
| 靈活性 | 改設定不用重建映像檔 |
Kubernetes 的解法:
| 物件 | 用途 |
|---|---|
| ConfigMap | 一般設定(非敏感) |
| Secret | 敏感資訊(密碼、金鑰) |
ConfigMap 使用
建立 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "db.example.com"
DATABASE_PORT: "5432"
LOG_LEVEL: "info"
config.json: |
{
"feature_flags": {
"new_ui": true
}
}
使用方式一:環境變數
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
env:
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_HOST
# 或一次載入全部
envFrom:
- configMapRef:
name: app-config
使用方式二:掛載為檔案
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
ConfigMap 的內容會變成 /etc/config/ 下的檔案。
Secret 使用
建立 Secret:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4= # base64 編碼的 "admin"
password: cGFzc3dvcmQ= # base64 編碼的 "password"
用 kubectl 建立(比較方便):
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=password
使用方式:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Secret 的安全性
重要提醒:
| 事實 | 說明 |
|---|---|
| Base64 不是加密 | 任何人都可以解碼 |
| etcd 預設不加密 | Secret 明文存在 etcd |
| 需要額外措施 | 啟用 etcd 加密、用外部工具 |
增強安全性的方式:
| 方式 | 說明 |
|---|---|
| etcd 加密 | 啟用 encryption at rest |
| RBAC | 限制誰可以讀取 Secret |
| 外部方案 | HashiCorp Vault、AWS Secrets Manager |
| Sealed Secrets | 可以安全地存在 Git |
💡 K8s 設定管理有困難?
正確的設定管理是穩定運作的基礎。讓我們幫你建立最佳實踐。
👉 預約免費諮詢
其他重要物件
除了上面介紹的核心物件,還有幾個常用的物件需要認識。
Namespace
用途: 邏輯隔離資源
apiVersion: v1
kind: Namespace
metadata:
name: production
使用場景:
| 場景 | 範例 |
|---|---|
| 環境隔離 | dev、staging、production |
| 團隊隔離 | team-a、team-b |
| 專案隔離 | project-x、project-y |
常用指令:
# 列出所有 namespace
kubectl get namespaces
# 在特定 namespace 操作
kubectl get pods -n production
# 設定預設 namespace
kubectl config set-context --current --namespace=production
PersistentVolume 與 PVC
Pod 是短暫的,但有些資料需要持久保存。
PersistentVolume (PV): 叢集管理員提供的儲存空間
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
hostPath:
path: /data/my-pv
PersistentVolumeClaim (PVC): 使用者請求儲存空間
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
在 Pod 中使用:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc
Ingress
用途: HTTP/HTTPS 路由,比 LoadBalancer 更靈活
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
優點:
| 功能 | 說明 |
|---|---|
| 域名路由 | 不同域名到不同服務 |
| 路徑路由 | /api 和 /web 到不同服務 |
| TLS 終止 | 統一處理 HTTPS |
| 成本 | 多個服務共用一個 LB |
更詳細的網路說明,請參考 Kubernetes 網路架構指南。
DaemonSet、StatefulSet、Job
DaemonSet: 每個 Node 跑一個 Pod
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
spec:
selector:
matchLabels:
app: log-collector
template:
metadata:
labels:
app: log-collector
spec:
containers:
- name: fluentd
image: fluentd:latest
使用場景: 日誌收集、監控 agent、網路插件
StatefulSet: 有狀態應用
| 特性 | 說明 |
|---|---|
| 穩定網路 ID | pod-0、pod-1、pod-2 |
| 穩定儲存 | 每個 Pod 有自己的 PVC |
| 有序部署 | 按順序啟動和關閉 |
使用場景: 資料庫、分散式系統(Kafka、Elasticsearch)
Job / CronJob: 一次性或定期任務
# Job:執行一次
apiVersion: batch/v1
kind: Job
metadata:
name: backup-job
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:1.0
restartPolicy: Never
# CronJob:定期執行
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # 每天凌晨 2 點
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:1.0
restartPolicy: Never
FAQ:常見問題
Q1: Pod 和容器有什麼差別?
容器 是實際執行的程序。 Pod 是 Kubernetes 的調度單位,包含一個或多個容器。
你可以把 Pod 想成容器的「殼」,提供共享的網路和儲存。
Q2: 什麼時候用多容器 Pod?
只有當容器需要緊密協作時。
判斷標準:
- 這些容器一定要一起跑嗎?
- 它們需要共享檔案系統嗎?
- 它們的生命週期一樣嗎?
如果答案都是「是」,用多容器 Pod。否則用多個單容器 Pod。
Q3: Deployment 和 ReplicaSet 差在哪?
ReplicaSet 只負責維持 Pod 數量。 Deployment 在 ReplicaSet 之上,加上滾動更新、回滾等功能。
實務上,你幾乎只會直接使用 Deployment。
Q4: ClusterIP、NodePort、LoadBalancer 怎麼選?
| 場景 | 選擇 |
|---|---|
| 內部服務 | ClusterIP |
| 開發測試 | NodePort |
| 生產對外 | LoadBalancer 或 Ingress |
Q5: ConfigMap 改了,Pod 會自動更新嗎?
要看使用方式:
| 方式 | 自動更新 |
|---|---|
| 環境變數 | ❌ 需要重啟 Pod |
| Volume 掛載 | ✅ 會自動更新(有延遲) |
如果用環境變數,改 ConfigMap 後要重啟 Pod 才會生效。
下一步
學會這些核心物件後,你可以:
| 目標 | 行動 |
|---|---|
| 動手實作 | 閱讀 Kubernetes 入門教學 |
| 深入網路 | 閱讀 Kubernetes 網路架構指南 |
| 了解架構 | 閱讀 Kubernetes 架構完整解析 |
| 選擇工具 | 閱讀 Kubernetes 工具生態系指南 |
🚀 需要 Kubernetes 導入協助?
從核心物件設計到生產環境部署,CloudInsight 提供完整的技術支援。
👉 立即預約諮詢
延伸閱讀
- Kubernetes 完整指南 - K8s 入門總覽
- Kubernetes 架構完整解析 - Control Plane 與 Node
- Kubernetes 入門教學 - 實戰步驟指南
- Kubernetes 網路架構指南 - Service、Ingress 詳解
- Kubernetes 工具生態系指南 - Helm、監控、CI/CD
參考資料
相關文章
Kubernetes 架構完整解析:Control Plane、Node、元件一次搞懂
深入解析 Kubernetes 架構。從 Control Plane 四大元件到 Worker Node 運作原理,包含 API Server、etcd、Scheduler、kubelet 完整說明。
KubernetesKubernetes 是什麼?K8s 完整指南:架構、教學與實戰入門【2025 更新】
Kubernetes(K8s)完整入門指南。從基礎概念、核心架構到實戰部署,一次搞懂容器編排平台。包含 Docker 比較、雲端服務選擇、學習資源推薦。
KubernetesKubernetes 網路架構完整指南:CNI、Service、Ingress 一次搞懂
Kubernetes 網路架構完整解析。從 CNI 插件、Service 類型到 Ingress 設定,包含 Network Policy 和常見問題排解。