推荐阅读

Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506
Helm3(K8S 资源对象管理工具)博客专栏:https://blog.csdn.net/xzk9381/category_10895812.html

本文原文链接:https://blog.csdn.net/xzk9381/article/details/109570832,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

一、Canary 规则说明

Ingress-Nginx 是一个K8S ingress工具,支持配置 Ingress Annotations 来实现不同场景下的灰度发布和测试( Ingress-Nginx 是在0.21.0 版本 中,引入的Canary 功能)。 Nginx Annotations 支持以下 4 种 Canary 规则:

  • nginx.ingress.kubernetes.io/canary-by-header:基于 Request Header 的流量切分,适用于灰度发布以及 A/B 测试。当 Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口;对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。
  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (即:canary-by-header)一起使用。
  • nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。权重为 100 意味着所有请求都将被发送到 Canary 入口。
  • nginx.ingress.kubernetes.io/canary-by-cookie:基于 Cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always时,它将被路由到 Canary 入口;当 cookie 值设置为 never时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较。

注意:金丝雀规则按优先顺序进行如下排序:

canary-by-header - > canary-by-cookie - > canary-weight

我们可以把以上的四个 annotation 规则可以总体划分为以下两类:

  1. 基于权重的 Canary 规则:

  1. 基于用户请求的 Canary 规则:

二、部署测试用例

1. 部署正式版本服务

首先创建一个 deployment 代表正式版本的服务,编写 yaml 内容如下:

---
apiVersion: v1
kind: Namespace
metadata:name: ns-myapplabels:name: ns-myapp---
apiVersion: apps/v1
kind: Deployment
metadata:name: productionnamespace: ns-myapp
spec:replicas: 1selector:matchLabels:app: productiontemplate:metadata:labels:app: productionspec:containers:- name: productionimage: mirrorgooglecontainers/echoserver:1.10ports:- containerPort: 8080env:- name: NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeName- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:name: productionnamespace: ns-myapplabels:app: production
spec:ports:- port: 80targetPort: 8080protocol: TCPname: httpselector:app: production

为这个服务创建 Ingress 路由规则,yaml 文件内容如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: productionnamespace: ns-myappannotations:kubernetes.io/ingress.class: nginx
spec:rules:- host: ingress.test.comhttp:paths:- backend:serviceName: productionservicePort: 80

应用以上 yaml 文件,创建完成后在 k8s 中查看到如下信息:

[k8s-master ~]# kubectl get ingress -n ns-myapp
NAME         CLASS    HOSTS              ADDRESS        PORTS   AGE
production   <none>   ingress.test.com   10.16.13.201   80      4m25s[k8s-master ~]# kubectl get pod -n ns-myapp
NAME                          READY   STATUS    RESTARTS   AGE
production-5698c4565c-jmjn5   1/1     Running   0          7m11s

此时在命令行中访问 ingress.test.com 可以看到如下内容:

# curl ingress.test.comHostname: production-5698c4565c-jmjn5Pod Information:node name:   dumlog013201pod name:   production-5698c4565c-jmjn5pod namespace:   ns-myapppod IP: 10.42.0.74Server values:server_version=nginx: 1.13.3 - lua: 10008Request Information:client_address=10.16.13.201method=GETreal path=/query=request_version=1.1request_scheme=httprequest_uri=http://ingress.test.com:8080/Request Headers:accept=*/*host=ingress.test.comuser-agent=curl/7.64.1x-forwarded-for=10.2.130.18x-forwarded-host=ingress.test.comx-forwarded-port=80x-forwarded-proto=httpx-real-ip=10.2.130.18x-request-id=3019362be59228ee2284f5737fa39eb1x-scheme=httpRequest Body:-no body in request-

本文原文链接:https://blog.csdn.net/xzk9381/article/details/109570832,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

2. 部署 Canary 版本服务

接下来创建一个 Canary 版本的服务,用于作为灰度测试。

参考将上述 Production 版本的 production.yaml 文件,再创建一个 Canary 版本的应用,包括一个 Canary 版本的 deploymentservice (为方便快速演示,仅需将 production.yaml 的 deployment 和 service 中的关键字 production 直接替换为 canary,实际场景中可能涉及业务代码变更)。

三、基于权重的 Canary 规则测试

基于权重的流量切分的典型应用场景就是蓝绿部署,可通过将权重设置为 0 或 100 来实现。例如,可将 Green 版本设置为主要部分,并将 Blue 版本的入口配置为 Canary。最初,将权重设置为 0,因此不会将流量代理到 Blue 版本。一旦新版本测试和验证都成功后,即可将 Blue 版本的权重设置为 100,即所有流量从 Green 版本转向 Blue。

