traefik灰度发布、流量复制、会话保持

简介

在这里插入图片描述

traefik的路由规则就可以实现4层和7层的基本负载均衡操作,使用IngressRoute/IngressRouteTCP/IngressRouteUDP资源即可。但是如果想要实现加权轮询、流量复制等高级操作,traefik抽象出了一个TraefikService资源。此时整体流量走向为:外部流量先通过entryPoints端口进入traefik,然后由IngressRoute/IngressRouteTCP/IngressRouteUDP匹配后进入TraefikService,在TraefikService这一层实现加权轮循和流量复制,最后将请求转发至kubernetes的service。
除此之外traefik还支持7层的粘性会话、健康检查、传递请求头、响应转发、故障转移等操作。

加权轮询(灰度发布)

灰度发布我们有时候也会称为金丝雀发布(Canary),主要就是让一部分测试的服务也参与到线上去,经过测试观察看是否符合上线要求,在traefik中,通过调整生产与测试服务的权重,实现灰度发布的功能。
接下来配置加权轮循,仍然请求myapp.test.com,myapp1的负载权重为1,myapp2的负载权重为2。
参考文档:https://doc.traefik.io/traefik/routing/services/#weighted-round-robin-service
依旧是上面创建的两个deployment应用与对应的svc

[root@k8s-master udp]# kubectl get pod
NAME                                          READY   STATUS    RESTARTS   AGE
myapp1-795d947b45-9lsm6                       1/1     Running   1          25h
myapp2-6ffd54f76-ljkr9                        1/1     Running   1          25h
[root@k8s-master udp]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                 2d22h
myapp1       ClusterIP   10.104.91.200   <none>        80/TCP                                                                                   25h
myapp2       ClusterIP   10.111.245.32   <none>        80/TCP    

创建IngressRouter资源,配置域名为myapp.test.com,注意此时后端service配置TraefikService。

[root@k8s-master ingress]# cat myapp-ingress.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`myapp.test.com`)
    kind: Rule
    services:                     # 加权轮循时,后端service不再是k8s的service,而是traefik的TraefikService
    - name: wrr     
      namespace: default
      kind: TraefikService
[root@k8s-master ingress]# kubectl apply -f myapp-ingress.yaml 
ingressroute.traefik.containo.us/myapp created

创建TraefikService资源,名称与IngressRouter的TraefikService保持一致,services后端填写kubernetes的service,并指定权重。

[root@k8s-master ingress]# cat myapp-traefikService.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: wrr
  namespace: default

spec:
  weighted:
    services:
      - name: myapp1
        port: 80
        weight: 1
      - name: myapp2
        port: 80
        weight: 2
[root@k8s-master ingress]# kubectl apply -f myapp-traefikService.yaml 
traefikservice.traefik.containo.us/wrr unchanged

查看dashboard的配置信息,此时myapp2权重为2,myapp1权重为1。
在这里插入图片描述

客户端访问测试,验证无误。

