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仓库
helmrepoaddtraefik-meshhttps://helm.traefik.io/mesh helmrepoupdate
(2)下载Chart包
helmpulltraefik-mesh/traefik-mesh
(3)解压Chart包
tarxftraefik-mesh-3.0.6.tgz
Traefik mesh会部署4个服务,它们分别是:
- controller:Mesh的控制器,负责代理节点的所有配置分析和配置
- proxy:Mesh的代理,负责处理每个节点的流量代理
- tracing:跟踪配置
- metrics:监控配置
(4)安装traefik mesh
helminstalltraefik-mesh.
traefik mesh需要coredns的配合,主要改动部分如下:
####BeginMaeshBlock maesh:53{ errors rewritecontinue{ nameregex([a-zA-Z0-9-_]*)\.([a-zv0-9-_]*)\.maeshdefault-{1}-6d61657368-{2}.default.svc.cluster.local answernamedefault-([a-zA-Z0-9-_]*)-6d61657368-([a-zA-Z0-9-_]*)\.default\.svc\.cluster\.local{1}.{2}.maesh } kubernetescluster.localin-addr.arpaip6.arpa{ podsinsecure upstream fallthroughin-addr.arpaip6.arpa } forward./etc/resolv.conf cache30 loop reload loadbalance } ####EndMaeshBlock ####BeginTraefikMeshBlock traefik.mesh:53{ errors rewritecontinue{ nameregex([a-zA-Z0-9-_]*)\.([a-zv0-9-_]*)\.traefik.meshdefault-{1}-6d61657368-{2}.default.svc.cluster.local answernamedefault-([a-zA-Z0-9-_]*)-6d61657368-([a-zA-Z0-9-_]*)\.default\.svc\.cluster\.local{1}.{2}.traefik.mesh } kubernetescluster.localin-addr.arpaip6.arpa{ podsinsecure upstream fallthroughin-addr.arpaip6.arpa } forward./etc/resolv.conf cache30 loop reload loadbalance } ####EndTraefikMeshBlock
如果在部署过程中,coredns报以下错误:
plugin/forward:thisplugincanonlybeusedonceperServerBlock
请检查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-nwhoamiexecwhoami-client--curl-swhoami.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-nwhoamiexec-tiwhoami-client--ncwhoami-tcp.whoami.svc.cluster.local8080 mydata Received:mydata 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-nwhoamiexecwhoami-client--curl-swhoami.whoami.svc.cluster.local
加了traefik mesh之后,即为:
kubectl-nwhoamiexecwhoami-client--curl-swhoami.whoami.traefik.mesh
当然之前的访问方式依然存在,用什么样的方式由用户自己决定。
脚注
【1】https://traefik.io/traefik/
【2】https://smi-spec.io/
【3】https://coredns.io/
转载请注明:IT运维空间 » 运维技术 » Traefik mesh:更简单的服务网格
发表评论