Traefik on Kubernetes (K8s):Ingress Controller 與 CRD
在 Docker Compose 環境中,我們通過 Labels 來設定 Traefik。而在 Kubernetes (K8s) 中,Traefik 扮演的是 Ingress Controller 的角色。
雖然 Traefik 支援標準的 Kubernetes Ingress 資源,但為了發揮其全部實力(如 Middleware、TCP/UDP 路由、金絲雀佈署等),官方強烈建議使用 Traefik 自定義的 CRD (Custom Resource Definition),其中最核心的就是 IngressRoute。
本章將帶你一步步在 Kubernetes 叢集中部署 Traefik,並使用 CRD 進行進階流量管理。
安裝 Traefik (使用 Helm)
在 K8s 上安裝 Traefik 最推薦的方式是使用 Helm。它能幫我們自動處理 CRD 的安裝和 RBAC 權限設定。
1. 新增 Helm Repo
首先,加入 Traefik 的官方 Helm 儲存庫:
helm repo add traefik https://traefik.github.io/charts
helm repo update
2. 建立設定檔 (values.yaml)
雖然可以直接安裝,但我建議建立一個 values.yaml 來客製化你的設定。例如,我們希望預設啟用 Dashboard 並強制使用 HTTPS:
# values.yaml
# 啟用 Dashboard (不公開,透過 Port Forward 或 IngressRoute 存取)
ingressRoute:
dashboard:
enabled: true
# 設定 Service 類型 (雲端環境通常用 LoadBalancer)
service:
type: LoadBalancer
# 全域設定:將 HTTP 自動導向 HTTPS
ports:
web:
redirectTo: websecure
3. 執行安裝
將 Traefik 安裝到 traefik namespace:
helm install traefik traefik/traefik \
--create-namespace \
--namespace traefik \
-f values.yaml
安裝完成後,你可以檢查 Pod 和 Service 狀態:
kubectl get pods,svc -n traefik
核心概念:IngressRoute vs Ingress
為什麼 Traefik 要發明自己的 IngressRoute CRD,而不直接用 K8s 內建的 Ingress?
| 特性 | Kubernetes Ingress | Traefik IngressRoute (CRD) |
|---|---|---|
| 標準化 | ✅ K8s 標準資源,可跨 Controller 遷移 | ❌ Traefik 專有,綁定 Traefik |
| 功能支援 | ⚠️ 依賴大量的 Annotations (註釋),語法混亂且無型別檢查 | ✅ 結構化設定,支援 TCP/UDP、Middleware 引用 |
| 多協議 | 僅 HTTP/HTTPS | HTTP, HTTPS, TCP, UDP |
| 易用性 | 簡單場景適用 | 複雜場景 (如重寫路徑、Header 修改) 更直觀 |
簡單來說:如果你希望設定乾淨、可維護,且需要 Middleware 功能,請使用 IngressRoute。
實戰:部署一個 Web 服務
讓我們部署一個簡單的 whoami 服務,並透過 IngressRoute 讓外部存取。
1. 部署應用程式 (Deployment & Service)
首先建立標準的 K8s Deployment 和 Service:
# whoami.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
ports:
- name: web
port: 80
targetPort: 80
selector:
app: whoami
套用設定:
kubectl apply -f whoami.yaml
2. 定義路由 (IngressRoute)
現在,我們不寫 Ingress,而是寫 IngressRoute:
# whoami-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami-route
namespace: default
spec:
entryPoints:
- websecure # 對應 Traefik 的 https entrypoint
routes:
- match: Host(`whoami.example.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: whoami # 指向原本的 K8s Service 名稱
port: 80
tls:
certResolver: myresolver # (選擇性) 如果有設定自動憑證
這裡的 routes 語法與 Docker Label 中的語法 (Host(...) && PathPrefix(...)) 完全一致!這大大降低了學習門檻。
進階功能:Middleware CRD
在 K8s 中,Middleware 也是一個 CRD 物件。例如,我們想為 whoami 服務加上 Basic Auth 密碼保護。
1. 定義 Middleware
# auth-middleware.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: my-auth
namespace: default
spec:
basicAuth:
secret: my-secret-auth # 需先建立含有 user/password 的 K8s Secret
2. 在 IngressRoute 中引用
修改剛剛的 IngressRoute,加入 middlewares 欄位:
spec:
routes:
- match: Host(`whoami.example.com`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: my-auth # 引用同 namespace 下的 Middleware CRD
namespace: default
金絲雀佈署 (Traffic Splitting)
K8s 原生 Ingress 很難做到精確的流量分割 (Canary Deployment),但 Traefik 提供了 TraefikService CRD 來輕鬆達成。
假設你有 whoami-v1 和 whoami-v2 兩個 Service,你想讓 v2 承擔 20% 的流量:
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
name: whoami-canary
namespace: default
spec:
weighted:
services:
- name: whoami-v1
port: 80
weight: 80
- name: whoami-v2
port: 80
weight: 20
接著,將 IngressRoute 的目標指向這個 TraefikService 即可:
services:
- name: whoami-canary
kind: TraefikService # 注意這裡要指定 kind
總結
在 Kubernetes 上使用 Traefik,雖然初期需要適應一下 CRD (IngressRoute, Middleware, TraefikService) 的寫法,但它帶來的結構化設定和強大功能,絕對值得投資。
如果你的團隊正在尋找一個能夠同時處理一般 Ingress 流量、API Gateway 需求(如 RateLimit, Auth),甚至 TCP/UDP 流量的解決方案,Traefik + CRD 是一個非常現代且強大的選擇。