使用以下 canary.ingress 的 yaml 文件再创建一个基于权重的 Canary 版本的应用路由 (Ingress)。

注意:要开启灰度发布机制,首先需设置 nginx.ingress.kubernetes.io/canary: "true" 启用 Canary,以下 Ingress 示例的 Canary 版本使用了基于权重进行流量切分的 annotation 规则,将分配 30% 的流量请求发送至 Canary 版本。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: canarynamespace: ns-myappannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "30"
spec:rules:- host: ingress.test.comhttp:paths:- backend:serviceName: canaryservicePort: 80

接下来在命令行中使用如下命令访问域名 ingress.test.com 100次,计算每个版本分配流量的占比:

c=0;p=0;for i in $(seq 100); do result=$(curl -s ingress.test.com | grep  Hostname | awk -F: '{print $2}'); [[ ${result} =~ ^[[:space:]]canary ]] && let c++ || let p++; done;echo "production:${p}; canary:${c};"

可以得到如下结果:

production:73; canary:28;

四、基于用户请求的 Canary 规则测试

1. 基于 Resquest Header

基于 Request Header 进行流量切分的典型应用场景即灰度发布或 A/B 测试场景

给 Canary 版本的 Ingress 新增一条 annotation :nginx.ingress.kubernetes.io/canary-by-header: canary(这里的 annotation 的 value 可以是任意值),使当前的 Ingress 实现基于 Request Header 进行流量切分。

将 Canary 版本 Ingress 的 yaml 文件修改为如下内容:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: canarynamespace: ns-myappannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "30"nginx.ingress.kubernetes.io/canary-by-header: "canary"
spec:rules:- host: ingress.test.comhttp:paths:- backend:serviceName: canaryservicePort: 80

说明:金丝雀规则按优先顺序 canary-by-header - > canary-by-cookie - > canary-weight 进行如下排序,因此上面的 ingress 将忽略原有 canary-weight 的规则。

由于上面的 ingress 规则中没有对 canary-by-header: "canary" 提供具体的值,也就是 nginx.ingress.kubernetes.io/canary-by-header-value 规则,所以在访问的时候,只可以为 canary 赋值 neveralways,当 header 信息为 canary:never 时,请求将不会发送到 canary 版本;当 header 信息为 canary:always 时,请求将会一直发送到 canary 版本。示例如下:

[k8s-master ~ ]# curl -s -H "canary:never" ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5[k8s-master ~ ]# curl -s -H "canary:always" ingress.test.com | grep Hostname
Hostname: canary-79c899d85-992nw

也可以在上一个 annotation (即 canary-by-header)的基础上添加一条 nginx.ingress.kubernetes.io/canary-by-header-value: user-value 。用于通知 Ingress 将匹配到的请求路由到 Canary Ingress 中指定的服务。

将 Canary 版本 Ingress 的 yaml 文件修改为如下内容:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: canarynamespace: ns-myappannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "30"nginx.ingress.kubernetes.io/canary-by-header: "canary"nginx.ingress.kubernetes.io/canary-by-header-value: "true"
spec:rules:- host: ingress.test.comhttp:paths:- backend:serviceName: canaryservicePort: 80

上面的 ingress 规则设置了 header 信息为 canary:true,也就是只有满足这个 header 值时才会路由到 canary 版本。示例如下:

[k8s-master ~ ]# curl -s ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5[k8s-master ~ ]# curl -s -H "canary:test" ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5[k8s-master ~ ]# curl -s -H "canary:true" ingress.test.com | grep Hostname
Hostname: canary-79c899d85-992nw

五、基于 Cookie 的 Canary 规则测试

与基于 Request Header 的 annotation 用法规则类似。例如在 A/B 测试场景 下,需要让地域为北京的用户访问 Canary 版本。那么当 cookie 的 annotation 设置为 nginx.ingress.kubernetes.io/canary-by-cookie: "users_from_Beijing",此时后台可对登录的用户请求进行检查,如果该用户访问源来自北京则设置 cookieusers_from_Beijing 的值为 always,这样就可以确保北京的用户仅访问 Canary 版本。

将 Canary 版本 Ingress 的 yaml 文件修改为如下内容:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: canarynamespace: ns-myappannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_beijing"
spec:rules:- host: ingress.test.comhttp:paths:- backend:serviceName: canaryservicePort: 80

访问示例如下:

