前言
負載均衡是生產環境中不可或缺的基礎設施。在 Kubernetes 中,Ingress Controller 就是幫你實現流量分發的核心元件。這篇文章會從原理講起,透過實際的 YAML 範例帶你掌握 Nginx Ingress 的各種負載均衡配置方式。
負載均衡的基本原理
負載均衡就是把流量分散到多台伺服器上,避免單一伺服器過載。在 K8s 中,Ingress Controller 根據 Ingress 資源定義的規則,把請求轉發到後端 Service 對應的 Pod。
常見的 Ingress Controller:
| Controller | 特點 |
|---|---|
| Nginx Ingress | 最廣泛使用,功能豐富 |
| Traefik | 自動服務發現,設定簡單 |
| HAProxy | 高效能,適合大流量場景 |
它們各自支援不同的負載均衡演算法,如輪詢(Round Robin)、IP 雜湊(IP Hash)、最少連線(Least Connections)等。
基本負載均衡設定
最基本的 Ingress 設定就是根據路徑把流量分發到不同的 Service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
這個設定會把 / 開頭的請求導到 frontend-service,/api 開頭的導到 api-service。每個 Service 背後的多個 Pod 會自動做輪詢負載均衡。
Session 黏性(Sticky Session)
有些應用需要同一個使用者的請求始終落在同一個 Pod 上(例如登入狀態存在本地記憶體的情況)。這時候就需要 Session 黏性:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/affinity: "cookie"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
關鍵是 nginx.ingress.kubernetes.io/affinity: "cookie" 這個 annotation。Nginx Ingress 會自動在回應中設定一個 Cookie,後續同一個用戶端的請求都會被導到同一個 Pod。
使用場景:
- 應用程式把 Session 存在本地記憶體(而非 Redis 等外部儲存)
- WebSocket 連線需要固定到特定 Pod
- 檔案上傳等需要多個請求到同一個 Pod 的場景
選擇負載均衡演算法
除了預設的輪詢,還可以透過 annotation 設定其他演算法:
metadata:
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/affinity-mode: "balanced"
affinity-mode: "balanced" 會根據後端服務的權重來做負載均衡,而不是單純的輪詢。
常用的負載均衡策略:
| 策略 | 說明 | 適用場景 |
|---|---|---|
| Round Robin(輪詢) | 依序輪流分配 | 後端 Pod 規格一致 |
| IP Hash | 根據來源 IP 固定路由 | 不方便用 Cookie 的場景 |
| Least Connections | 分配給目前連線數最少的 Pod | 長連線或處理時間差異大 |
| Balanced | 根據權重分配 | 後端 Pod 效能不一致 |
整合外部負載均衡器
在某些架構中,Ingress Controller 前面還有一層外部 LB(如雲端的 ALB/NLB)。這時候可以設定 External Traffic Policy 為 Local,讓流量直接到達本地節點的 Pod:
metadata:
annotations:
nginx.ingress.kubernetes.io/external-traffic-policy: "Local"
這個設定的好處:
- 避免跨節點的 SNAT,保留真實的客戶端 IP
- 減少一跳網路延遲
- 外部 LB 可以直接做健康檢查
但要注意:如果 Pod 在某些節點上沒有部署,那些節點收到的流量會被丟棄。所以通常搭配 DaemonSet 或確保每個節點都有 Pod。
小結
Nginx Ingress Controller 提供了豐富的負載均衡功能,從基本的路徑路由、Session 黏性、多種演算法選擇到外部 LB 整合,都能透過 annotation 輕鬆設定。根據你的應用特性選擇合適的策略,是確保服務效能和可用性的關鍵。

發佈留言