還不會 Traefik?看完這篇文章,你就徹底搞懂了~
大家好,我是喬克。
提到 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 等;並且可以同時處理許多集羣。
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
是什麼呢?
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 服務網絡,這些接口由許多供應商實現,並得到了廣泛的行業支持。
-
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)、現在就可以直接在瀏覽器訪問了
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] 進行學習,也歡迎交流。
最後,求關注。如果你還想看更多優質原創文章,歡迎關注我們的公衆號「運維開發故事」。
如果我的文章對你有所幫助,還請幫忙點贊、在看、轉發一下,你的支持會激勵我輸出更高質量的文章,非常感謝!
來源:本文轉自公衆號 “運維開發故事”,點擊查看原文。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/wfBfQ0pzhNh7-A31aPIG6A