[k8s-master ~ ]# curl -s -b "user_from_beijing=always" ingress.test.com | grep Hostname
Hostname: canary-79c899d85-992nw[k8s-master ~ ]# curl -s -b "user_from_beijing=no" ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5

本文原文链接:https://blog.csdn.net/xzk9381/article/details/109570832,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

Kubernetes 使用 Ingress-nginx 实现灰度发布功能相关推荐

  1. 一文看懂ingress nginx实现灰度发布和蓝绿发布过程

    背景信息 灰度及蓝绿发布是为新版本创建一个与老版本完全一致的生产环境,在不影响老版本的前提下,按照一定的规则把部分流量切换到新版本,当新版本试运行一段时间没有问题后,将用户的全量流量从老版本迁移至新版 ...

  2. E融汇移动端灰度发布功能演进

    背景 灰度发布是近两年互联网产品必备的一个基础能力,在新功能发布时,只对一小部分用户开放,通过采集.分析用户的数据与反馈,逐步扩大范围,直至向所有用户开放. 灰度发布能使我们及早获得用户的意见反馈,完 ...

  3. 使用Nginx实现灰度发布

    灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B ...

  4. zuul灰度发布功能实现

    灰度发布.蓝绿发布.金丝雀发布各是什么意思,可以看这篇http://www.appadhoc.com/blog/product-release-strategy/. 基于eureka.ribbon实现 ...

  5. FinClip 9月产品小报丨灰度发布功能更新;FIDE 自定义接口 mock 功能优化

    9月底,在迎接国庆的时候,看看 FinClip 带给了大家什么最新的消息. 产品方面的相关动向

  6. 云视频自动化部署与灰度发布实践

    概要:Kubernetes改造与自动化灰度发布是一个长期的过程,需要克服很多困难.但改造也能实实在在带来研发效能的提升,支持灰度发布以后,测试的主要时间可以从晚上转到白天,减轻研发和测试和运维人员的负 ...

  7. 通过阿里云容器服务K8S Ingress Controller实现应用服务的灰度发布

    简介 日常工作中我们经常需要对服务进行版本更新升级,为此我们经常使用到的发布方式有滚动升级.分批暂停发布.蓝绿发布以及灰度发布,今天主要跟大家分享下在阿里云容器服务Kubernetes集群中如何通过I ...

  8. Spring Cloud微服务版本灰度发布新神器

    项目地址:https://github.com/Nepxion/Discovery 强烈建议stra.fork该项目,该项目可以作为学习改造Spring Cloud组件的案例项目. Nepxion D ...

  9. Web服务不停机更新和灰度发布方案

    文章目录 Web服务不停机更新和灰度发布方案 当前情况 方案一 负载均衡: 问题: 方案二 灰度发布: 用IF指令实现 根据来源ip做判断 根据cookie做判断 使用lua写脚本实现 使用nginx ...

最新文章

  1. CUDA刷新:GPU计算生态系统
  2. Linux环境ddd安装与使用
  3. linux strace 用法
  4. Java 中初始化 List 集合的 6 种方式!
  5. Spring 框架所有版本大集合下载
  6. 超经典解释什么叫网关
  7. Linux挂载windows中的共享目录步骤及问题解决方案(步骤清晰)
  8. HDFS应用场景、部署、原理与基本架构
  9. P2517-订货【网络流,费用流】
  10. 记一次ora-1652错误的解决过程
  11. Itext学习(二)----实现把图片转化为pdf
  12. 基于JAVA+SSH+MYSQL的外卖点餐系统
  13. git pull命令模式
  14. 安装qt qmake assistant 错误:could not find a Qt installation of ''
  15. java retainall_java 取交集方法retainAll
  16. SOLD2算法详解之2: 特征点检测,点NMS(CVPR 2021)
  17. 列宽一字符等于多少厘米_excel表格换算厘米的方法
  18. 华硕服务器怎么装win7系统教程,华硕win7系统重装教程
  19. Markdown离线编辑器
  20. 使用OLED屏显示汉字

热门文章

  1. JSK-217 阶乘【大数】
  2. CCF NOI1023 最大跨度
  3. pandas DataFrame 索引(iloc 与 loc 的区别)
  4. Python 标准库 —— glob
  5. 分治法(divide conquer)与动态规划(dynamic programming)应用举例
  6. 神奇的国际日期变更线
  7. php memcache数据类型,php读取memcache二进制数据
  8. python编程入门课 视频-Python入门到精通视频教程下载[21课程全]
  9. 学python能干什么工作-什么是Python?学完之后能做哪些工作?
  10. python编程入门电子书-Python编程基础 PDF 原书高质量版