掀起 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:開放埠,例如我們部署中的 webwebsecure
  • 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 了。