文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247484478&idx=1&sn=238390dc34340ec291aed517f4a6cb9f&chksm=fdb90b23cace8235ef224bd086f9f3e9e29e07fa18d444e0edde5e76efa39bdbb921588726b8&cur_album_id=1319287026209947648&scene=190#rd

灰度发布我们有时候也会称为金丝雀发布(Canary),主要就是让一部分测试的服务也参与到线上去,经过测试观察看是否符号上线要求。

这篇使用的是FileProvider提供的灰度发布,高版本使用 TraefikService 对象提供的,地址:https://www.cnblogs.com/sanduzxcvbnm/p/15749641.html

k8s版本:1.20.12

traefik版本:2.4.8

比如现在我们有两个名为 appv1 和 appv2 的 Nginx 服务,我们希望通过 Traefik 来控制我们的流量,将 3/4 的流量路由到 appv1,1/4 的流量路由到 appv2 去,这个时候就可以利用 Traefik2.0 中提供的带权重的轮询(WRR)来实现该功能,首先在 Kubernetes 集群中部署上面的两个服务。

截止v2.0.2版本,要实现上面的灰度发布、流量复制这些高级功能,只能通过 FileProvider 来实现,所以我们不能直接使用前面的 KubernetesCRDProvider 了。

appv1 服务的资源清单如下所示:(appv1.yaml)

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: appv1
  5. namespace: kube-system
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: appv1
  10. template:
  11. metadata:
  12. labels:
  13. use: test
  14. app: appv1
  15. spec:
  16. containers:
  17. - name: nginx
  18. image: nginx:1.15-alpine
  19. ports:
  20. - containerPort: 80
  21. name: portv1
  22. ---
  23. apiVersion: v1
  24. kind: Service
  25. metadata:
  26. name: appv1
  27. namespace: kube-system
  28. spec:
  29. selector:
  30. app: appv1
  31. ports:
  32. - name: http
  33. port: 80
  34. targetPort: portv1

appv2 服务的资源清单如下所示:(appv2.yaml)

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: appv2
  5. namespace: kube-system
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: appv2
  10. template:
  11. metadata:
  12. labels:
  13. use: test
  14. app: appv2
  15. spec:
  16. containers:
  17. - name: nginx
  18. image: nginx:1.15-alpine
  19. ports:
  20. - containerPort: 80
  21. name: portv2
  22. ---
  23. apiVersion: v1
  24. kind: Service
  25. metadata:
  26. name: appv2
  27. namespace: kube-system
  28. spec:
  29. selector:
  30. app: appv2
  31. ports:
  32. - name: http
  33. port: 80
  34. targetPort: portv2

直接创建上面两个服务:

  1. # kubectl apply -f appv1.yaml
  2. deployment.apps/appv1 created
  3. service/appv1 created
  4. # kubectl apply -f appv2.yaml
  5. deployment.apps/appv2 created
  6. service/appv2 created
  7. # 通过下面的命令可以查看服务是否运行成功
  8. # kubectl get pods -l use=test -n kube-system
  9. NAME READY STATUS RESTARTS AGE
  10. appv1-9d5c487-ssj9s 1/1 Running 0 51s
  11. appv2-5b94b97989-cjmgj 1/1 Running 0 47s

由于 WRR 这个功能目前只支持 FileProvider,所以我们需要开启该 Provider 才能使用.

这里需要注意的是由于需要开启 FileProvider,所以我们需要提供一个文件用于该 Provider 的配置,我们这里是用在 Kubernetes 集群中的,所以可以通过一个 ConfigMap 对象,将配置文件内容挂载到 Traefik 的 Pod 中去.

如下所示,我们通过将一个名为 traefik-dynamic-conf 的 ConfigMap 对象挂载到了 /config 目录下面去,然后通过 --providers.file.filename参数指定配置文件开启 FileProvider,另外添加 ---providers.file.watch=true 参数可以让 Traefik 动态更新配置:

  1. # 参考内容
  2. ......
  3. volumes:
  4. - name: config
  5. configMap:
  6. name: traefik-dynamic-conf
  7. containers:
  8. - image: traefik:v2.0.2
  9. name: traefik-ingress-lb
  10. volumeMounts:
  11. - name: config
  12. mountPath: /config
  13. ports:
  14. - name: web
  15. containerPort: 80
  16. hostPort: 80
  17. - name: admin
  18. containerPort: 8080
  19. hostPort: 8080
  20. args:
  21. - --entrypoints.web.Address=:80
  22. - --api.insecure=true
  23. - --providers.file.watch=true
  24. - --providers.file.filename=/config/traefik-dynamic.toml
  25. - --api
  26. - --api.debug=true
  27. - --api.dashboard=true
  28. - --accesslog

完整的 YAML 文件可以前往 https://github.com/cnych/kubeapp/tree/master/traefik2/canary 获取。

上面是开启 FileProvider 的配置。

我这里安装的traefik是使用kubeoperator安装k8s集群时选择的,对照上面的文件,修改步骤有两种,第一种是修改对应的yaml文件,第二种是通过kubepi进行修改

