Pod 跑起來了,外面怎麼連進去?
到 Day 5 Deployment 為止,我們的 Pod 管得好好的:擴縮容、滾動更新、自我修復都會了。但是有個現實問題沒解決:
Pod 跑起來了,但 Pod 有三個常見的痛點:
10.42.0.15 變成 10.42.0.20。前端寫死 IP 連線就斷了K8s 的解法是 Service。Service 給你一個永遠不變的 IP + 自動負載均衡。Pod 怎麼換、怎麼重建都不影響。
ClusterIP:Service 的預設類型
Service 有三種類型,這篇先講最常用的 ClusterIP:
- 給 Service 一個叢集內部的虛擬 IP
- IP 永遠不變(只要 Service 存在)
- 自動把流量負載均衡到後面的 Pod
- 自動 DNS 解析(用 Service 名字就能連)
⚠️ ClusterIP 只在叢集內可見。外面的瀏覽器連不上 — 那是 NodePort 的工作。
Service 怎麼找到後面的 Pod?
答案還是 label + selector:
# service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP # 預設值,可省略
selector:
app: nginx # ← 找所有 app=nginx 的 Pod
ports:
- port: 80 # Service 監聽的 port
targetPort: 80 # 轉發到 Pod 的 port
💡 黃金法則重申:Deployment selector / Pod template labels / Service selector 三者必須一致。寫錯一個 Service 就找不到 Pod。
port vs targetPort 怎麼分?
port: 80— Service 自己監聽的 port(別人連 Service 用這個)targetPort: 80— 轉發到 Pod 容器的哪個 port(最終接收請求的地方)
ports:
- port: 8080 # 別人連 nginx-svc:8080
targetPort: 80 # 實際送到 Pod 的 80
對照 docker run -p 8080:80:左邊 8080 = port,右邊 80 = targetPort。
部署 + 驗證
kubectl apply -f service-clusterip.yaml
# 看 Service
kubectl get svc
# nginx-svc ClusterIP 10.43.0.150 <none> 80/TCP
# 10.43.0.150 就是 ClusterIP,永遠不變
Endpoints:Service 背後的 Pod IP 列表
K8s 在背後維護一個 Endpoints 物件,記錄 Service 對應到哪些 Pod IP:
kubectl get endpoints nginx-svc
# ENDPOINTS: 10.42.0.15:80, 10.42.1.8:80, 10.42.2.12:80
這三個就是 nginx Deployment 的三個 Pod IP。
Pod 重建/擴容時,Endpoints 自動更新 — 你完全不用手動改。
從另一個 Pod 連進去測試
# 開一個臨時 Pod 測試
kubectl run test-curl --image=curlimages/curl --rm -it --restart=Never -- sh
# 進到 shell 後
curl http://nginx-svc
# 看到 nginx 歡迎頁
# 完整 DNS 名字也行
curl http://nginx-svc.default.svc.cluster.local
# 多打幾次,K8s 自動負載均衡到不同 Pod
DNS 名字格式:用 Service 名字就能連
K8s 內建 CoreDNS,每個 Service 自動註冊一筆 DNS 紀錄:
完整:<svc-name>.<namespace>.svc.cluster.local
同 namespace:<svc-name>
跨 namespace:<svc-name>.<namespace>
實際例子:
nginx-svc← 在 default namespace 內,這樣就行nginx-svc.default← 跨 namespace 連nginx-svc.default.svc.cluster.local← 完整 FQDN
自動更新驗證:刪 Pod 看 Endpoints
kubectl get endpoints nginx-svc
# 記下三個 IP
kubectl delete pod nginx-deploy-xxx-aaa
# Deployment 自動補新 Pod(IP 變了)
# 等幾秒
kubectl get endpoints nginx-svc
# 三個 IP 中有一個變了 ← Service 自動偵測 + 更新
Service 幫你解決的問題:Pod 隨便掛、隨便重建、IP 怎麼變都沒關係,Service 地址永遠不變、流量永遠到健康的 Pod。
連不上 Service 怎麼辦?常見排錯
固定排錯流程:
# 1. 看 endpoints 有沒有 IP
kubectl get endpoints nginx-svc
# 空的 → selector 沒對上
# 有 IP → 走第 2 步
# 2. 確認 selector 跟 Pod label 一致
kubectl describe svc nginx-svc | grep Selector
# Selector: app=nginx
kubectl get pods --show-labels
# 確認 Pod 的 LABELS 有 app=nginx
# 3. 確認 targetPort 跟容器實際監聽的 port 一致
90% 的 Service 連不上是 selector 對不上或 targetPort 寫錯。
對照 Docker Compose
| 功能 | Docker Compose | K8s ClusterIP |
|---|---|---|
| 服務名稱 DNS | http://api:8080 | http://nginx-svc:80 |
| 跨 Node | 做不到 | ✅ |
| 自動負載均衡 | 簡單輪詢 | kube-proxy 真的負載均衡 |
| 健康檢查踢 Pod | 做不到 | ✅ |
重點整理
- ClusterIP = 叢集內部的穩定 IP,永遠不變
- 用
selector+ label 找後面的 Pod port是 Service 監聽的、targetPort是 Pod 容器監聽的- 用
在同 namespace 直接連 - Endpoints 自動更新(Pod 變動跟著動)
- 連不上 → 先看 Endpoints 是否為空 → selector → targetPort
下一步
ClusterIP 解決了叢集內部的連線。但外面的使用者怎麼連?這就要用 NodePort、LoadBalancer 和三種 Service 的差異。