掀起 Traefik 2 的蓋頭來
- 2019 年 10 月 6 日
- 筆記
Traefik 2.0 發布也有幾天了,根據通稿來看,有幾個新的功能值得注意:
- 開始使用 CRD 來完成原本使用 Ingress + 註解來完成的任務。
- 加入了一個中間件概念,來提供豐富多樣的控制能力。
- 終於支援 TCP 了。
我的測試集群中經常會使用 Traefik 做 Ingress,又有 Maesh 加入 Service Mesh 的暖場戰之中,所以 Traefik 2.0 還是值得看看的。它的文檔做的還不太完善,著實花了一段時間來摸索,這裡做個記錄,方便後續的使用和學習。
安裝
我知道開篇說安裝特別 Low,但是奇葩的是這個版本的安裝文檔居然只提到了一個 Docker 下的安裝過程,只是在一個不起眼的角落裡有一個針對 Kubernetes 環境的安裝清單。
我做了一些修改,源碼參見:
https://gist.github.com/fleeto/0666a58e83c5b201e61ab2fca779ace2#file-traefik-v2-0-kubernetes-yaml
這裡有一點需要注意的,Traefik 預設開放三個埠:80、443 和 8080,其中 8080 是管理埠。建議將其分為兩個服務,把管理埠和業務埠做個隔離,方便使用不同策略進行訪問控制。另外 Configmap 中加入了訪問日誌方便調試,可酌情關閉。
例如下面把 Ingress 埠分配給 Loadbalancer,而管理埠僅設置為 ClusterIP。
--- apiVersion: v1 kind: Service metadata: name: traefik-ingress namespace: traefik-system labels: app: traefik spec: ports: - name: https protocol: TCP port: 443 targetPort: 443 - name: http protocol: TCP port: 80 targetPort: 80 type: LoadBalancer selector: app: traefik --- apiVersion: v1 kind: Service metadata: name: traefik-admin namespace: traefik-system labels: app: traefik spec: ports: - name: admin protocol: TCP port: 8080 targetPort: 8080 type: ClusterIP selector: app: traefik ---
配置文件很簡單,只要加入 Kubernetes 內部介面的端點即可:
providers: kubernetescrd: endpoint: https://kubernetes.default
然後給 80 和 443 埠所在的 Loadbalancer 提供一個域名,用於後續的規則設置。
部署測試服務
隨便部署一個 HTTP 服務,例如 Istio 用到的 HTTPBIN
這個服務開放了 8000 埠提供 HTTP 服務,後面我們會用這個服務進行限流測試。
開放 Dashboard
前面把 Dashboard 的服務類型設置為 ClusterIP
,創建一個 CRD 就能夠通過 Traefik 開放服務了:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard spec: entryPoints: - web routes: - match: Host(`traefik.microservice.xyz`) kind: Rule services: - name: traefik-admin port: 8080
這裡使用了一個表達式來對流量進行篩選,表達式目前的支援範圍如下表所示:

接下來用了幾個不同級別的對象:
- entryPoints:開放埠,例如我們部署中的
web
或websecure
。 - routes:路由規則。
- match:一個匹配表達式,這裡我們指定匹配域名
traefik.microservice.xyz
- name 和 Port:此處使用 Service 的定義
提交之後,就可以使用指定域名訪問 Dashboard 了:

當然了,這個並不重要。
開啟一個插件
用同樣的方法,給 HTTPBIN 開放一個路由:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: httpbin spec: entryPoints: - web routes: - kind: Rule match: Host(`httpbin.microservice.xyz`) services: - name: httpbin port: 8000
在路由定義中,可以使用插件,對該路由的進出流量進行處理,例如重定向、認證、重試等功能。
Ratelimit 的用法很簡單,官網文檔也有說明,我們模仿寫一個:
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: httpbin-traffic spec: rateLimit: burst: 1 average: 2
其中的單位稍顯死板,是 qps。但是怎麼把這個對象加入到 Route 裡面就不太明顯了:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: httpbin ... services: - name: httpbin port: 8000 middlewares: - name: httpbin-traffic
提交之後,可以看看 Dashboard 去看看這條規則的詳情:

這條路由的 Middleware 中加入了新的元素,下面可以測試一下:
$ siege httpbin.microservice.xyz/get ** SIEGE 4.0.4 ** Preparing 25 concurrent users for battle. The server is now under siege... HTTP/1.1 200 1.68 secs: 398 bytes ==> GET /get HTTP/1.1 429 1.68 secs: 17 bytes ==> GET /get HTTP/1.1 429 1.68 secs: 17 bytes ==> GET /get HTTP/1.1 429 1.68 secs: 17 bytes ==> GET /get HTTP/1.1 429 1.68 secs: 17 bytes ==> GET /get
看到極少出現 200 的響應碼,多數都是 429,證明限流生效了。
廢話
真是不知道 Kubernetes 用戶哪裡對不起 Traefik 了。