灰度发布
Traefik2.0 以后的一个更强大的功能就是灰度发布,灰度发布我们有时候也会称为金丝雀发布(Canary),主要就是让一部分测试的服务也参与到线上去,经过测试观察看是否符号上线要求。
假设一个应用现在运行着V1
版本,新的V2
版本需要上线,这时候我们需要在集群中部署好V2
版本,然后通过Traefik
提供的带权重的轮询(WRR)
来实现该功能。
1、部署appv1、appv2应用
appv1.yaml
--- apiVersion: apps/v1 kind: Deployment metadata: name: appv1 spec: selector: matchLabels: app: appv1 template: metadata: labels: use: test app: appv1 spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello v1 > /usr/share/nginx/html/index.html"] ports: - containerPort: 80 name: portv1 --- apiVersion: v1 kind: Service metadata: name: appv1 spec: selector: app: appv1 ports: - name: http port: 80 targetPort: portv1
appv2.yaml
--- apiVersion: apps/v1 kind: Deployment metadata: name: appv2 spec: selector: matchLabels: app: appv2 template: metadata: labels: use: test app: appv2 spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello v2 > /usr/share/nginx/html/index.html"] ports: - containerPort: 80 name: portv2 --- apiVersion: v1 kind: Service metadata: name: appv2 spec: selector: app: appv2 ports: - name: http port: 80 targetPort: portv2
2、创建TraefikService
在 Traefik2.1以后新增了一个 TraefikService
的 CRD 资源,我们可以直接利用这个对象来配置 WRR
。
apiVersion: traefik.containo.us/v1alpha1 kind: TraefikService metadata: name: app-wrr spec: weighted: services: - name: appv1 weight: 3 port: 80 kind: Service - name: appv2 weight: 1 port: 80 kind: Service
3、创建ingressRoute
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: app-ingressroute-canary spec: entryPoints: - web routes: - match: Host(`app.coolops.cn`) kind: Rule services: - name: app-wrr kind: TraefikService
注意:这里配置的不是Service
类型,而是TraefikService
。
然后就可以通过访问http://app.coolops.cn
来校验结果。
待V2
测试没问题后,就可以将流量全切到V2
了。
流量复制
在Traefik 2.0
之后还引入了镜像服务
[11],它可以将请求的流量按规则复制一份发送给其他服务,并且会忽略这部分请求的响应。
这个功能在做一些压测或者问题复现的时候还是很有用。
这里依然以上没的appv1和appv2为例进行简单的演示。
1、创建TraefikService,定义复制规则
apiVersion: traefik.containo.us/v1alpha1 kind: TraefikService metadata: name: app-mirror spec: mirroring: name: appv1 port: 80 mirrors: - name: appv2 percent: 50 port: 80
上面定义的意思是将请求到appv1的50%请求复制到appv2。
2、创建ingressRoute,进行效果演示
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: app-ingressroute-mirror spec: entryPoints: - web routes: - match: Host(`mirror.coolops.cn`) kind: Rule services: - name: app-mirror kind: TraefikService
然后进行测试,效果如下:
发了4次请求,appv1可以正常接收4次请求,appv2可以收到2次请求,收到的响应是appv1的,并没有appv2的响应。
Kubernetes Gateway API
我们在上面创建路由规则要么使用ingress
,要么使用ingressRoute
,其实在Traefik 2.4
以后支持Kubernetes Gateway API
[12]提供的CRD
方式创建路由规则。
什么是Gateway API?
Gateway API
【13】是一个由SIG-NETWORK
社区管理的开源项目。它是Kubernetes
中服务网络模型的资源集合。这些资源(GatewayClass、Gateway、HTTPRoute、TCPRoute、Service)旨在通过表达式的、可扩展的和面向角色的接口来发展Kubernetes服务网络,这些接口由许多供应商实现,并得到了广泛的行业支持。
- GatewayClass:GatewayClass 是基础结构提供程序定义的群集范围的资源。此资源表示可以实例化的网关类。一般该资源是用于支持多个基础设施提供商用途的,这里我们只部署一个即可。
- Gateway:Gateway 与基础设施配置的生命周期是 1:1。当用户创建网关时,GatewayClass 控制器会提供或配置一些负载平衡基础设施。
- HTTPRoute:HTTPRoute 是一种网关 API 类型,用于指定 HTTP 请求从网关侦听器到 API 对象(即服务)的路由行为。
使用Gateway API
1、安装Gateway API 的CRD
Traefik Gateway provider 仅支持 v0.3.0 (v1alpha1).
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.3.0" \ | kubectl apply -f -
2、创建rbac,给traefik授权
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: gateway-role rules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - networking.x-k8s.io resources: - gatewayclasses - gateways - httproutes - tcproutes - tlsroutes verbs: - get - list - watch - apiGroups: - networking.x-k8s.io resources: - gatewayclasses/status - gateways/status - httproutes/status - tcproutes/status - tlsroutes/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: gateway-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: gateway-role subjects: - kind: ServiceAccount name: traefik namespace: traefik-ingress
2、Traefik开启gateway api支持
修改my-value.yaml
文件,如下:
...... additionalArguments: - "--entryPoints.redis.address=:6379" - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true" - "--certificatesresolvers.coolops.acme.email=coolops@163.com" - "--certificatesresolvers.coolops.acme.storage=/data/acme.json" - "--certificatesresolvers.coolops.acme.httpchallenge=true" - "--certificatesresolvers.coolops.acme.httpchallenge.entrypoint=web" - "--experimental.kubernetesgateway" - "--providers.kubernetesgateway"
更新Traefik,命令如下:
helm upgrade traefik -n traefik-ingress -f my-value.yaml .
4、通过Gateway api的方式暴露traefik dashboard应用
(1)、创建GatewayClass
apiVersion: networking.x-k8s.io/v1alpha1 kind: GatewayClass metadata: name: traefik spec: controller: traefik.io/gateway-controller
(2)、创建gateway
apiVersion: networking.x-k8s.io/v1alpha1 kind: Gateway metadata: name: http-gateway namespace: traefik-ingress spec: gatewayClassName: traefik listeners: - protocol: HTTP port: 8000 routes: kind: HTTPRoute namespaces: from: All selector: matchLabels: app: traefik
(3)、创建HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1 kind: HTTPRoute metadata: name: whoami-gateway-api-route namespace: traefik-ingress labels: app: traefik spec: hostnames: - "traefik1.coolops.cn" rules: - matches: - path: type: Prefix value: / forwardTo: - serviceName: traefik port: 9000 weight: 1
(4)、现在就可以直接在浏览器访问了
GatewayClass
在集群中可以只创建一个,然后Gateway
和HTTPRoute
是需要对应的。
比如我这里要暴露default命名空间下的whoami应用,YAML就应该如下:
apiVersion: networking.x-k8s.io/v1alpha1 kind: Gateway metadata: name: http-gateway spec: gatewayClassName: traefik listeners: - protocol: HTTP port: 8000 routes: kind: HTTPRoute namespaces: from: All selector: matchLabels: app: whoami --- apiVersion: networking.x-k8s.io/v1alpha1 kind: HTTPRoute metadata: name: whoami-gateway-api-route labels: app: whoami spec: hostnames: - "whoami8.coolops.cn" rules: - matches: - path: type: Prefix value: / forwardTo: - serviceName: whoami port: 80 weight: 1
最后
Traefik
是一个功能比较强大的边缘网关,基本能满足绝大部分的场景需求,而且还有Mesh
等工具,比较好用,有兴趣的朋友可以到官网[14]进行学习,也欢迎交流。