Traefik的中間件,灰度發布,流量復制


Kubernetes 1.18.3 部署 Traefik2.2

Traefik的中間件,灰度發布,流量復制基於上篇文章環境。

1.部署whoami 應用和SVC

apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 2
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: containous/whoami
          ports:
            - name: web
              containerPort: 80

2.部署 IngressRoute 對象

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: simpleingressroute
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`who.heian.com`) && PathPrefix(`/notls`)
    kind: Rule
    services:
    - name: whoami
      port: 80

3.配置 HTTPS 路由

[root@k8s-master1 who]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=who.heian.com" 
Generating a 2048 bit RSA private key
..........................................................................+++
..........+++
writing new private key to 'tls.key'
-----
[root@k8s-master1 who]#  kubectl create secret tls who-tls --cert=tls.crt --key=tls.key
secret/who-tls created

創建一個 HTTPS 訪問應用的 IngressRoute 對象

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutetls
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`who.heian.com`) && PathPrefix(`/tls`)
    kind: Rule
    services:
    - name: whoami
      port: 80
  tls:
    secretName: who-tls

4 . 中間件

中間件是 Traefik2.0 中一個非常有特色的功能,我們可以根據自己的各種需求去選擇不同的中間件來滿足服務,Traefik 官方已經內置了許多不同功能的中間件,其中一些可以修改請求,頭信息,一些負責重定向,一些添加身份驗證等等,而且中間件還可以通過鏈式組合的方式來適用各種情況。

traefik middleware overview

同樣比如上面我們定義的 whoami 這個應用,我們可以通過 https://who.heian.com/tls 來訪問到應用,但是如果我們用 http 來訪問的話呢就不行了,就會404了,因為我們根本就沒有簡單80端口這個入口點,

所以要想通過 http 來訪問應用的話自然我們需要監聽下 web 這個入口點:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutetls-http
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`who.heian.com`) && PathPrefix(`/tls`)
    kind: Rule
    services:
    - name: whoami
      port: 80

注意這里我們創建的 IngressRoute 的 entryPoints 是 web,然后創建這個對象,這個時候我們就可以通過 http 訪問到這個應用了。

但是我們如果只希望用戶通過 https 來訪問應用的話呢?按照以前的知識,我們是不是可以讓 http 強制跳轉到 https 服務去,對的,在 Traefik 中也是可以配置強制跳轉的,只是這個功能現在是通過中間件來提供的了。

如下所示,我們使用 redirectScheme 中間件來創建提供強制跳轉服務:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-https
spec:
  redirectScheme:
    scheme: https

然后將這個中間件附加到 http 的服務上面去,因為 https 的不需要跳轉:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutetls-http
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`who.heian.com`) && PathPrefix(`/tls`)
    kind: Rule
    services:
    - name: whoami
      port: 80
    middlewares: 
    - name: redirect-https

這個時候我們再去訪問 http 服務可以發現就會自動跳轉到 https 去了。關於更多中間件的用法可以查看文檔 Traefik Docs

5. 灰度發布

Traefik2.0 的一個更強大的功能就是灰度發布,灰度發布我們有時候也會稱為金絲雀發布(Canary),主要就是讓一部分測試的服務也參與到線上去,經過測試觀察看是否符號上線要求。

canary deployment

比如現在我們有兩個名為 appv1 和 appv2 的服務,我們希望通過 Traefik 來控制我們的流量,將 3⁄4 的流量路由到 appv1,¼ 的流量路由到 appv2 去,這個時候就可以利用 Traefik2.0 中提供的帶權重的輪詢(WRR)來實現該功能

首先在 Kubernetes 集群中部署上面的兩個服務。

為了對比結果我們這里提供的兩個服務一個是 heian99/myapp:v2,一個是heian99/myapp:v1,方便測試。

appv1 服務的資源清單如下所示:(appv1.yaml)heian99/myapp:v1

apiVersion: apps/v1
kind: Deployment
metadata:
  name: appv1
spec:
  selector:
    matchLabels:
      app: appv1
  template:
    metadata:
      labels:
        use: test
        app: appv1
    spec:
      containers:
      - name: myappv1
        image: heian99/myapp:v1
        ports:
        - containerPort: 80
          name: portv1
---
apiVersion: v1
kind: Service
metadata:
  name: appv1
spec:
  selector:
    app: appv1
  ports:
  - name: http
    port: 80
    targetPort: portv1

 

