使用 Nginx Ingress 实现金丝雀发布/灰度发布

news/2024/12/27 14:34:18/文章来源:https://www.cnblogs.com/sl08/p/18553470

使用 Nginx Ingress 实现金丝雀发布/灰度发布

说明:

使用 Nginx Ingress 实现金丝雀发布的集群,需部署 Nginx Ingress 作为 Ingress Controller,并且对外暴露统一的流量入口。详情请参见 在 TKE 上部署 Nginx Ingress

使用场景

使用 Nginx Ingress 实现金丝雀发布适用场景主要取决于业务流量切分的策略。目前 Nginx Ingress 支持基于 Header、Cookie 和服务权重三种流量切分的策略,基于这三种策略可实现以下两种发布场景:

场景1: 灰度新版本到部分用户

假设线上已运行了一套对外提供7层服务的 Service A,此时需上线开发的新版本 Service A',但不期望直接替换原有的 Service A,仅灰度部分用户,待运行一段时间足够稳定后再逐渐全量上线新版本,平滑下线旧版本。针对此场景可使用 Nginx Ingress 基于 Header 或 Cookie 进行流量切分的策略来发布,业务使用 Header 或 Cookie 来标识不同类型的用户,并通过配置 Ingress 来实现让带有指定 Header 或 Cookie 的请求被转发到新版本,其它请求仍然转发到旧版本,从而将新版本灰度给部分用户。示意图如下:

img

场景2: 切分一定比例的流量到新版本

假设线上已运行了一套对外提供7层服务的 Service B,此时修复了 Service B 的部分问题,需灰度上线新版本 Service B'。但不期望直接替换原有的 Service B,需先切换10%的流量至新版本,待运行一段时间足够稳定后再逐渐加大新版本流量比例直至完全替换旧版本,最终平滑下线旧版本。示意图如下:

img

 

注解说明

通过给 Ingress 资源指定 Nginx Ingress 所支持的 annotation 可实现金丝雀发布。需给服务创建两个 Ingress,其中一个为常规 Ingress,另一个为带 nginx.ingress.kubernetes.io/canary: "true" 固定 annotation 的 Ingress,称为 Canary Ingress。Canary Ingress 一般代表新版本的服务,结合另外针对流量切分策略的 annotation 一起配置即可实现多种场景的金丝雀发布。以下为相关 annotation 的详细介绍:

**nginx.ingress.kubernetes.io/canary-by-header** 表示如果请求头中包含指定的 header 名称,并且值为 always,就将该请求转发给该 Ingress 定义的对应后端服务。如果值为 never 则不转发,可以用于回滚到旧版。如果为其他值则忽略该 annotation。

**nginx.ingress.kubernetes.io/canary-by-header-value** 该 annotation 可以作为 canary-by-header 的补充,可指定请求头为自定义值,包含但不限于 alwaysnever。当请求头的值命中指定的自定义值时,请求将会转发给该 Ingress 定义的对应后端服务,如果是其它值则忽略该 annotation。

**nginx.ingress.kubernetes.io/canary-by-header-pattern**canary-by-header-value 类似,区别为该 annotation 用正则表达式匹配请求头的值,而不是只固定某一个值。如果该 annotation 与 canary-by-header-value 同时存在,该 annotation 将被忽略。

**nginx.ingress.kubernetes.io/canary-by-cookie**canary-by-header 类似,该 annotation 用于 cookie,仅支持 alwaysnever

**nginx.ingress.kubernetes.io/canary-weight** 表示 Canary Ingress 所分配流量的比例的百分比,取值范围 [0-100]。例如,设置为10,则表示分配10%的流量给 Canary Ingress 对应的后端服务。

说明:

以上规则会按优先顺序进行评估,优先顺序为: canary-by-header -> canary-by-cookie -> canary-weight

当 Ingress 被标记为 Canary Ingress 时,除了 nginx.ingress.kubernetes.io/load-balancenginx.ingress.kubernetes.io/upstream-hash-by 外,所有其他非 Canary 注释都将被忽略。

使用示例

注意: 下面以 TKE 集群为例,为您演示如何使用 Nginx Ingress 进行金丝雀发布。在操作过程中,请注意以下事项:

\1. 相同服务的 Canary Ingress 仅能够定义一个,导致后端服务最多支持两个版本。

\2. 在 Ingress 中必须配置域名,否则将无法生效。

\3. 即便流量完全切到了 Canary Ingress 上,旧版服务仍需存在,否则会出现报错。

使用 YAML 创建资源

本文提供以下两种方式使用 YAML 部署工作负载及创建 Service:

方式1:在单击 TKE 或 Serverless 集群详情页右上角的 YAML 创建资源,并将本文示例的 YAML 文件内容输入编辑界面。

方式2:将示例 YAML 保存为文件,再使用 kubectl 指定 YAML 文件进行创建。例如 kubectl apply -f xx.yaml

部署两个版本的服务