[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

镜像复制(流量复制)

traefik还支持镜像复制功能,是一种可以将流入流量复制并同时将其发送给其他服务的方法,镜像服务可以获得给定百分比的请求同时也会忽略这部分请求的响应,在实际生产中主要用于测试场景以及问题复现bug定位。
参考文档:https://doc.traefik.io/traefik/routing/services/#mirroring-service
依旧是上面创建的两个deployment应用与对应的svc

[root@k8s-master udp]# kubectl get pod
NAME                                          READY   STATUS    RESTARTS   AGE
myapp1-795d947b45-9lsm6                       1/1     Running   1          25h
myapp2-6ffd54f76-ljkr9                        1/1     Running   1          25h
[root@k8s-master udp]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                 2d22h
myapp1       ClusterIP   10.104.91.200   <none>        80/TCP                                                                                   25h
myapp2       ClusterIP   10.111.245.32   <none>        80/TCP    

创建IngressRouter资源,配置域名为myapp.test.com,注意此时后端service配置TraefikService。

[root@k8s-master ingress]# cat myapp-ingress.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`myapp.test.com`)
    kind: Rule
    services:                     # 流量复制时,后端service不再是k8s的service,而是traefik的TraefikService
    - name: mirror   
      namespace: default
      kind: TraefikService
[root@k8s-master ingress]# kubectl apply -f myapp-ingress.yaml 
ingressroute.traefik.containo.us/myapp created

创建TraefikService资源,名称与IngressRouter的TraefikService保持一致,services后端填写kubernetes的service,并设置复制流量比例。

[root@k8s-master ingress]# cat myapp-traefikService.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: mirror
  namespace: default

spec:
  mirroring:      # 所有流量全部请求到k8s的myapp1
    name: myapp1
    port: 80
    mirrors:      # 同时复制50%的请求到k8s的myapp2  
    - name: myapp2
      port: 80
      percent: 50
[root@k8s-master ingress]# kubectl apply -f myapp-traefikService.yaml 
traefikservice.traefik.containo.us/mirror created

查看dashboard的配置信息,此时myapp2类型为mirroring,比例为50%
在这里插入图片描述

客户端访问测试,只响应了myapp1的内容。

[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

查看myapp1和myapp2的日志,发现有请求日志符合预期。

[root@k8s-master ingress]# kubectl logs myapp1-795d947b45-9lsm6 
10.244.0.0 - - [25/Sep/2022:08:45:33 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.61.1" "192.168.93.1"
10.244.0.0 - - [25/Sep/2022:08:45:35 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.61.1" "192.168.93.1"
10.244.0.0 - - [25/Sep/2022:08:45:36 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.61.1" "192.168.93.1"
10.244.0.0 - - [25/Sep/2022:09:45:38 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.61.1" "192.168.93.1"
[root@k8s-master ingress]# kubectl logs myapp2-6ffd54f76-ljkr9 
10.244.0.0 - - [25/Sep/2022:08:45:33 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.61.1" "192.168.93.1"
10.244.0.0 - - [25/Sep/2022:08:45:36 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.61.1" "192.168.93.1"

粘性会话(会话保持)

当我们使用traefik的负载均衡时,默认情况下轮循多个k8s的service服务,如果用户对同一内容的多次请求,可能被转发到了不同的后端服务器。假设用户发出请求被分配至服务器A,保存了一些信息在session中,该用户再次发送请求被分配到服务器B,要用之前保存的信息,若服务器A和B之间没有session粘滞,那么服务器B就拿不到之前的信息,这样会导致一些问题。traefik同样也支持粘性会话,可以让用户在一次会话周期内的所有请求始终转发到一台特定的后端服务器上。
参考文档:https://doc.traefik.io/traefik/routing/services/#servers
依旧是上面创建的两个deployment应用与对应的svc

[root@k8s-master udp]# kubectl get pod
NAME                                          READY   STATUS    RESTARTS   AGE
myapp1-795d947b45-9lsm6                       1/1     Running   1          25h
myapp2-6ffd54f76-ljkr9                        1/1     Running   1          25h
[root@k8s-master udp]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                 2d22h
myapp1       ClusterIP   10.104.91.200   <none>        80/TCP                                                                                   25h
myapp2       ClusterIP   10.111.245.32   <none>        80/TCP    

创建IngressRouter资源,配置域名为myapp.test.com,注意此时后端service配置TraefikService。

[root@k8s-master ingress]# cat myapp-ingress.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`myapp.test.com`)
    kind: Rule
    services:                     # 粘性会话依赖加权轮循,后端service不再是k8s的service,而是traefik的TraefikService
    - name: wrr  
      namespace: default
      kind: TraefikService
[root@k8s-master ingress]# kubectl apply -f myapp-ingress.yaml 
ingressroute.traefik.containo.us/myapp created

创建TraefikService资源,名称与IngressRouter的TraefikService保持一致,services后端填写kubernetes的service,并指定权重。

[root@k8s-master ingress]# cat myapp-traefikService.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: wrr
  namespace: default

spec:
  weighted:
    services:
      - name: myapp1
        kind: Service
        port: 80
        weight: 1
      - name: myapp2
        kind: Service
        weight: 2
        port: 80
    sticky:                 # 开启粘性会话
      cookie:               # 基于cookie区分客户端
        name: lvl1          # 指定客户端请求时,包含的cookie名称
[root@k8s-master ingress]# kubectl apply -f myapp-traefikService.yaml 
traefikservice.traefik.containo.us/wrr unchanged

客户端携带cookie信息访问测试。

# lvl1为default-myapp2-80的请求全部由myapp2响应
[root@tiaoban ~]# curl -b "lvl1=default-myapp2-80" http://myapp.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl -b "lvl1=default-myapp2-80" http://myapp.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
# lvl1为default-myapp1-80的请求全部由myapp1响应
[root@tiaoban ~]# curl -b "lvl1=default-myapp1-80" http://myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@tiaoban ~]# curl -b "lvl1=default-myapp1-80" http://myapp.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

查看更多

微信公众号

微信公众号同步更新,欢迎关注微信公众号第一时间获取最近文章。在这里插入图片描述

博客网站

崔亮的博客-专注devops自动化运维,传播优秀it运维技术文章。更多原创运维开发相关文章,欢迎访问https://www.cuiliangblog.cn

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值