Kubernetes 入門:Pod、Service、Deployment
當你 應用只是a簡單 Docker 容器時,用 Docker Compose 來managed就已經足夠了。但當你 系統擴展到以下規模時,Docker Compose 就會開始顯得力不從心:
- 你 應用needs自動伸縮(流量高時自動增加副本,流量低時減少)
- 某個容器 crash 了,needs自動重新啟動
- 你needs在不中斷服務 情況下更新版本(滾動更新)
- 你needs將多個容器平均分配到不同 伺服器上(負載平衡)
- 你 服務散落在多台雲端主機上,needs統一managed
這時候,我們就needs Kubernetes (K8s) 登場了。
what is Kubernetes?
Kubernetes 是a容器編排平台 (Container Orchestration Platform),by Google 基於其內部使用多年 Borg 系統開源而來,現在by Cloud Native Computing Foundation (CNCF) maintained。
簡單來說,Kubernetes 就是你整個應用 「作業系統」:
- Docker 容器就像是「應用程式」
- Kubernetes 就像是「作業系統」,負責managed這些應用程式 啟動、監控、資源分配與溝通
Kubernetes 優勢
| 功能 | 說明 | |------|------| | 自動修復 | 當某個容器 crash,K8s 自動重新啟動 | | 自動伸縮 | 根據 CPU 或記憶體使用量,自動增減容器數量 | | 滾動更新 | 更新版本時逐步替換,不中斷服務 | | 服務發現 | 自動為每個服務分配 DNS 名稱,容器間可直接透過名稱溝通 | | 負載平衡 | 自動將流量分配到多個容器副本 | | 儲存編排 | 自動掛載雲端硬碟、本地儲存等 | | 自我修復 | 如果某個nodes (Node) 掛了,自動在其他nodes重新排程 |
Kubernetes three核心物件
在 Kubernetes 中,一切都是「物件 (Object)」。你透過撰寫 YAML 或 JSON 來宣告你想要 狀態,然後 K8s 會努力讓現實狀態符合你 宣告。
1. Pod(最小 部署單元)
Pod 是 Kubernetes 中最小 可部署單元。a Pod 裡面可以包含a或多個容器(通常是a)。
你可以把 Pod 想像成「一艘太空船」:
- 太空船裡面可以有a或多個太空人(容器)
- 每個太空人各自執行不同 任務
- 他們共享太空船 生命週期與資源
- 太空船被摧毀時,all太空人simultaneously消失
Pod YAML 範例:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
labels:
app: my-app
version: v1
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 3000
resources:
requests:
cpu: "250m" # 最少保證 0.25 核心
memory: "256Mi" # 最少保證 256 MB
limits:
cpu: "500m" # 最多使用 0.5 核心
memory: "512Mi" # 最多使用 512 MB
但 Pod 有a重要 features:Pod 是臨時性 (Ephemeral)。如果你刪除了a Pod,它不會自動重現。這就是為什麼我們通常不會直接建立 Pod,而是透過更高層 抽象來managed它們。
2. Deployment(宣告期望狀態)
Deployment 是 Kubernetes 中最常用 控制器。它定義了你期望 「副本數量」與「更新策略」,K8s 會自動確保實際運行 Pod 數量符合你 期望。
Deployment YAML 範例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 3 # 期望 3 個副本
selector:
matchLabels:
app: my-app
template: # Pod 模板
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:v2
ports:
- containerPort: 3000
livenessProbe: # 存活檢查:如果失敗則重新啟動
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe: # 就緒檢查:如果失敗則不導入流量
httpGet:
path: /api/ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
Deployment 關鍵能力:
滾動更新 (Rolling Update)
當你將 Image 版本從 v1 更新到 v2 時,K8s 會逐步替換 Pod:
- 建立a v2 Pod
- 等待 v2 Pod 通過 Readiness Probe(就緒檢查)
- 刪除a v1 Pod
- 重複直到all Pod 都被替換
這確保了更新過程中服務完全不會中斷。
自動復原 (Rollback) 如果 v2 版本出了問題(例如 Liveness Probe 失敗),K8s 會自動停止滾動,保留 v1 版本:
# 查看 Deployment 的更新歷史
kubectl rollout history deployment/my-app-deployment
# 回滾到上一個版本
kubectl rollout undo deployment/my-app-deployment
3. Service(穩定 存取入口)
Pod 是動態 ,它可能因為nodes故障而被重新排程到不同 伺服器,IP 位址也會隨之改變。如果我們直接使用 Pod IP 來連線,只要 Pod 重啟或漂移,連線就會中斷。
Service 提供了a穩定 虛擬 IP (ClusterIP) 與 DNS 名稱,作為後端 Pod 存取入口。
Service YAML 範例:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app # 選擇所有 label 為 app: my-app 的 Pod
ports:
- protocol: TCP
port: 80 # Service 對外開放的埠
targetPort: 3000 # 轉發到 Pod 的 3000 埠
type: ClusterIP # 只在叢集內部可存取
Service 四種類型:
| 類型 | 說明 | 使用場景 | |------|------|---------| | ClusterIP | 只在叢集內部可存取,分配a虛擬 IP | 內部服務(database、API) | | NodePort | 在allnodes上開啟a隨機埠,外部可透過nodes IP 存取 | 開發測試 | | LoadBalancer | 自動建立雲端負載平衡器,分配外部 IP | 正式環境(搭配雲端服務商) | | Ingress | 七層 HTTP 路by,根據域名或路徑轉發到不同 Service | 生產環境 對外入口 |
在本機建立 Kubernetes 測試叢集
在正式購買雲端 K8s 叢集之前,我們可以用 kind (Kubernetes in Docker) 來在本機建立a測試用 K8s 環境。
install kind
# macOS (Homebrew)
brew install kind
# 驗證安裝
kind version
建立a叢集
kind create cluster --name my-test-cluster
輸出範例:
Creating cluster "my-test-cluster" ...
✓ Ensuring node image (kindest/node:v1.28.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-my-test-cluster"
You can now use your cluster with:
kubectl cluster-info --context kind-my-test-cluster
驗證叢集狀態
# 檢視節點
kubectl get nodes
# 檢視系統 Pod
kubectl get pods -n kube-system
# 取得叢集資訊
kubectl cluster-info
部署你 第a應用
現在,讓我們用剛才學到 Deployment 與 Service,將我們之前 Docker 化 應用部署到 K8s 上:
# 部署應用(建立 Deployment)
kubectl apply -f deployment.yaml
# 暴露服務(建立 Service)
kubectl apply -f service.yaml
# 查看 Pod 狀態
kubectl get pods -w
# 查看 Service
kubectl get svc
[!TIP] 在 kind 中,by於不是雲端環境,LoadBalancer 類型 Service 不會自動分配外部 IP。你可以使用
kubectl port-forward來將叢集內 服務轉發到本機:kubectl port-forward service/my-app-service 3000:80
本日總結
在本章中,你學到了:
- ✅ Kubernetes 是什麼:a容器編排平台,managed容器叢集 生命週期
- ✅ Pod:最小 部署單元,運行a或多個容器
- ✅ Deployment:宣告期望狀態,managed Pod 滾動更新與伸縮
- ✅ Service:提供穩定 存取入口,支援 ClusterIP/NodePort/LoadBalancer/Ingress
- ✅ kind 本地叢集:在本機用 Docker 建立 K8s 測試環境
- ✅ kubectl 基本操作:get、apply、port-forward、rollout
下一章,我們將真正把acomplete應用部署到雲端 Kubernetes 叢集上!