Traefik mesh_ 让服务网格更简单 原创

Traefik mesh是一款轻量级的服务网格,它简单易行,易于安装并且易于使用。
Traefik mesh建立在Traefik之上,适合于符合最新网络接口规范SMI的Kubernetes集群。
Traefik mesh的最大特点就是非侵入性,也就是使用Traefik mesh并不会改变你现有的Kubernetes对象。
非侵入性服务网格
Traefik mesh不使用任何sidecar模式,其路由处理是通过运行在每个节点的proxy完成。网格控制器也是通过单独的Pod运行,负责处理代理节点的所有配置分析和部署。
使用Traefik mesh之后,其逻辑如下。

Traefik mesh没有通过 sidecar 的形式进行流量拦截或者修改,哪是怎么实现的呢?
它其实是借助于CoreDNS,它通过修改CoreDNS的少量配置,让用于允许使用Mesh端点而不是标准的Kubernetes端点,Mesh端点和用于服务并行运行,用户可以选择是否使用它。
安装
前提:
Kubernetes 1.11+
CoreDNS 1.3+
Helm v3
Traefik mesh 的安装很简单,使用Helm即可实现快速的安装。
(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.tgzTraefik mesh 会部署 4 个服务,它们分别是:
- controller:Mesh 的控制器,负责代理节点的所有配置分析和配置
- proxy:Mesh 的代理,负责处理每个节点的流量代理
- tracing:跟踪配置
- metrics:监控配置
(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 的配置分为静态配置和动态配置。
静态配置
- 可以手动指定
controller镜像版本和Traefik镜像版本 - 可以配置
controller和proxies的日志级别和格式 - 可以配置
mesh的模式,默认是HTTP - 可以打开
tracing功能 - 可以开启
ACL权限控制功能,这配置了 Traefik 网格以 ACL 模式运行,除非通过 SMI流量目标明确允许,否则禁止所有流量
动态配置
- Traffic-Type
- Scheme
- Retry
- Circuit-Breaker
- Rate-Limit
- Traffic-Split
- Traffic-Targe
这里简单介绍如何在Kubernetes 的service中使用annotations进行配置。
(1)Traffic-Type 主要用于配置流量类型,可以配置 tcp,udp,http 三种类型,如果没有配置,默认使用 http 类型,配置如下:
mesh.traefik.io/traffic-type: "http"(2)Scheme 主要配置请求的协议,可以配置 http,https,h2c 三种类型,配置如下:
mesh.traefik.io/scheme: "h2c"(3)Retry 主要配置重试次数,当网络等异常情况下,会根据用户配置发起几次重试,如果还是失败,则返回失败,配置如下:
mesh.traefik.io/retry-attempts: "2"(4)Cricuit break 主要用于配置断开流量转发,当系统处于健康的情况下,默认是关闭的,如果系统异常,则会打开,不再转发流量到异常的系统中,配置如下:
mesh.traefik.io/circuit-breaker-expression: "Expression"(5)Rate limit 主要用于配置限流,单位是请求次数/秒,可以配置平均请求和突发请求,配置如下:
mesh.traefik.io/ratelimit-average: "100"
mesh.traefik.io/ratelimit-burst: "200"(6)Access control 主要用于配置权限控制,可以配置应用允许哪些客户端访问。
比如定义如下路由:
---
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 路径。定义好路由还不够,在默认情况下,所有的流量都会被拒绝访问,如果要授予客户端访问权限,需要配置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 主要用于流量拆分,特别是在做金丝雀发布的时候特别有用,比如如下配置:
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%的流量转发到 server-v1,20%的流量转发到 server-v2。
例子
上面已经安装部署好Traefik mesh,下面已官方的例子来进行简单的测试。
(1)部署应用
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"上面部署了两个应用,一个 http 类型应用,一个是 tcp 类型应用。
可以通过以下命名查看应用启动情况kubectl get all -n whoami。

然后可以测试以下应用连通性,如下:
# 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如果现在要为上面的服务配置 Traefik mesh,只需要更改这两个服务的 service,http 类型应用的 service 加mesh.traefik.io/traffic-type: "http"的 annotations,tcp 类型应用的 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现在访问服务,只需将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当然之前的访问方式依然存在,用什么样的方式由用户自己决定。