\1. 在集群中部署第一个版本的 Deployment,本文以 nginx-v1 为例。YAML 示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-v1namespace: defaultlabels:   app: nginx-v1
spec:replicas: 3selector:   matchLabels:     app: nginx-v1template:   metadata:     labels:       app: nginx-v1   spec:     containers:       - name: nginx-v1         image: nginx:1.15.2         command:           - sh           - '-c'           - >-             echo nginx-v1 > /usr/share/nginx/html/index.html && exec nginx -g             'daemon off;'         ports:           - name: nginxprot             containerPort: 80             protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: nginx-v1namespace: defaultlabels:   app: nginx-v1
spec:ports:   - name: nginxprot     protocol: TCP     port: 80     targetPort: 80selector:   app: nginx-v1type: ClusterIP

\2. 再部署第二个版本的 Deployment,本文以 nginx-v2 为例。YAML 示:

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-v2namespace: defaultlabels:   app: nginx-v2
spec:replicas: 3selector:   matchLabels:     app: nginx-v2template:   metadata:     labels:       app: nginx-v2   spec:     containers:       - name: nginx-v2         image: nginx:1.15.2         command:           - sh           - '-c'           - >-             echo nginx-v2 > /usr/share/nginx/html/index.html && exec nginx -g             'daemon off;'         ports:           - name: nginxprot             containerPort: 80             protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: nginx-v2namespace: defaultlabels:   app: nginx-v2
spec:ports:   - name: nginxprot     protocol: TCP     port: 80     targetPort: 80selector:   app: nginx-v2

您可登录 容器服务控制台,在集群的工作负载详情页查看部署情况。如下图所示:

img

\3.创建 Ingress,对外暴露服务,指向 v1 版本的服务。YAML 示例如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginxnamespace: default
spec:ingressClassName: nginxrules:   - host: canary.example.com     http:       paths:         - path: /           pathType: Prefix           backend:             service:               name: nginx-v1               port:                 number: 80

\4.执行以下命令,进行访问验证。

curl -H "Host: canary.example.com" http://EXTERNAL-IP # EXTERNAL-IP 替换为 Nginx Ingress 自身对外暴露的 IP

返回结果如下:

nginx-v1

基于 Header 的流量切分

创建 Canary Ingress,指定 v2 版本的后端服务,并增加 annotation。实现仅将带有名为 Region 且值为 cd 或 sz 的请求头的请求转发给当前 Canary Ingress,模拟灰度新版本给成都和深圳地域的用户。YAML 示例如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-canarynamespace: defaultannotations:   nginx.ingress.kubernetes.io/canary: 'true'   nginx.ingress.kubernetes.io/canary-by-header: Region   nginx.ingress.kubernetes.io/canary-by-header-pattern: cd|sz
spec:ingressClassName: nginxrules:   - host: canary.example.com     http:       paths:         - path: /           pathType: Prefix           backend:             service:               name: nginx-v2               port:                 number: 80
​

执行以下命令,进行访问测试。

curl -H "Host: canary.example.com" -H "Region: cd" http://EXTERNAL-IP # EXTERNAL-IP 替换为 Nginx Ingress 自身对外暴露的 IP
nginx-v2
curl -H "Host: canary.example.com" -H "Region: bj" http://EXTERNAL-IP
nginx-v1
curl -H "Host: canary.example.com" -H "Region: cd" http://EXTERNAL-IP
nginx-v2
curl -H "Host: canary.example.com" http://EXTERNAL-IP
nginx-v1

可查看当仅有 header Region 为 cd 或 sz 的请求才由 v2 版本服务响应。

基于 Cookie 的流量切分

使用 Cookie 则无法自定义 value,以模拟灰度成都地域用户为例,仅将带有名为 user_from_cd 的 Cookie 的请求转发给当前 Canary Ingress。YAML 示例如下:

说明:

若您已配置以上步骤创建 Canary Ingress,则请删除后再参考本步骤创建。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-canarynamespace: defaultannotations:   nginx.ingress.kubernetes.io/canary: 'true'   nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_cd"
spec:ingressClassName: nginxrules:   - host: canary.example.com     http:       paths:         - path: /           pathType: Prefix           backend:             service:               name: nginx-v2               port:                 number: 80
​

执行以下命令,进行访问测试。

curl -s -H "Host: canary.example.com" --cookie "user_from_cd=always" http://EXTERNAL-IP # EXTERNAL-IP 替换为 Nginx Ingress 自身对外暴露的 IP
nginx-v2
curl -s -H "Host: canary.example.com" --cookie "user_from_bj=always" http://EXTERNAL-IP
nginx-v1
curl -s -H "Host: canary.example.com" http://EXTERNAL-IP
nginx-v1

可查看当仅有 cookie user_from_cdalways 的请求才由 v2 版本的服务响应。

基于服务权重的流量切分

使用基于服务权重的 Canary Ingress 时,直接定义需要导入的流量比例即可。以导入10%流量到 v2 版本为例,YAML 示例如下:

