文章转载自: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)

apiVersion: apps/v1
kind: Deployment
metadata:
name: appv1
namespace: kube-system
spec:
selector:
matchLabels:
app: appv1
template:
metadata:
labels:
use: test
app: appv1
spec:
containers:
- name: nginx
image: nginx:1.15-alpine
ports:
- containerPort: 80
name: portv1
---
apiVersion: v1
kind: Service
metadata:
name: appv1
namespace: kube-system
spec:
selector:
app: appv1
ports:
- name: http
port: 80
targetPort: portv1

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

apiVersion: apps/v1
kind: Deployment
metadata:
name: appv2
namespace: kube-system
spec:
selector:
matchLabels:
app: appv2
template:
metadata:
labels:
use: test
app: appv2
spec:
containers:
- name: nginx
image: nginx:1.15-alpine
ports:
- containerPort: 80
name: portv2
---
apiVersion: v1
kind: Service
metadata:
name: appv2
namespace: kube-system
spec:
selector:
app: appv2
ports:
- name: http
port: 80
targetPort: portv2

直接创建上面两个服务:

# kubectl apply -f appv1.yaml
deployment.apps/appv1 created
service/appv1 created # kubectl apply -f appv2.yaml
deployment.apps/appv2 created
service/appv2 created # 通过下面的命令可以查看服务是否运行成功
# kubectl get pods -l use=test -n kube-system
NAME READY STATUS RESTARTS AGE
appv1-9d5c487-ssj9s 1/1 Running 0 51s
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 动态更新配置:

# 参考内容

......
volumes:
- name: config
configMap:
name: traefik-dynamic-conf
containers:
- image: traefik:v2.0.2
name: traefik-ingress-lb
volumeMounts:
- name: config
mountPath: /config
ports:
- name: web
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8080
hostPort: 8080
args:
- --entrypoints.web.Address=:80
- --api.insecure=true
- --providers.file.watch=true
- --providers.file.filename=/config/traefik-dynamic.toml
- --api
- --api.debug=true
- --api.dashboard=true
- --accesslog

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

上面是开启 FileProvider 的配置。

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

修改对应的yaml文件

......
volumeMounts:
- name: data
mountPath: /data
- name: tmp
mountPath: /tmp
- name: config
mountPath: /config
args:
- "--global.checknewversion"
- "--global.sendanonymoususage"
- "--entryPoints.traefik.address=:18443/tcp"
- "--entryPoints.web.address=:80/tcp"
- "--entryPoints.websecure.address=:443/tcp"
- "--api.insecure=true"
- "--api.dashboard=true"
- "--ping=true"
- "--providers.kubernetescrd"
- "--providers.kubernetesingress"
- "--providers.file.watch=true"
- "--providers.file.filename=/config/traefik-dynamic.toml"
volumes:
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}
volumes:
- name: config
configMap:
name: traefik-dynamic-conf

通过kubepi进行修改

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

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

[http]
[http.routers]
[http.routers.Router0]
entryPoints = ["web"]
service = "app"
rule = "Host(`www.daniel.com`)" [http.services]
[http.services.app] [[http.services.app.weighted.services]]
name = "appv1"
weight = 3 [[http.services.app.weighted.services]]
name = "appv2"
weight = 1 [http.services.appv1]
[http.services.appv1.loadBalancer]
[[http.services.appv1.loadBalancer.servers]]
url = "http://appv1/" [http.services.appv2]
[http.services.appv2.loadBalancer]
[[http.services.appv2.loadBalancer.servers]]
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/ 这个真实的服务上。

# 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

---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app.kubernetes.io/name: traefik
kubernetes.io/ingress.class: traefik
name: app-test
namespace: test
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`www.daniel.com`)
services:
- name: app # 指向app,但是根据traefik-dynamic.toml文件又进行分流,按比例到appv1和appv2
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. 毫秒值的概念和作用 --Date类的构造方法和成员方法

    一,  Date类类 Date 表示特定的瞬间,精确到毫秒. 毫秒:千分之一秒作用:可以对时间和日期进行计算可一把日期转换为毫秒进行计算,计算完毕,再转换为日期. 把日期转换为毫秒:当前的日期:202 ...

  2. CTO与CIO选型数据中台的几大建议

    企业数字化转型离不开企业数字化技术的配备.但企业在选择数字化技术时也面临着一个问题,就是如何在大胆采用先进的数字化技术和对技术进行投资之间找到平衡,将投资风险降到最低,毕竟错误的技术选型会给企业带来不 ...

  3. Markdown扩展语法

    目录 Markdown 语法补充 一.快速生成 HTML 表格代码 在线表格编辑器--TablesGenerator 二. 插入视频.音频或GIF 1. 视频 2. 音频 方法一 方法二 方法三 3. ...

  4. Tomcat介绍和配置使用

    目录 JavaWeb 的概念 什么是 JavaWeb? 什么是请求? 什么是响应? 请求和响应的关系 Web 资源的分类 常用的 Web 服务器 Tomcat 服务器和 Servlet 版本的对应关系 ...

  5. AtCoder Beginner Contest 253 F - Operations on a Matrix // 树状数组

    题目传送门:F - Operations on a Matrix (atcoder.jp) 题意: 给一个N*M大小的零矩阵,以及Q次操作.操作1(l,r,x):对于 [l,r] 区间内的每列都加上x ...

  6. 对象的反序列化流_ObjectInputStream和transient关键字瞬态关键字

    对象的反序列化流_ObjectInputStream package com.yang.Test.ObjectStreamStudy; import java.io.FileInputStream; ...

  7. Web 前端实战:Gitee 贡献图

    前言 这次要做的 Web 前端实战是一个 Gitee 个人主页下的贡献图(在线 Demo),偶尔做一两个,熟悉熟悉 JS 以及 jQ.整体来说这个案例并不难,主要是控制第一个节点以及最后一个节点处于星 ...

  8. STC8H开发(十六): GPIO驱动XL2400无线模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  9. Vue3中插槽(slot)用法汇总

    Vue中的插槽相信使用过Vue的小伙伴或多或少的都用过,但是你是否了解它全部用法呢?本篇文章就为大家带来Vue3中插槽的全部用法来帮助大家查漏补缺. 什么是插槽 简单来说就是子组件中的提供给父组件使用 ...

  10. redis-zset命令

    一.BZPOPMAX key [key ...] timeout BZPOPMAX 是有序集合命令 ZPOPMAX带有阻塞功能的版本. 在参数中的所有有序集合均为空的情况下,阻塞连接.参数中包含多个有 ...