提到Traefik,有些人可能並不熟悉,但是提到Nginx,應該都耳熟能詳。
暫且我們把Traefik當成和Nginx差不多的一類軟件,待讀完整篇文章,你就會對Traefik有不一樣的認識。
本文主要帶大家對Traefik有一個全面的認識,我將從下面幾個方面作介紹。

本文基於Traefik 2.5.3進行介紹。
什么是Traefik
Traefik是一個開源的邊緣路由網關,它簡單易用並且功能全面。官方【1】的介紹是:Traefik is an [open-source](https://github.com/traefik/traefik) _Edge Router_ that makes publishing your services a fun and easy experience.
Traefik原生支持多種集群,如Kubernetes、Docker、Docker Swarm、AWS、Mesos、Marathon等;並且可以同時處理許多集群。

image.png
Traefik的核心概念及能力
Traefik是一個邊緣路由器,它會攔截外部的請求並根據邏輯規則選擇不同的操作方式,這些規則決定着這些請求到底該如何處理。Traefik提供自動發現能力,會實時檢測服務,並自動更新路由規則。

從上圖可知,請求首先會連接到entrypoints
,然后分析這些請求是否與定義的rules
匹配,如果匹配,則會通過一系列middlewares
,再到對應的services
上。
這就涉及到以下幾個重要的核心組件。
- Providers
- Entrypoints
- Routers
- Services
- Middlewares
Providers
Providers
是基礎組件,Traefik的配置發現是通過它來實現的,它可以是協調器,容器引擎,雲提供商或者鍵值存儲。
Traefik
通過查詢Providers
的API
來查詢路由的相關信息,一旦檢測到變化,就會動態的更新路由。
Entrypoints
Entrypoints
是Traefik
的網絡入口,它定義接收請求的接口,以及是否監聽TCP或者UDP。
Routers
Routers
主要用於分析請求,並負責將這些請求連接到對應的服務上去,在這個過程中,Routers還可以使用Middlewares來更新請求,比如在把請求發到服務之前添加一些Headers。
Services
Services
負責配置如何到達最終將處理傳入請求的實際服務。
Middlewares
Middlewares
用來修改請求或者根據請求來做出一些判斷(authentication, rate limiting, headers, ...),中間件被附件到路由上,是一種在請求發送到你的服務之前(或者在服務的響應發送到客戶端之前)調整請求的一種方法。
部署Traefik
Traefik的部署方式有多種,這里主要采用Helm
方式進行部署管理。
Helm部署
環境:kubernetes: 1.22.3 helm: 3.7.1
1、添加traefik helm倉庫
$ helm repo add traefik https://helm.traefik.io/traefik $ helm repo update
2、將traefik包下載到本地進行管理
$ helm search repo traefik
NAME CHART VERSION APP VERSION DESCRIPTION traefik/traefik 10.6.0 2.5.3 A Traefik based Kubernetes ingress controller $ helm pull traefik/traefik
3、部署Traefik
默認的value.yaml
[2]配置文件配置比較多,可能需要花一定的時間去梳理,不過根據相關的注釋還是可以很快的理解。
這里自定義一個配置文件my-value.yaml
,如下:
service:
type: NodePort ingressRoute: dashboard: enabled: false ports: traefik: port: 9000 expose: true web: port: 8000 expose: true websecure: port: 8443 expose: true persistence: enabled: true name: data accessMode: ReadWriteOnce size: 5G storageClass: "openebs-hostpath" path: /data additionalArguments: - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true"
進行部署,命令如下:
$ kubectl create ns traefik-ingress
$ helm install traefik -n traefik-ingress -f my-value.yaml .
這里不是使用的是默認的value.yaml
[2]配置文件。
然后可以看到部署結果,如下:
# kubectl get all -n traefik-ingress NAME READY STATUS RESTARTS AGE pod/traefik-77ff894bb5-qqszd 1/1 Running 0 6m26s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/traefik NodePort 10.108.170.22 <none> 9000:32271/TCP,80:31728/TCP,443:30358/TCP 6m26s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/traefik 1/1 1 1 6m26s NAME DESIRED CURRENT READY AGE replicaset.apps/traefik-77ff894bb5 1 1 1 6m26s
然后可以通過NodePort
訪問Dashboard頁面,如下:

使用Traefik
創建第一個路由規則
我們上面訪問Dashboard是采用的NodePort
的方式,既然已經把Traefik
部署好了,為什么不使用路由網關的方式呢?
下面我們就來創建第一個路由網關來訪問Dashboard
。
Traefik創建路由規則有多種方式,比如:
- 原生Ingress寫法
- 使用CRD IngressRoute方式
- 使用GatewayAPI的方式
這里暫時介紹前面兩種方式,關於GatewayAPI的方式在后續進行介紹。
原生Ingress路由規則
原生Ingress的路由規則,寫法就比較簡單,如下。
# cat traefik-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: traefik-dashboard-ingress annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/router.entrypoints: web spec: rules: - host: traefik-web.coolops.cn http: paths: - pathType: Prefix path: / backend: service: name: traefik port: number: 9000
創建路由規則,命令如下:
# kubectl apply -f traefik-ingress.yaml -n traefik-ingress ingress.networking.k8s.io/traefik-dashboard-ingress created
現在就可以通過域名http://traefik-web.coolops.cn:31728/dashboard/#/ 進行訪問了(31728是80端口的映射端口),如下:

使用CRD方式配置路由規則
在早期版本,Traefik僅提供kubernetes ingress方式配置路由規則,社區認為采用開發一個自定義CRD的類型能夠更好的提供Kubernetes的訪問配置【3】。
IngressRoute
的配置方式也比較簡單,如下:
# cat traefik-ingressRoute.yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard-route spec: entryPoints: - web routes: - match: Host(`traefik-web2.coolops.cn`) kind: Rule services: - name: traefik port: 9000
部署命令如下:
# kubectl apply -f traefik-ingressRoute.yaml -n traefik-ingress ingressroute.traefik.containo.us/traefik-dashboard-route created
然后就可以通過http://traefik-web2.coolops.cn:31728/dashboard/#/ 進行訪問了。

暴露HTTP服務
首先,部署一個簡單的whoami
[4]應用,YAML文件如下:
--- apiVersion: v1 kind: Pod metadata: name: whoami labels: app: whoami spec: containers: - name: whoami image: traefik/whoami:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: whoami spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: whoami type: ClusterIP
部署成功后,創建一個路由規則,使外部可以訪問。
# cat ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route spec: entryPoints: - web routes: - match: Host(`whoami.coolops.cn`) kind: Rule services: - name: whoami port: 80
創建過后,就可以進行訪問了,如下:

暴露HTTPS服務
上面的whoami
應用,是通過HTTP
進行訪問的,如果要通過HTTPS
進行訪問,應該如何配置呢?
Traefik
支持HTTPS和TLS,對於證書可以選擇自有證書,也可以使用Let's Encrypt【5】自動生成證書。這里會分別介紹這兩種方式。
自有證書配置HTTPS
現在公司基本都會自己購買更安全的證書,那對於自有證書配置HTTPS就會使用更加頻繁,這里主要介紹這種配置方式。
1、申請或者購買證書
我這里是在騰訊雲申請的免費證書。

然后下載對應的證書,並上傳到服務器上。
2、將證書文件保存為Secret
# kubectl create secret tls whoami-tls --cert=1_whoami.coolops.cn_bundle.crt --key=2_whoami.coolops.cn.key
3、創建IngressRoute對象,使其可以通過TLS訪問
# cat ingressroutetls.yaml
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route-tls spec: entryPoints: - websecure routes: - match: Host(`whoami.coolops.cn`) kind: Rule services: - name: whoami port: 80 tls: secretName: whoami-tls
創建完成后,就可以通過https://whoami.coolops.cn:30358/ 進行訪問了(30358是443映射出來的端口)。

自動生成HTTPS證書
Traefik
除了使用自有證書外,還支持Let's Encrypt
自動生成證書【6】。
要使用Let's Encrypt
自動生成證書,需要使用ACME
。需要在靜態配置中定義 "證書解析器",Traefik
負責從ACME
服務器中檢索證書。
然后,每個 "路由器 "被配置為啟用TLS,並通過tls.certresolver配置選項與一個證書解析器關聯。
Traefik
的ACME
驗證方式主要有以下三種:
- tlsChallenge
- httpChallenge
- dnsChallenge
如果使用tlsChallenge
,則要求Let's Encrypt
到 Traefik 443
端口必須是可達的。如果使用httpChallenge
,則要求Let's Encrypt
到 Traefik 80
端口必須是可達的。如果使用dnsChallenge
,則需要對應的providers
[7]。
但是我們上面部署Traefik
的時候並沒有把80和443端口暴露出來,要測試tlsChallenge
和httpChallenge
的話就必須暴露,下面我們更改一下my-value.yaml
,如下:
service:
type: NodePort ingressRoute: dashboard: enabled: false ports: traefik: port: 9000 expose: true web: port: 8000 hostPort: 80 expose: true websecure: port: 8443 hostPort: 443 expose: true persistence: enabled: true name: data accessMode: ReadWriteOnce size: 5G storageClass: "openebs-hostpath" path: /data additionalArguments: - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true"
然后重新更新一下Traefik
,命令如下:
helm upgrade traefik -n traefik-ingress -f my-value.yaml .
現在我們就可以直接通過80或443端口進行訪問了。
1、tlsChallenge
上面已經介紹過,要使用tlsChallenge
,必須能訪問入口的443端口,現在我們入口已經放開,接下來就修改Traefik
的my-value.yaml
配置,如下:
...... deployment: initContainers: - name: volume-permissions image: busybox:1.31.1 command: ["sh", "-c", "chmod -Rv 600 /data/*"] volumeMounts: - name: data mountPath: /data additionalArguments: - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true" - "--certificatesresolvers.coolops.acme.email=coolops@163.com" - "--certificatesresolvers.coolops.acme.storage=/data/acme.json" - "--certificatesresolvers.coolops.acme.tlschallenge=true"
PS:這里需要將/data目錄權限給更改一下,默認是0660,權限太大是不允許的。
然后我們創建一個ingressRoute
,如下:
# cat ingressrouteautotls.yaml
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route-auto-tls spec: entryPoints: - websecure routes: - match: Host(`whoami3.coolops.cn`) kind: Rule services: - name: whoami port: 80 tls: certResolver: coolops
這時候我們訪問https://whoami3.coolops.cn是可以正常使用證書的,如下:

2、httpChallenge
下面再使用httpChallenge
進行測試,修改my-value.yaml
配置文件如下:
...... deployment: initContainers: - name: volume-permissions image: busybox:1.31.1 command: ["sh", "-c", "chmod -Rv 600 /data/*"] volumeMounts: - name: data mountPath: /data additionalArguments: - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true" - "--certificatesresolvers.coolops.acme.email=coolops@163.com" - "--certificatesresolvers.coolops.acme.storage=/data/acme.json" - "--certificatesresolvers.coolops.acme.httpchallenge=true" - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web"
更新Traefik
過后,然后再創建一個ingressRoute
進行測試,YAML文件如下:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route-auto-tls-http spec: entryPoints: - websecure routes: - match: Host(`whoami4.coolops.cn`) kind: Rule services: - name: whoami port: 80 tls: certResolver: coolops
然后使用https://whoami4.coolops.cn
,效果如下:

3、dnsChallenge
dnsChallenge
在使用上相對比較麻煩,因為需要配置對應的provider
,不過它可以生成通配符證書,這里以阿里雲DNS【8】為例。
使用阿里DNS的前提是您的域名是在阿里雲上面,不然在簽署證書的時候會報錯,如下:
Unable to obtain ACME certificate for domains \"*.coolops.cn\" : unable to generate a certificate for the domains [*.coolops.cn]: error: one or more domains had a problem:\n[*.coolops.cn] [*.coolops.cn] acme: error presenting token: alicloud: zone coolops.cn. not found in AliDNS for domain coolops.cn\n" providerName=coolops.acme
使用阿里雲的 DNS 校驗需要配置3個環境變量:ALICLOUD_ACCESS_KEY
、ALICLOUD_SECRET_KEY
、ALICLOUD_REGION_ID
,分別對應我們平時開發阿里雲應用的時候的密鑰,可以登錄阿里雲后台獲取,由於這是比較私密的信息,所以我們用 Secret 對象來創建:
$ kubectl create secret generic traefik-alidns --from-literal=ALICLOUD_ACCESS_KEY=<aliyun ak> --from-literal=ALICLOUD_SECRET_KEY=<aliyun sk>--from-literal=ALICLOUD_REGION_ID=cn-beijing -n traefik-ingress
修改Traefik的my-value.yaml,如下:
...... additionalArguments: - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true" - "--certificatesresolvers.coolops.acme.email=coolops@163.com" - "--certificatesresolvers.coolops.acme.storage=/data/acme.json" - "--certificatesresolvers.coolops.acme.dnschallenge=true" - "--certificatesResolvers.coolops.acme.dnsChallenge.provider=alidns" envFrom: - secretRef: name: traefik-alidns
更新Traefik
過后,然后再創建一個ingressRoute
進行測試,YAML文件如下(由於coolops.cn不在阿里雲上,所以換了一個域名):
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route-auto-tls-dns spec: entryPoints: - websecure routes: - match: Host(`whoami6.coolops.cn`) kind: Rule services: - name: whoami port: 80 tls: certResolver: coolops domains: - main: "*.coolops.cn"
然后訪問域名后,就可以看到證書簽署 成功,如下:

中間件的使用
在介紹Traefik
的核心概念的時候有提到一個請求匹配Rules
后,會經過一系列的Middleware
,再到具體的Services
上。這個Middleware
是什么呢?

image.png
Middleware
是Traefik 2.0
之后新增的功能,用戶可以根據不通的需求來選擇不同的Middleware來滿足服務,提高了定制化的能力。
Traefik內置了很多不同功能的Middleware,主要是針對HTTP和TCP,HTTP占大部分[9],這里挑選幾個比較常用的進行演示。
強制跳轉HTTPS
強制跳轉HTTPS是經常會配置的功能,這里還是以上沒的whoami
應用為例。
1、創建一個HTTPS的ingressRoute
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route-auto-tls spec: entryPoints: - websecure routes: - match: Host(`whoami3.coolops.cn`) kind: Rule services: - name: whoami port: 80 tls: certResolver: coolops
2、定義一個跳轉HTTPS的中間件
這里會用到RedirectScheme
的內置中間件,配置如下:
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: redirect-https-middleware spec: redirectScheme: scheme: https
3、定義一個HTTP的ingressRoute,並使用Middleware
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami3-route spec: entryPoints: - web routes: - match: Host(`whoami3.coolops.cn`) kind: Rule services: - name: whoami port: 80 middlewares: - name: redirect-https-middleware
然后訪問http://whoami3.coolops.cn
就會被強制跳轉到https://whoami3.coolops.cn
。

去除請求路徑前綴
有時候會遇到這么一個需求:
- 只有一個域名
- 相通過這個域名訪問不同的應用
這種需求是非常常見的,在NGINX
中,我們可以配置多個Location
來定制規則,使用Traefik
也可以這么做。
但是定制不同的前綴后,由於應用本身並沒有這些前綴,導致請求返回404
,這時候我們就需要對請求的path
進行處理,還是以whoami
應用為例。
1、創建一個帶前綴的ingressRoute
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami7-route spec: entryPoints: - web routes: - match: Host(`whoami7.coolops.cn`) && PathPrefix('/coolops') kind: Rule services: - name: whoami port: 80
我們現在訪問是會返回404
狀態的。

2、定義去除前綴的中間件
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: prefix-coolops-url-middleware spec: stripPrefix: prefixes: - /coolops
3、修改上面的ingressRoute,應用中間件
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami7-route spec: entryPoints: - web routes: - match: Host(`whoami7.coolops.cn`) && PathPrefix('/coolops') kind: Rule services: - name: whoami port: 80 middlewares: - name: prefix-coolops-url-middleware
然后就可以正常訪問了。
添加IP白名單
在工作中,有一些URL並不希望對外暴露,比如prometheus、grafana等的url,這時候我們希望通過白名單IP來達到需求,就可以使用Traefik
中的ipWhiteList
中間件來完成。
1、定義白名單IP的中間件
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: ip-white-list-middleware spec: ipWhiteList: sourceRange: - 127.0.0.1/32 - 192.168.100.180
然后將中間件應用到對應的Rules上,就可以完成白名單功能。
除了上面的功能,Traefik內置Middleware還支持很多其他功能,比如限流、認證鑒權等,可以通過引用【9】進行查看。
暴露TCP服務
Traefik 2.0支持暴露TCP,這里以Redis為例。
1、部署一個Redis服務
apiVersion: apps/v1 kind: Deployment metadata: name: redis spec: selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis:5.0.14 ports: - containerPort: 6379 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: redis spec: ports: - port: 6379 targetPort: 6379 selector: app: redis
2、暴露Redis端口
暴露TCP端口使用的是SNI【10】,而SNI又是依賴TLS的,所以我們需要配置證書才行,但是如果沒有證書的話,我們可以使用通配符*
進行配置。
(1)、添加一個redis的entrypoints
修改Traefik
的部署文件my-value.yaml
,添加如下內容:
ports:
traefik: port: 9000 expose: true web: port: 8000 hostPort: 80 expose: true websecure: port: 8443 hostPort: 443 expose: true redis: port: 6379 containerPort: 6379 hostPort: 6379 additionalArguments: - "--entryPoints.redis.address=:6379" - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true" - "--certificatesresolvers.coolops.acme.email=coolops@163.com" - "--certificatesresolvers.coolops.acme.storage=/data/acme.json" - "--certificatesresolvers.coolops.acme.httpchallenge=true" - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web"
在啟動參數中添加--entryPoints.redis.address=:6379
用來指定entrypoint。
(2)、創建ingressRoute進行對外暴露
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRouteTCP metadata: name: redis-traefik-tcp spec: entryPoints: - redis routes: - match: HostSNI(`*`) services: - name: redis port: 6379
然后可以使用客戶端工具進行Redis的操作了。
# redis-cli -h redis.coolops.cn redis.coolops.cn:6379> set a b OK redis.coolops.cn:6379> get a "b" redis.coolops.cn:6379>
灰度發布
Traefik2.0 以后的一個更強大的功能就是灰度發布,灰度發布我們有時候也會稱為金絲雀發布(Canary),主要就是讓一部分測試的服務也參與到線上去,經過測試觀察看是否符號上線要求。
假設一個應用現在運行着V1
版本,新的V2
版本需要上線,這時候我們需要在集群中部署好V2
版本,然后通過Traefik
提供的帶權重的輪詢(WRR)
來實現該功能。
1、部署appv1、appv2應用
appv1.yaml
--- apiVersion: apps/v1 kind: Deployment metadata: name: appv1 spec: selector: matchLabels: app: appv1 template: metadata: labels: use: test app: appv1 spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello v1 > /usr/share/nginx/html/index.html"] ports: - containerPort: 80 name: portv1 --- apiVersion: v1 kind: Service metadata: name: appv1 spec: selector: app: appv1 ports: - name: http port: 80 targetPort: portv1
appv2.yaml
--- apiVersion: apps/v1 kind: Deployment metadata: name: appv2 spec: selector: matchLabels: app: appv2 template: metadata: labels: use: test app: appv2 spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello v2 > /usr/share/nginx/html/index.html"] ports: - containerPort: 80 name: portv2 --- apiVersion: v1 kind: Service metadata: name: appv2 spec: selector: app: appv2 ports: - name: http port: 80 targetPort: portv2
2、創建TraefikService
在 Traefik2.1以后新增了一個 TraefikService
的 CRD 資源,我們可以直接利用這個對象來配置 WRR
。
apiVersion: traefik.containo.us/v1alpha1 kind: TraefikService metadata: name: app-wrr spec: weighted: services: - name: appv1 weight: 3 port: 80 kind: Service - name: appv2 weight: 1 port: 80 kind: Service
3、創建ingressRoute
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: app-ingressroute-canary spec: entryPoints: - web routes: - match: Host(`app.coolops.cn`) kind: Rule services: - name: app-wrr kind: TraefikService
注意:這里配置的不是Service
類型,而是TraefikService
。
然后就可以通過訪問http://app.coolops.cn
來校驗結果。

待V2
測試沒問題后,就可以將流量全切到V2
了。
流量復制
在Traefik 2.0
之后還引入了鏡像服務
[11],它可以將請求的流量按規則復制一份發送給其他服務,並且會忽略這部分請求的響應。
這個功能在做一些壓測或者問題復現的時候還是很有用。
這里依然以上沒的appv1和appv2為例進行簡單的演示。
1、創建TraefikService,定義復制規則
apiVersion: traefik.containo.us/v1alpha1 kind: TraefikService metadata: name: app-mirror spec: mirroring: name: appv1 port: 80 mirrors: - name: appv2 percent: 50 port: 80
上面定義的意思是將請求到appv1的50%請求復制到appv2。
2、創建ingressRoute,進行效果演示
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: app-ingressroute-mirror spec: entryPoints: - web routes: - match: Host(`mirror.coolops.cn`) kind: Rule services: - name: app-mirror kind: TraefikService
然后進行測試,效果如下:

發了4次請求,appv1可以正常接收4次請求,appv2可以收到2次請求,收到的響應是appv1的,並沒有appv2的響應。
Kubernetes Gateway API
我們在上面創建路由規則要么使用ingress
,要么使用ingressRoute
,其實在Traefik 2.4
以后支持Kubernetes Gateway API
[12]提供的CRD
方式創建路由規則。
什么是Gateway API?
Gateway API
【13】是一個由SIG-NETWORK
社區管理的開源項目。它是Kubernetes
中服務網絡模型的資源集合。這些資源(GatewayClass、Gateway、HTTPRoute、TCPRoute、Service)旨在通過表達式的、可擴展的和面向角色的接口來發展Kubernetes服務網絡,這些接口由許多供應商實現,並得到了廣泛的行業支持。

image.png
- GatewayClass:GatewayClass 是基礎結構提供程序定義的群集范圍的資源。此資源表示可以實例化的網關類。一般該資源是用於支持多個基礎設施提供商用途的,這里我們只部署一個即可。
- Gateway:Gateway 與基礎設施配置的生命周期是 1:1。當用戶創建網關時,GatewayClass 控制器會提供或配置一些負載平衡基礎設施。
- HTTPRoute:HTTPRoute 是一種網關 API 類型,用於指定 HTTP 請求從網關偵聽器到 API 對象(即服務)的路由行為。
使用Gateway API
1、安裝Gateway API 的CRD
Traefik Gateway provider 僅支持 v0.3.0 (v1alpha1).
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.3.0" \
| kubectl apply -f -
2、創建rbac,給traefik授權
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: gateway-role rules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - networking.x-k8s.io resources: - gatewayclasses - gateways - httproutes - tcproutes - tlsroutes verbs: - get - list - watch - apiGroups: - networking.x-k8s.io resources: - gatewayclasses/status - gateways/status - httproutes/status - tcproutes/status - tlsroutes/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: gateway-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: gateway-role subjects: - kind: ServiceAccount name: traefik namespace: traefik-ingress
2、Traefik開啟gateway api支持
修改my-value.yaml
文件,如下:
...... additionalArguments: - "--entryPoints.redis.address=:6379" - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true" - "--certificatesresolvers.coolops.acme.email=coolops@163.com" - "--certificatesresolvers.coolops.acme.storage=/data/acme.json" - "--certificatesresolvers.coolops.acme.httpchallenge=true" - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web" - "--experimental.kubernetesgateway" - "--providers.kubernetesgateway"
更新Traefik,命令如下:
helm upgrade traefik -n traefik-ingress -f my-value.yaml .
4、通過Gateway api的方式暴露traefik dashboard應用
(1)、創建GatewayClass
apiVersion: networking.x-k8s.io/v1alpha1 kind: GatewayClass metadata: name: traefik spec: controller: traefik.io/gateway-controller
(2)、創建gateway
apiVersion: networking.x-k8s.io/v1alpha1 kind: Gateway metadata: name: http-gateway namespace: traefik-ingress spec: gatewayClassName: traefik listeners: - protocol: HTTP port: 8000 routes: kind: HTTPRoute namespaces: from: All selector: matchLabels: app: traefik
(3)、創建HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1 kind: HTTPRoute metadata: name: whoami-gateway-api-route namespace: traefik-ingress labels: app: traefik spec: hostnames: - "traefik1.coolops.cn" rules: - matches: - path: type: Prefix value: / forwardTo: - serviceName: traefik port: 9000 weight: 1
(4)、現在就可以直接在瀏覽器訪問了

image.png
GatewayClass
在集群中可以只創建一個,然后Gateway
和HTTPRoute
是需要對應的。
比如我這里要暴露default命名空間下的whoami應用,YAML就應該如下:
apiVersion: networking.x-k8s.io/v1alpha1 kind: Gateway metadata: name: http-gateway spec: gatewayClassName: traefik listeners: - protocol: HTTP port: 8000 routes: kind: HTTPRoute namespaces: from: All selector: matchLabels: app: whoami --- apiVersion: networking.x-k8s.io/v1alpha1 kind: HTTPRoute metadata: name: whoami-gateway-api-route labels: app: whoami spec: hostnames: - "whoami8.coolops.cn" rules: - matches: - path: type: Prefix value: / forwardTo: - serviceName: whoami port: 80 weight: 1
最后
Traefik
是一個功能比較強大的邊緣網關,基本能滿足絕大部分的場景需求,而且還有Mesh
等工具,比較好用,有興趣的朋友可以到官網[14]進行學習,也歡迎交流。
最后,求關注。如果你還想看更多優質原創文章,歡迎關注我們的公眾號「運維開發故事」。
如果我的文章對你有所幫助,還請幫忙點贊、在看、轉發一下,你的支持會激勵我輸出更高質量的文章,非常感謝!
你還可以把我的公眾號設為「星標」,這樣當公眾號文章更新時,你會在第一時間收到推送消息,避免錯過我的文章更新。
我是 喬克,《運維開發故事》公眾號團隊中的一員,一線運維農民工,雲原生實踐者,這里不僅有硬核的技術干貨,還有我們對技術的思考和感悟,歡迎關注我們的公眾號,期待和你一起成長!
引用
[1] https://doc.traefik.io/traefik/ [2] https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml [3] https://doc.traefik.io/traefik/providers/kubernetes-crd/ [4] https://github.com/traefik/whoami [5] https://letsencrypt.org/zh-cn/ [6] https://doc.traefik.io/traefik/https/acme/ [7] https://doc.traefik.io/traefik/https/acme/#tlschallenge [8] https://go-acme.github.io/lego/dns/alidns/ [9] https://doc.traefik.io/traefik/middlewares/http/overview/ [10] https://doc.traefik.io/traefik/routing/routers/#configuring-tcp-routers [11] https://doc.traefik.io/traefik/routing/services/#mirroring-service [12] https://doc.traefik.io/traefik/providers/kubernetes-gateway/ [13] https://gateway-api.sigs.k8s.io/ [14] https://traefik.io/
本文分享自微信公眾號 - 運維開發故事(mygsdcsf),作者:喬克
原文出處及轉載信息見文內詳細說明,如有侵權,請聯系 yunjia_community@tencent.com 刪除。