修改对应的yaml文件

  1. ......
  2. volumeMounts:
  3. - name: data
  4. mountPath: /data
  5. - name: tmp
  6. mountPath: /tmp
  7. - name: config
  8. mountPath: /config
  9. args:
  10. - "--global.checknewversion"
  11. - "--global.sendanonymoususage"
  12. - "--entryPoints.traefik.address=:18443/tcp"
  13. - "--entryPoints.web.address=:80/tcp"
  14. - "--entryPoints.websecure.address=:443/tcp"
  15. - "--api.insecure=true"
  16. - "--api.dashboard=true"
  17. - "--ping=true"
  18. - "--providers.kubernetescrd"
  19. - "--providers.kubernetesingress"
  20. - "--providers.file.watch=true"
  21. - "--providers.file.filename=/config/traefik-dynamic.toml"
  22. volumes:
  23. - name: data
  24. emptyDir: {}
  25. - name: tmp
  26. emptyDir: {}
  27. volumes:
  28. - name: config
  29. configMap:
  30. name: traefik-dynamic-conf

通过kubepi进行修改

等创建ConfigMap 对象后再通过kubepi添加挂载点

接下来需要创建对应的 ConfigMap 对象,首先创建一个名为 traefik-dynamic.toml 的文件,内容如下所示:

  1. [http]
  2. [http.routers]
  3. [http.routers.Router0]
  4. entryPoints = ["web"]
  5. service = "app"
  6. rule = "Host(`www.daniel.com`)"
  7. [http.services]
  8. [http.services.app]
  9. [[http.services.app.weighted.services]]
  10. name = "appv1"
  11. weight = 3
  12. [[http.services.app.weighted.services]]
  13. name = "appv2"
  14. weight = 1
  15. [http.services.appv1]
  16. [http.services.appv1.loadBalancer]
  17. [[http.services.appv1.loadBalancer.servers]]
  18. url = "http://appv1/"
  19. [http.services.appv2]
  20. [http.services.appv2.loadBalancer]
  21. [[http.services.appv2.loadBalancer.servers]]
  22. url = "http://appv2/"

上面这个配置文件就是我们需要配置的灰度发布的规则,创建一个名为 Router0 的路由,在 web 这个入口点上面监听 Host=www.daniel.com 这样的请求,将请求路由给名为 app 的服务,而该服务则将请求路由给了 appv1 这个服务,权重为 3,另外一部分请求路由给了 appv2 这个服务,权重为 1,也就是有 3/4 的请求会被路由到 http://appv1/ 这个真实的服务上,这个地址也就是我们 Kubernetes 集群中的 appv1 这个 Service 对象的 FQDN 地址,当然我们也可以用全路径( http://appv1.kube-system.svc.cluster.local:80)表示,因为都在 kube-system 这个命名空间下面,所以直接用服务名也是可以的,同样的另外的 1/4 请求会被路由到 http://appv2/ 这个真实的服务上。

  1. # kubectl create configmap traefik-dynamic-conf --from-file=traefik-dynamic.toml -n kube-system

创建完成后,再更新 Traefik2.0,就可以将配置文件通过 ConfigMap 挂载到 Traefik Pod 的 /config/traefik-dynamic.toml 路径下面去了。

创建ConfigMap 对象后再通过kubepi添加挂载点



或者是

检查:确保新traefik 的pod起来后,在/config目录下有traefik-dynamic.toml文件

添加IngressRoute

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRoute
  4. metadata:
  5. labels:
  6. app.kubernetes.io/name: traefik
  7. kubernetes.io/ingress.class: traefik
  8. name: app-test
  9. namespace: test
  10. spec:
  11. entryPoints:
  12. - web
  13. routes:
  14. - kind: Rule
  15. match: Host(`www.daniel.com`)
  16. services:
  17. - name: app # 指向app,但是根据traefik-dynamic.toml文件又进行分流,按比例到appv1和appv2
  18. port: 80

然后将域名www.daniel.com 解析到 Traefik 所在的 Pod,这个时候我们打开两个终端,分别去观察 appv1 和 appv2 两个应用的日志。

在浏览器中连续访问 www.daniel.com 4 次,我们可以观察到 appv1 这应用会收到 3 次请求,而 appv2 这个应用只收到 1 次请求,符合上面我们的 3:1 的权重配置。



不知道是否是 Traefik 的 BUG,同时将 KubernetesCRD Provider 和 File Provider 开启的时候,识别不了 File Provider 中的配置,该问题还有待验证。

traefik版本:2.4.8未出现该问题 :--providers.kubernetescrd

traefik接口显示内容

注意:隔天后在访问,会有个奇怪的现象,用firefox:95.0.2版本访问后的结果始终只有一个,用chrome:95.0.4638.54版本则可以进行灰度轮询

Traefik 2.0 实现灰度发布的更多相关文章

  1. Traefik 2.0 发布了

    Traefik 2.0 发布了,包含了很多不错的行特性 tcp 路由(同时也支持sni 路由) 参考配置 tcp: routers: to-db-1: entrypoints: - web-secur ...

  2. 利用nginx+lua+memcache实现灰度发布

    一.灰度发布原理说明 灰度发布在百度百科中解释: 灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什 ...

  3. Nginx配之负载均衡、缓存、黑名单和灰度发布

    一.Nginx安装(基于CentOS 6.5) 1.yum命令安装 yum install nginx –y(若不能安装,执行命令yum install epel-release) 2. 启动.停止和 ...

  4. Nginx配置之负载均衡、限流、缓存、黑名单和灰度发布

    一.Nginx安装(基于CentOS 6.5) 1.yum命令安装 yum install nginx –y(若不能安装,执行命令yum install epel-release) 2. 启动.停止和 ...

  5. 灰度发布/AB test

    背景 互联网产品有一个特点,就是不停的升级,升级,再升级.一般采用敏捷开发的团队,基本上保持每周一次的发布频率,系统升级总是伴随着风险,新旧版本兼容的风险,用户使用习惯突然改变而造成用户流失的风险,系 ...

  6. Nginx详解二十四:Nginx深度学习篇之灰度发布

    实战场景 - 灰度发布 灰度发布的作用:按照一定的关系区别,分部分的代码进行上线,使代码的发布能平滑过渡上线实现方式: 1.用户的信息cookie等信息区别 2.根据用户的IP地址 安装memcach ...

  7. 蓝绿部署、红黑部署、AB测试、灰度发布、金丝雀发布、滚动发布的概念与区别(转)

    出处:https://www.baidu.com/link?url=QjboallwNm_jxcL3fHG57wEakiBfAs_3-TChTGu1eBXstlHEsGBc-NDA7AKTqsiroB ...

  8. 使用gitlab, jenkins搭建CI(持续集成)系统(4) 灰度发布publish

    publish环境是正式环境,和dev, test, prepublish环境不同的是,正式环境一般要更加谨慎一些,发布的时候需要有一个灰度过程,即:分多次部署,每次部署几个服务器节点,验证没有问题以 ...

  9. 新浪的动态策略灰度发布系统:ABTestingGateway

    原文链接:http://www.open-open.com/lib/view/open1439889185239.html ABTesingGateway 是一个可以动态设置分流策略的灰度发布系统,工 ...

随机推荐

  1. [原创]树莓派CM4配置GPIO复用为i2c

    1.简介 项目中需要控制各种外设的电源,正常应该是通过GPIO进行控制,但是树莓派CM4的GPIO管脚有限,因此需要使用i2c扩展IO 查阅CM4-datesheet发现GPIO22和GPIO23可以 ...

  2. 2020.7.19 区间 dp 阶段测试

    打崩了-- 事先说明,今天没有很在状态,所以题解就直接写在代码注释里的,非常抱歉 T1 颜色联通块 此题有争议,建议跳过 题目描述 N 个方块排成一排,第 i 个颜色为 Ci .定义一个颜色联通块 [ ...

  3. CSDN垃圾的没有底线!

    平时写代码,经常需要百度. 今天我输入搜索关键词"access sql字符串转日期"进行百度搜索: 然后点开第一条: 这个加粗的标题可以点的,再点开: 这个内容跟我的搜索关键词有什 ...

  4. 题解【洛谷 P1466 [USACO2.2]集合 Subset Sums】

    题目传送门 设 \(sum=1+2+3+4+\dots+n=\dfrac{n(n+1)}{2}\). 如果 \(2\nmid sum\),则显然没有方案. 如果 \(2\mid sum\),则这两个集 ...

  5. 使用Python3.7+Tornado5.1配合七牛云存储api来异步切分上传文件

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_123 之前写了几篇关于FastDfs分布式存储的文章:python3.7.3操作FastDfs来进行文件操作,其实市面上关于云存储 ...

  6. 6.13 NOI 模拟

    \(T1\ first\) \(bitset\)字符串匹配 \(yyds\) \(O(\frac{n^2}{w})\)就是正解! #include<bits/stdc++.h> #defi ...

  7. Linxu用户名验证登录MySQL管理数据库

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 前情介绍: 我们都知道登录MySQL数据库时,连接层接入数据库需要经过mysql.user表中,用户名密码的验证才能登录数 ...

  8. 技术分享 | MySQL数据误删除的总结

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 内容提要 用delete语句 使用drop.truncate删除表以及drop删 ...

  9. MybatisPlus高级特性

    MybatisPlus高级特性 1. 公共字段自动填充 1.1 问题分析 在新增员工时需要设置创建时间.创建人.修改时间.修改人等字段,在编辑员工时需要设置修改时间.修改人等字段.这些字段属于公共字段 ...

  10. Spring源码 13 IOC refresh方法8

    本文章基于 Spring 5.3.15 Spring IOC 的核心是 AbstractApplicationContext 的 refresh 方法. 其中一共有 13 个主要方法,这里分析第 8 ...