appv2 服務的資源清單如下所示:(appv2.yaml)heian99/myapp:v2

apiVersion: apps/v1
kind: Deployment
metadata:
  name: appv2
spec:
  selector:
    matchLabels:
      app: appv2
  template:
    metadata:
      labels:
        use: test
        app: appv2
    spec:
      containers:
      - name: myappv2
        image: heian99/myapp:v2
        ports:
        - containerPort: 80
          name: portv2
---
apiVersion: v1
kind: Service
metadata:
  name: appv2
spec:
  selector:
    app: appv2
  ports:
  - name: http
    port: 80
    targetPort: portv2

直接創建上面兩個服務:


[root@k8s-master1 test]# kubectl apply -f .
deployment.apps/appv1 created
service/appv1 created
deployment.apps/appv2 created
service/appv2 created

[root@k8s-master1 test]# kubectl get pods -l use=test
NAME                     READY   STATUS    RESTARTS   AGE
appv1-597bbc966f-chwpj   1/1     Running   0          69s
appv2-5f5489b4c5-7gsnd   1/1     Running   0          69s

 

在 Traefik2.1 中新增了一個 TraefikService 的 CRD 資源,我們可以直接利用這個對象來配置 WRR,之前的版本需要通過 File Provider,比較麻煩,新建一個描述 WRR 的資源清單:(wrr.yaml)

apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: app-wrr
spec:
  weighted:
    services:
      - name: appv1
        weight: 3  # 定義權重
        port: 80
        kind: Service  # 可選,默認就是 Service
      - name: appv2
        weight: 1
        port: 80

然后為我們的灰度發布的服務創建一個 IngressRoute 資源對象:(ingressroute.yaml)

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: wrringressroute
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`app.heian.com`)
    kind: Rule
    services:
    - name: app-wrr
      kind: TraefikService

不過需要注意的是現在我們配置的 Service 不再是直接的 Kubernetes 對象了,而是上面我們定義的 TraefikService 對象,直接創建上面的兩個資源對象,這個時候我們對域名 app.heian.com 做上解析,去瀏覽器中連續訪問 4 次,我們可以觀察到 appv1 這應用會收到 3 次請求,而 appv2 這個應用只收到 1 次請求,符合上面我們的 3:1 的權重配置。

6. 流量復制

除了灰度發布之外,Traefik 2.0 還引入了流量鏡像服務,是一種可以將流入流量復制並同時將其發送給其他服務的方法,鏡像服務可以獲得給定百分比的請求同時也會忽略這部分請求的響應。

traefik mirror

同樣的在 2.0 中只能通過 FileProvider 進行配置,在 2.1 版本中我們已經可以通過 TraefikService 資源對象來進行配置了,現在我們部署兩個 whoami 的服務,資源清單文件如下所示:

apiVersion: v1
kind: Service
metadata:
  name: v1
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: v1
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: v1
  labels:
    app: v1
spec:
  selector:
    matchLabels:
      app: v1
  template:
    metadata:
      labels:
        app: v1
    spec:
      containers:
        - name: v1
          image: heian99/myapp:v1
          ports:
            - name: web
              containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: v2
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: v2
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: v2
  labels:
    app: v2
spec:
  selector:
    matchLabels:
      app: v2
  template:
    metadata:
      labels:
        app: v2
    spec:
      containers:
        - name: v2
          image: heian99/myapp:v2
          ports:
            - name: web
              containerPort: 80

現在我們創建一個 IngressRoute 對象,將服務 v1 的流量復制 50% 到服務 v2,如下資源對象所示:(mirror-ingress-route.yaml)

apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: app-mirror
spec:
  mirroring:
    name: v1 # 發送 100% 的請求到 K8S 的 Service "v1"
    port: 80
    mirrors:
    - name: v2 # 然后復制 50% 的請求到 v2
      percent: 50
      port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: mirror-ingress-route
  namespace: default
spec:
  entryPoints:
  - web
  routes:   
  - match: Host(`mirror.heian.com`)
    kind: Rule
    services:
    - name: app-mirror
      kind: TraefikService # 使用聲明的 TraefikService 服務,而不是 K8S 的 Service

這個時候我們在瀏覽器中去連續訪問4次 mirror.heian.com 可以發現有一半的請求也出現在了 v2 這個服務中:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM