今天智一面来跟大家聊聊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.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
配置
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)部署应用
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
当然之前的访问方式依然存在,用什么样的方式由用户自己决定。
运维工程师QQ交流群:580175957