说明:

若您已配置以上步骤创建 Canary Ingress,则请删除后再参考本步骤创建。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-canarynamespace: defaultannotations:   nginx.ingress.kubernetes.io/canary: 'true'   nginx.ingress.kubernetes.io/canary-weight: '10'
spec:ingressClassName: nginxrules:   - host: canary.example.com     http:       paths:         - path: /           pathType: Prefix           backend:             service:               name: nginx-v2               port:                 number: 80
​

执行以下命令,进行访问测试。

for i in {1..10}; do curl -H "Host: canary.example.com" http://EXTERNAL-IP; done;
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v2
nginx-v1
nginx-v1
nginx-v1

可查看,有十分之一的几率由 v2 版本的服务响应,符合10%服务权重的设置。

参考资料

希望大家多给博主提提建议

Nginx Ingress 金丝雀注解官方文档

在 TKE 上部署 Nginx Ingress

使用 Nginx Ingress 实现金丝雀发布-实践教程-腾讯云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/836343.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

# 20222309 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 本实践目标是掌握metasploit的用法。 指导书参考Rapid7官网的指导教程。 https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/ 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,search一…

如何在开源鸿蒙OpenHarmony开启SELinux模式?RK3566鸿蒙开发板演示

本文介绍开源鸿蒙OpenHarmony系统下,开启/关闭SELinux权限的方法,触觉智能Purple Pi OH鸿蒙开发板演示,已适配全新OpenHarmony5.0 Release系统!本文介绍在开源鸿蒙OpenHarmOony系统下,开启/关闭SELinux权限的方法,触觉智能Purple Pi OH鸿蒙开发板演示,搭载了瑞芯微RK356…

locust(服务器压测)

一: 注意事项:项目和压力机不能在同一台机器 二: 1.脚本压测 命令行:locust -f get.py --host=http:ip+host 注意事项Wait_time写0,0 不进行等待 1.脚本压测 2.1服务器防火墙需要关闭 2.2需要把打印去掉 2.3 Download Data 下载报告三.非web模式新版中 -u 指的是多少 用户/…

旺仔水饺-冲刺总结

1. 冲刺内容总结与反思 1.1 项目总结 本次冲刺阶段对项目的不足之处进行了相关改进: 针对团队沟通问题: 我们在本次冲刺阶段几乎是每天召开团队会议,包括沟通效率比较高的的站立会议;我们站立会议每次召开十分钟,尽量在这个十分钟之内大家都都把自己当前进行的的功能模块遇…

线程初见与线程管理

Chap1,2 Hello Concurrency与线程管理 参考书目:《C++ Concurrency in action》- By Anthony Willians, Second Edition 读书笔记 Contents定义并发,多线程 使用并发,多线程 简单的C++多线程1.1 什么是并发 1.1.1 计算机并发多核心:真正并行 单核心:时间片切换。1.1.2 并发…

人工智能之机器学习线代基础——线性相关和线性无关

线性相关(Linearly Dependent) 和 线性无关(Linearly Independent) 是线性代数中描述向量组关系的概念,用于判断向量组是否可以通过线性组合生成其他向量,以及它们是否包含冗余信息。

BurpSuite功能介绍

Burp Suite一共包含13个功能模块,它们帮助渗透测试人员更好地了解目标应用的整体状况、当前的工作涉及哪些目标、攻击面等信息。 Burp Suite Target主要包含站点地图、目标域、Target工具域并分析可能存在的漏洞。 Burp Suite Spider主要用于大型的应用系统测试,它能在很短时…

Jluosne的GNU Radio 频道的介绍

Jluosne的GUN Radio的频道 本频道主要发布有关GUN Radio有关的学习路径和学习资料,相关材料涉及到GUN Radio官方网站和优质的博文会进行refence mark。欢迎大家的关注和评论。 本频道的内容发布周期 非节假日为日刊,节假日休刊。不定期休刊,休刊会提前发布声明。 本频道的发…

2024-2025, 四大翻译工具加AI翻译的深度对比

在过去两年中,人工智能技术的迅猛发展对翻译工具产生了深远的影响。本期特意挑选了四款翻译工具以及一个AI翻译工具,对其性能进行评测,看看在AI技术的加持下,它们的质量提升如何。前言 在过去两年中,人工智能技术的迅猛发展对翻译工具产生了深远的影响。 本期特意挑选了四…

vue2-组件化编程

模块:向外提供特定功能的js呈现 组件:用来实现局部(特定)功能效果的代码集合 模块化:当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用 组件化:当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用编写组件-非单文件组件非单文件组件:一个…

实验4 类的组合、继承、模板类、标准库

任务2 源码:1 #include <iostream>2 #include <vector>3 #include <string>4 #include <algorithm>5 #include <numeric>6 #include <iomanip>7 8 using std::vector;9 using std::string;10 using std::cin;11 using std::cout;12 using…