Traefik mesh:更簡單的服務(wù)網(wǎng)格
Traefik mesh是一款輕量級的服務(wù)網(wǎng)格,它簡單易行,易于安裝并且易于使用。
Traefik mesh建立在Traefik之上,適合于符合最新網(wǎng)絡(luò)接口規(guī)范SMI的Kubernetes集群。
Traefik mesh的最大特點就是非侵入性,也就是使用Traefik mesh并不會改變你現(xiàn)有的Kubernetes對象。
非侵入性服務(wù)網(wǎng)格
Traefik mesh不使用任何sidecar模式,其路由處理是通過運行在每個節(jié)點的proxy完成。網(wǎng)格控制器也是通過單獨的Pod運行,負(fù)責(zé)處理代理節(jié)點的所有配置分析和部署。
使用Traefik mesh之后,其邏輯如下。
Traefik mesh沒有通過sidecar的形式進行流量攔截或者修改,那是怎么實現(xiàn)的呢?
它其實是借助于CoreDNS,它通過修改CoreDNS的少量配置,讓用于允許使用Mesh端點而不是標(biāo)準(zhǔn)的Kubernetes端點,Mesh端點和用于服務(wù)并行運行,用戶可以選擇是否使用它。
安裝
- 前提:
- Kubernetes 1.11+
- CoreDNS 1.3+
- Helm v3
Traefik mesh的安裝很簡單,使用Helm即可實現(xiàn)快速的安裝。
(1)添加Helm倉庫
- helm repo add traefik-mesh https://helm.traefik.io/mesh
- helm repo update
(2)下載Chart包
- helm pull traefik-mesh/traefik-mesh
(3)解壓Chart包
- tar xf traefik-mesh-3.0.6.tgz
Traefik mesh會部署4個服務(wù),它們分別是:
- controller:Mesh的控制器,負(fù)責(zé)代理節(jié)點的所有配置分析和配置
- proxy:Mesh的代理,負(fù)責(zé)處理每個節(jié)點的流量代理
- tracing:跟蹤配置
- metrics:監(jiān)控配置
(4)安裝traefik mesh
- helm install traefik-mesh .
traefik mesh需要coredns的配合,主要改動部分如下:
- #### Begin Maesh Block
- maesh:53 {
- errors
- rewrite continue {
- name regex ([a-zA-Z0-9-_]*)\.([a-zv0-9-_]*)\.maesh default-{1}-6d61657368-{2}.default.svc.cluster.local
- answer name default-([a-zA-Z0-9-_]*)-6d61657368-([a-zA-Z0-9-_]*)\.default\.svc\.cluster\.local {1}.{2}.maesh
- }
- kubernetes cluster.local in-addr.arpa ip6.arpa {
- pods insecure
- upstream
- fallthrough in-addr.arpa ip6.arpa
- }
- forward . /etc/resolv.conf
- cache 30
- loop
- reload
- loadbalance
- }
- #### End Maesh Block
- #### Begin Traefik Mesh Block
- traefik.mesh:53 {
- errors
- rewrite continue {
- name regex ([a-zA-Z0-9-_]*)\.([a-zv0-9-_]*)\.traefik.mesh default-{1}-6d61657368-{2}.default.svc.cluster.local
- answer name default-([a-zA-Z0-9-_]*)-6d61657368-([a-zA-Z0-9-_]*)\.default\.svc\.cluster\.local {1}.{2}.traefik.mesh
- }
- kubernetes cluster.local in-addr.arpa ip6.arpa {
- pods insecure
- upstream
- fallthrough in-addr.arpa ip6.arpa
- }
- forward . /etc/resolv.conf
- cache 30
- loop
- reload
- loadbalance
- }
- #### End Traefik Mesh Block
如果在部署過程中,coredns報以下錯誤:
- plugin/forward: this plugin can only be used once per Server Block
請檢查coredns的configMap配置,看DNS下是否有兩個forward。
配置
Traefik mesh的配置分為靜態(tài)配置和動態(tài)配置。
靜態(tài)配置
- 可以手動指定controller鏡像版本和Traefik鏡像版本
- 可以配置controller和proxies的日志級別和格式
- 可以配置mesh的模式,默認(rèn)是HTTP
- 可以打開tracing功能
- 可以開啟ACL權(quán)限控制功能,這配置了 Traefik 網(wǎng)格以 ACL 模式運行,除非通過 SMI流量目標(biāo)明確允許,否則禁止所有流量
動態(tài)配置
在Kubernetes service上使用annotations 和 SMI 對象可向 Traefik Mesh 提供動態(tài)配置。支持的動態(tài)配置參數(shù)主要有:
- Traffic-Type
- Scheme
- Retry
- Circuit-Breaker
- Rate-Limit
- Traffic-Split
- Traffic-Targe
這里簡單介紹如何在Kubernetes的service中使用annotations進行配置。
(1)Traffic-Type主要用于配置流量類型,可以配置tcp,udp,http三種類型,如果沒有配置,默認(rèn)使用http類型,配置如下:
- mesh.traefik.io/traffic-type: "http"
(2)Scheme主要配置請求的協(xié)議,可以配置http,https,h2c三種類型,配置如下:
- mesh.traefik.io/scheme: "h2c"
(3)Retry主要配置重試次數(shù),當(dāng)網(wǎng)絡(luò)等異常情況下,會根據(jù)用戶配置發(fā)起幾次重試,如果還是失敗,則返回失敗,配置如下:
- mesh.traefik.io/retry-attempts: "2"
(4)Cricuit break主要用于配置斷開流量轉(zhuǎn)發(fā),當(dāng)系統(tǒng)處于健康的情況下,默認(rèn)是關(guān)閉的,如果系統(tǒng)異常,則會打開,不再轉(zhuǎn)發(fā)流量到異常的系統(tǒng)中,配置如下:
- mesh.traefik.io/circuit-breaker-expression: "Expression"
(5)Rate limit主要用于配置限流,單位是請求次數(shù)/秒,可以配置平均請求和突發(fā)請求,配置如下:
- mesh.traefik.io/ratelimit-average: "100"
- mesh.traefik.io/ratelimit-burst: "200"
(6)Access control主要用于配置權(quán)限控制,可以配置應(yīng)用允許哪些客戶端訪問。比如定義如下路由:
- ---
- apiVersion: specs.smi-spec.io/v1alpha3
- kind: HTTPRouteGroup
- metadata:
- name: server-routes
- namespace: server
- spec:
- matches:
- - name: api
- pathRegex: /api
- methods: ["*"]
- - name: metrics
- pathRegex: /metrics
- methods: ["GET"]
它表示可以通過任何方法訪問/api路徑,只允許使用GET方法訪問/metrics路徑。定義好路由還不夠,在默認(rèn)情況下,所有的流量都會被拒絕訪問,如果要授予客戶端訪問權(quán)限,需要配置TrafficTarget,如下:
- ---
- apiVersion: access.smi-spec.io/v1alpha2
- kind: TrafficTarget
- metadata:
- name: client-server-target
- namespace: server
- spec:
- destination:
- kind: ServiceAccount
- name: server
- namespace: server
- rules:
- - kind: HTTPRouteGroup
- name: server-routes
- matches:
- - api
- sources:
- - kind: ServiceAccount
- name: client
- namespace: client
該配置表示允許運行在client namespace下的具有sa為client的所有pod訪問api路由。
(7)Traffic Split主要用于流量拆分,特別是在做金絲雀發(fā)布的時候特別有用,比如如下配置:
- apiVersion: split.smi-spec.io/v1alpha3
- kind: TrafficSplit
- metadata:
- name: server-split
- namespace: server
- spec:
- service: server
- backends:
- - service: server-v1
- weight: 80
- - service: server-v2
- weight: 20
其表示將80%的流量轉(zhuǎn)發(fā)到server-v1,20%的流量轉(zhuǎn)發(fā)到server-v2。
例子
上面已經(jīng)安裝部署好Traefik mesh,下面以官方的例子來進行簡單的測試。(1)部署應(yīng)用
- apiVersion: v1
- kind: Namespace
- metadata:
- name: whoami
- ---
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: whoami-server
- namespace: whoami
- ---
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: whoami-client
- namespace: whoami
- ---
- kind: Deployment
- apiVersion: apps/v1
- metadata:
- name: whoami
- namespace: whoami
- spec:
- replicas: 2
- selector:
- matchLabels:
- app: whoami
- template:
- metadata:
- labels:
- app: whoami
- spec:
- serviceAccount: whoami-server
- containers:
- - name: whoami
- image: traefik/whoami:v1.6.0
- imagePullPolicy: IfNotPresent
- ---
- kind: Deployment
- apiVersion: apps/v1
- metadata:
- name: whoami-tcp
- namespace: whoami
- spec:
- replicas: 2
- selector:
- matchLabels:
- app: whoami-tcp
- template:
- metadata:
- labels:
- app: whoami-tcp
- spec:
- serviceAccount: whoami-server
- containers:
- - name: whoami-tcp
- image: traefik/whoamitcp:v0.1.0
- imagePullPolicy: IfNotPresent
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: whoami
- namespace: whoami
- labels:
- app: whoami
- spec:
- type: ClusterIP
- ports:
- - port: 80
- name: whoami
- selector:
- app: whoami
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: whoami-tcp
- namespace: whoami
- labels:
- app: whoami-tcp
- spec:
- type: ClusterIP
- ports:
- - port: 8080
- name: whoami-tcp
- selector:
- app: whoami-tcp
- ---
- apiVersion: v1
- kind: Pod
- metadata:
- name: whoami-client
- namespace: whoami
- spec:
- serviceAccountName: whoami-client
- containers:
- - name: whoami-client
- image: giantswarm/tiny-tools:3.9
- command:
- - "sleep"
- - "3600"
上面部署了兩個應(yīng)用,一個http類型應(yīng)用,一個是tcp類型應(yīng)用。
可以通過以下命名查看應(yīng)用啟動情況kubectl get all -n whoami。
然后可以測試以下應(yīng)用連通性,如下:
- # kubectl -n whoami exec whoami-client -- curl -s whoami.whoami.svc.cluster.local
- Hostname: whoami-576cb59fd-qvnl7
- IP: 127.0.0.1
- IP: 172.16.235.193
- RemoteAddr: 172.16.7.181:33150
- GET / HTTP/1.1
- Host: whoami.whoami.svc.cluster.local
- User-Agent: curl/7.64.0
- Accept: */*
- # kubectl -n whoami exec -ti whoami-client -- nc whoami-tcp.whoami.svc.cluster.local 8080
- my data
- Received: my data
- Received:
- eee
- Received: eee
- eee
- Received: eee
如果現(xiàn)在要為上面的服務(wù)配置Traefik mesh,只需要更改這兩個服務(wù)的service,http類型應(yīng)用的service加mesh.traefik.io/traffic-type: "http"的annotations,tcp類型應(yīng)用的service加mesh.traefik.io/traffic-type: "tcp"的annotations,如下:
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: whoami
- namespace: whoami
- labels:
- app: whoami
- annotations:
- mesh.traefik.io/traffic-type: "http"
- mesh.traefik.io/retry-attempts: "2"
- spec:
- type: ClusterIP
- ports:
- - port: 80
- name: whoami
- selector:
- app: whoami
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: whoami-tcp
- namespace: whoami
- labels:
- app: whoami-tcp
- annotations:
- mesh.traefik.io/traffic-type: "tcp"
- spec:
- type: ClusterIP
- ports:
- - port: 8080
- name: whoami-tcp
- selector:
- app: whoami-tcp
現(xiàn)在訪問服務(wù),只需將svc.cluster.local改為traefik.mesh即可。比如之前訪問方式如下:
- kubectl -n whoami exec whoami-client -- curl -s whoami.whoami.svc.cluster.local
加了traefik mesh之后,即為:
- kubectl -n whoami exec whoami-client -- curl -s whoami.whoami.traefik.mesh
當(dāng)然之前的訪問方式依然存在,用什么樣的方式由用戶自己決定。
腳注
【1】https://traefik.io/traefik/
【2】https://smi-spec.io/
【3】https://coredns.io/