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.tgz
Traefik 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 流量目标明确允许,否则禁止所有流量
动态配置
在 Kubernetes service 上使用 annotations 和 SMI 对象可向 Traefik Mesh 提供动态配置。支持的动态配置参数主要有:
- 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
当然之前的访问方式依然存在,用什么样的方式由用户自己决定。
脚注
【1】https://traefik.io/traefik/
【2】https://smi-spec.io/
【3】https://coredns.io/