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仓库

  1. helm repo add traefik-mesh https://helm.traefik.io/mesh 
  2. helm repo update 

(2)下载Chart包

  1. helm pull traefik-mesh/traefik-mesh 

(3)解压Chart包

  1. tar xf traefik-mesh-3.0.6.tgz 

Traefik mesh会部署4个服务,它们分别是:

  • controller:Mesh的控制器,负责代理节点的所有配置分析和配置
  • proxy:Mesh的代理,负责处理每个节点的流量代理
  • tracing:跟踪配置
  • metrics:监控配置

(4)安装traefik mesh

  1. helm install traefik-mesh . 

traefik mesh需要coredns的配合,主要改动部分如下:

  1. #### Begin Maesh Block 
  2. maesh:53 { 
  3.     errors 
  4.     rewrite continue { 
  5.         name regex ([a-zA-Z0-9-_]*)\.([a-zv0-9-_]*)\.maesh default-{1}-6d61657368-{2}.default.svc.cluster.local 
  6.         answer name default-([a-zA-Z0-9-_]*)-6d61657368-([a-zA-Z0-9-_]*)\.default\.svc\.cluster\.local {1}.{2}.maesh 
  7.     } 
  8.     kubernetes cluster.local in-addr.arpa ip6.arpa { 
  9.         pods insecure 
  10.         upstream 
  11.         fallthrough in-addr.arpa ip6.arpa 
  12.     } 
  13.     forward . /etc/resolv.conf 
  14.     cache 30 
  15.     loop 
  16.     reload 
  17.     loadbalance 
  18. #### End Maesh Block 
  19.  
  20. #### Begin Traefik Mesh Block 
  21. traefik.mesh:53 { 
  22.     errors 
  23.     rewrite continue { 
  24.         name regex ([a-zA-Z0-9-_]*)\.([a-zv0-9-_]*)\.traefik.mesh default-{1}-6d61657368-{2}.default.svc.cluster.local 
  25.         answer name default-([a-zA-Z0-9-_]*)-6d61657368-([a-zA-Z0-9-_]*)\.default\.svc\.cluster\.local {1}.{2}.traefik.mesh 
  26.     } 
  27.     kubernetes cluster.local in-addr.arpa ip6.arpa { 
  28.         pods insecure 
  29.         upstream 
  30.         fallthrough in-addr.arpa ip6.arpa 
  31.     } 
  32.     forward . /etc/resolv.conf 
  33.     cache 30 
  34.     loop 
  35.     reload 
  36.     loadbalance 
  37. #### End Traefik Mesh Block 

如果在部署过程中,coredns报以下错误:

  1. 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类型,配置如下:

  1. mesh.traefik.io/traffic-type: "http" 

(2)Scheme主要配置请求的协议,可以配置http,https,h2c三种类型,配置如下:

  1. mesh.traefik.io/scheme: "h2c" 

(3)Retry主要配置重试次数,当网络等异常情况下,会根据用户配置发起几次重试,如果还是失败,则返回失败,配置如下:

  1. mesh.traefik.io/retry-attempts: "2" 

(4)Cricuit break主要用于配置断开流量转发,当系统处于健康的情况下,默认是关闭的,如果系统异常,则会打开,不再转发流量到异常的系统中,配置如下:

  1. mesh.traefik.io/circuit-breaker-expression: "Expression" 

(5)Rate limit主要用于配置限流,单位是请求次数/秒,可以配置平均请求和突发请求,配置如下:

  1. mesh.traefik.io/ratelimit-average: "100" 
  2. mesh.traefik.io/ratelimit-burst: "200" 

(6)Access control主要用于配置权限控制,可以配置应用允许哪些客户端访问。比如定义如下路由:

  1. --- 
  2. apiVersion: specs.smi-spec.io/v1alpha3 
  3. kind: HTTPRouteGroup 
  4. metadata: 
  5.   name: server-routes 
  6.   namespace: server 
  7. spec: 
  8.   matches: 
  9.     - name: api 
  10.       pathRegex: /api 
  11.       methods: ["*"] 
  12.     - name: metrics 
  13.       pathRegex: /metrics 
  14.       methods: ["GET"] 

它表示可以通过任何方法访问/api路径,只允许使用GET方法访问/metrics路径。定义好路由还不够,在默认情况下,所有的流量都会被拒绝访问,如果要授予客户端访问权限,需要配置TrafficTarget,如下:

  1. --- 
  2. apiVersion: access.smi-spec.io/v1alpha2 
  3. kind: TrafficTarget 
  4. metadata: 
  5.   name: client-server-target 
  6.   namespace: server 
  7. spec: 
  8.   destination: 
  9.     kind: ServiceAccount 
  10.     name: server 
  11.     namespace: server 
  12.   rules: 
  13.     - kind: HTTPRouteGroup 
  14.       name: server-routes 
  15.       matches: 
  16.         - api 
  17.   sources: 
  18.     - kind: ServiceAccount 
  19.       name: client 
  20.       namespace: client 

该配置表示允许运行在client namespace下的具有sa为client的所有pod访问api路由。

(7)Traffic Split主要用于流量拆分,特别是在做金丝雀发布的时候特别有用,比如如下配置:

  1. apiVersion: split.smi-spec.io/v1alpha3 
  2. kind: TrafficSplit 
  3. metadata: 
  4.   name: server-split 
  5.   namespace: server 
  6. spec: 
  7.   service: server 
  8.   backends: 
  9.     - service: server-v1 
  10.       weight: 80 
  11.     - service: server-v2 
  12.       weight: 20 

其表示将80%的流量转发到server-v1,20%的流量转发到server-v2。

例子

上面已经安装部署好Traefik mesh,下面以官方的例子来进行简单的测试。(1)部署应用

  1. apiVersion: v1 
  2. kind: Namespace 
  3. metadata: 
  4.   name: whoami 
  5.  
  6. --- 
  7. apiVersion: v1 
  8. kind: ServiceAccount 
  9. metadata: 
  10.   name: whoami-server 
  11.   namespace: whoami 
  12.  
  13. --- 
  14. apiVersion: v1 
  15. kind: ServiceAccount 
  16. metadata: 
  17.   name: whoami-client 
  18.   namespace: whoami 
  19. --- 
  20. kind: Deployment 
  21. apiVersion: apps/v1 
  22. metadata: 
  23.   name: whoami 
  24.   namespace: whoami 
  25. spec: 
  26.   replicas: 2 
  27.   selector: 
  28.     matchLabels: 
  29.       app: whoami 
  30.   template: 
  31.     metadata: 
  32.       labels: 
  33.         app: whoami 
  34.     spec: 
  35.       serviceAccount: whoami-server 
  36.       containers: 
  37.         - name: whoami 
  38.           image: traefik/whoami:v1.6.0 
  39.           imagePullPolicy: IfNotPresent 
  40.  
  41. --- 
  42. kind: Deployment 
  43. apiVersion: apps/v1 
  44. metadata: 
  45.   name: whoami-tcp 
  46.   namespace: whoami 
  47. spec: 
  48.   replicas: 2 
  49.   selector: 
  50.     matchLabels: 
  51.       app: whoami-tcp 
  52.   template: 
  53.     metadata: 
  54.       labels: 
  55.         app: whoami-tcp 
  56.     spec: 
  57.       serviceAccount: whoami-server 
  58.       containers: 
  59.         - name: whoami-tcp 
  60.           image: traefik/whoamitcp:v0.1.0 
  61.           imagePullPolicy: IfNotPresent 
  62.  
  63. --- 
  64. apiVersion: v1 
  65. kind: Service 
  66. metadata: 
  67.   name: whoami 
  68.   namespace: whoami 
  69.   labels: 
  70.     app: whoami 
  71. spec: 
  72.   type: ClusterIP 
  73.   ports: 
  74.     - port: 80 
  75.       name: whoami 
  76.   selector: 
  77.     app: whoami 
  78.  
  79. --- 
  80. apiVersion: v1 
  81. kind: Service 
  82. metadata: 
  83.   name: whoami-tcp 
  84.   namespace: whoami 
  85.   labels: 
  86.     app: whoami-tcp 
  87. spec: 
  88.   type: ClusterIP 
  89.   ports: 
  90.     - port: 8080 
  91.       name: whoami-tcp 
  92.   selector: 
  93.     app: whoami-tcp 
  94.  
  95. --- 
  96. apiVersion: v1 
  97. kind: Pod 
  98. metadata: 
  99.   name: whoami-client 
  100.   namespace: whoami 
  101. spec: 
  102.   serviceAccountName: whoami-client 
  103.   containers: 
  104.     - name: whoami-client 
  105.       image: giantswarm/tiny-tools:3.9 
  106.       command: 
  107.         - "sleep" 
  108.         - "3600" 

上面部署了两个应用,一个http类型应用,一个是tcp类型应用。

可以通过以下命名查看应用启动情况kubectl get all -n whoami。

然后可以测试以下应用连通性,如下:

  1. # kubectl -n whoami exec whoami-client -- curl -s whoami.whoami.svc.cluster.local 
  2. Hostname: whoami-576cb59fd-qvnl7 
  3. IP: 127.0.0.1 
  4. IP: 172.16.235.193 
  5. RemoteAddr: 172.16.7.181:33150 
  6. GET / HTTP/1.1 
  7. Host: whoami.whoami.svc.cluster.local 
  8. User-Agent: curl/7.64.0 
  9. Accept: */* 
  10.  
  11. # kubectl -n whoami exec -ti whoami-client -- nc whoami-tcp.whoami.svc.cluster.local 8080 
  12. my data 
  13. Received: my data 
  14.  
  15. Received:  
  16. eee 
  17. Received: eee 
  18. eee 
  19. Received: eee 

如果现在要为上面的服务配置Traefik mesh,只需要更改这两个服务的service,http类型应用的service加mesh.traefik.io/traffic-type: "http"的annotations,tcp类型应用的service加mesh.traefik.io/traffic-type: "tcp"的annotations,如下:

  1. --- 
  2. apiVersion: v1 
  3. kind: Service 
  4. metadata: 
  5.   name: whoami 
  6.   namespace: whoami 
  7.   labels: 
  8.     app: whoami 
  9.   annotations: 
  10.     mesh.traefik.io/traffic-type: "http" 
  11.     mesh.traefik.io/retry-attempts: "2" 
  12. spec: 
  13.   type: ClusterIP 
  14.   ports: 
  15.     - port: 80 
  16.       name: whoami 
  17.   selector: 
  18.     app: whoami 
  19.  
  20. --- 
  21. apiVersion: v1 
  22. kind: Service 
  23. metadata: 
  24.   name: whoami-tcp 
  25.   namespace: whoami 
  26.   labels: 
  27.     app: whoami-tcp 
  28.   annotations: 
  29.     mesh.traefik.io/traffic-type: "tcp" 
  30. spec: 
  31.   type: ClusterIP 
  32.   ports: 
  33.     - port: 8080 
  34.       name: whoami-tcp 
  35.   selector: 
  36.     app: whoami-tcp 

现在访问服务,只需将svc.cluster.local改为traefik.mesh即可。比如之前访问方式如下:

  1. kubectl -n whoami exec whoami-client -- curl -s whoami.whoami.svc.cluster.local 

加了traefik mesh之后,即为:

  1. kubectl -n whoami exec whoami-client -- curl -s whoami.whoami.traefik.mesh 

当然之前的访问方式依然存在,用什么样的方式由用户自己决定。

脚注

https://traefik.io/traefik/

https://smi-spec.io/

https://coredns.io/

相关内容