Kubernetes Service 網路概念完整解析
Kubernetes Service 網路概念完整解析
在 Kubernetes 中,Pod 是短暫的——它們會因為節點故障、滾動更新或自動擴縮而被刪除並重建,每次重建後 IP 位址都會改變。這讓服務發現(Service Discovery)成為一個必須解決的問題:其他服務怎麼知道要連到哪個 IP?
這就是 Kubernetes Service 存在的原因。本文深入解析 Service 的各種類型、DNS 解析機制,以及 kube-proxy 的運作原理。
Service 的本質
Kubernetes Service 是一個抽象層,定義了一組 Pod 的邏輯集合,以及存取這些 Pod 的策略。Service 透過 Label Selector 選取目標 Pod,並提供一個穩定的虛擬 IP(ClusterIP)。
# 基本 Service 定義
apiVersion: v1
kind: Service
metadata:
name: my-app-service
namespace: production
spec:
selector:
app: my-app # 選取帶有此標籤的 Pod
version: stable
ports:
- protocol: TCP
port: 80 # Service 暴露的端口
targetPort: 3000 # Pod 實際監聽的端口
type: ClusterIP # Service 類型Service 的四種類型
1. ClusterIP(預設)
ClusterIP 只在叢集內部可存取,分配一個虛擬 IP:
spec:
type: ClusterIP
clusterIP: 10.96.100.50 # 可指定,或讓系統自動分配
ports:
- port: 80
targetPort: 8080同一叢集中的任何 Pod 都可以透過 my-app-service.production.svc.cluster.local 或 my-app-service.production 存取此 Service。
2. NodePort
在每個節點上開放一個端口(30000-32767),讓叢集外部可存取:
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80 # ClusterIP 端口
targetPort: 8080 # Pod 端口
nodePort: 30080 # 節點端口(可選,不指定則自動分配)存取方式:http://<任意節點IP>:30080
3. LoadBalancer
在雲端環境中自動建立外部負載均衡器:
spec:
type: LoadBalancer
selector:
app: web-frontend
ports:
- port: 443
targetPort: 8443
protocol: TCP雲端供應商(AWS、GCP、Azure)會自動配置 ELB/GLB 等負載均衡器,並分配一個外部 IP。
4. ExternalName
將 Service 映射到外部 DNS 名稱,不涉及實際的 Pod 選取:
apiVersion: v1
kind: Service
metadata:
name: external-database
namespace: production
spec:
type: ExternalName
externalName: db.example.com這讓叢集內的應用程式可以用統一的方式存取外部服務,需要切換外部端點時只需更改 Service,不需更改應用程式設定。
Headless Service
有時候你需要直接存取各個 Pod,而不是透過負載均衡。設定 clusterIP: None 可以建立 Headless Service:
apiVersion: v1
kind: Service
metadata:
name: my-statefulset-service
spec:
clusterIP: None
selector:
app: my-statefulset
ports:
- port: 5432
targetPort: 5432DNS 查詢 Headless Service 時,會直接回傳所有 Pod 的 IP 清單,而不是 ClusterIP。這對 StatefulSet(如資料庫叢集)特別有用。
Kubernetes DNS
CoreDNS 是 Kubernetes 的預設 DNS 伺服器,負責解析 Service 和 Pod 的名稱。
DNS 命名規則
# 完整格式
<service-name>.<namespace>.svc.<cluster-domain>
# 範例
my-app-service.production.svc.cluster.local
# 同 namespace 內可以省略
my-app-service
my-app-service.production驗證 DNS 解析
# 在 Pod 內執行 DNS 查詢
kubectl exec -it debug-pod -- nslookup my-app-service.production
# 使用 dig
kubectl exec -it debug-pod -- dig my-app-service.production.svc.cluster.local
# 查看 DNS 設定
kubectl exec -it debug-pod -- cat /etc/resolv.conf
# 輸出:
# nameserver 10.96.0.10
# search production.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5Endpoints 與 EndpointSlices
Service 的後端實際上是由 Endpoints 物件管理的:
# 查看 Service 對應的 Endpoints
kubectl get endpoints my-app-service -n production
# 輸出
NAME ENDPOINTS AGE
my-app-service 10.244.1.5:8080,10.244.2.3:8080 5d當 Pod 的 Ready 狀態改變時,Endpoints 會自動更新。這就是為什麼健康檢查(Readiness Probe)如此重要——只有 Ready 的 Pod 才會出現在 Endpoints 中,才能接收流量。
kube-proxy 的運作原理
kube-proxy 在每個節點上運行,負責實現 Service 的網路規則。它有三種模式:
iptables 模式(預設)
用戶端請求 → ClusterIP:Port
↓
iptables DNAT 規則(隨機選擇後端 Pod)
↓
目標 Pod IP:Portkube-proxy 監聽 Kubernetes API,當 Service 或 Endpoints 變更時,更新每個節點上的 iptables 規則。
IPVS 模式(高效能)
對於大型叢集,IPVS 模式效能更好:
# 啟用 IPVS 模式
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "ipvs"IPVS 使用雜湊表而非線性掃描,在大量 Service 和 Endpoints 的情況下效能大幅優於 iptables。
Ingress:七層負載均衡
Ingress 是管理外部 HTTP/HTTPS 流量的資源,建立在 Service 之上:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80常見問題排查
# 1. 確認 Service 存在且設定正確
kubectl describe service my-app-service -n production
# 2. 確認 Endpoints 不為空
kubectl get endpoints my-app-service -n production
# 3. 確認 Pod 標籤符合 Selector
kubectl get pods -n production --show-labels
kubectl get pods -n production -l app=my-app
# 4. 確認 Pod 的 Readiness Probe 通過
kubectl describe pod <pod-name> -n production
# 5. 在 Pod 內測試連線
kubectl exec -it debug-pod -n production -- curl http://my-app-service/health總結
Kubernetes Service 是叢集內部網路的核心抽象。理解 ClusterIP、NodePort、LoadBalancer 和 Headless Service 的差異,掌握 DNS 解析機制和 kube-proxy 的工作原理,是部署和維護 Kubernetes 應用的必備知識。配合 Ingress 處理外部流量,你就擁有了完整的 Kubernetes 網路工具箱。
分享這篇文章