首页 > 系统相关 >使用 Nginx Ingress 实现金丝雀发布/灰度发布

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

时间:2024-11-18 19:32:35浏览次数:1  
标签:Ingress nginx 金丝雀 canary v1 v2 灰度 io

使用 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-v1
  namespace: default
  labels:
    app: nginx-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-v1
  template:
    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-v1
  namespace: default
  labels:
    app: nginx-v1
spec:
  ports:
    - name: nginxprot
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: nginx-v1
  type: ClusterIP

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v2
  namespace: default
  labels:
    app: nginx-v2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-v2
  template:
    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-v2
  namespace: default
  labels:
    app: nginx-v2
spec:
  ports:
    - name: nginxprot
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: nginx-v2

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

img

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

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  namespace: default
spec:
  ingressClassName: nginx
  rules:
    - 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-canary
  namespace: default
  annotations:
    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: nginx
  rules:
    - 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-canary
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/canary: 'true'
    nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_cd"
spec:
  ingressClassName: nginx
  rules:
    - 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-canary
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/canary: 'true'
    nginx.ingress.kubernetes.io/canary-weight: '10'
spec:
  ingressClassName: nginx
  rules:
    - 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 实现金丝雀发布-实践教程-腾讯云

标签:Ingress,nginx,金丝雀,canary,v1,v2,灰度,io
From: https://www.cnblogs.com/sl08/p/18553470

相关文章

  • Nacos 配置中心变更利器:自定义标签灰度
    作者:柳遵飞配置中心被广泛使用配置中心是Nacos的核心功能之一,接入配置中心,可以实现不重启线上应用的情况下动态改变程序的运行期行为,在整个软件生命周期中,可以极大降低了软件构建及部署的成本,提升效率,为业务发展提速。配置中心在各个领域都有着非常广泛的应用。上图列举了N......
  • k8s: 配置ingress的会话亲和(转载)
    Ingress会话亲和,又称会话保持,粘性会话,指同一客户端的请求在一定时间内会被ingress路由到相同的pod处理.本文控制器使用的是ingress-nginx ingress默认的负载均衡策略是轮询,验证如下使用浏览器连续访问9次ingress查看ingress日志,可看到9次请求被轮询负载到不同pod处......
  • 如何将 Kubernetes 中的两个 Nginx Ingress 合并成一个:操作步骤与注意事项
    个人名片......
  • 深入理解 Kubernetes 中的 Service、Ingress 和 NginxIngress:如何配置多个域名访问 Ja
    个人名片......
  • 全链路多重灰度发布
    1.什么是灰度发布让我们从最简单的情况开始。灰度发布又叫金丝雀发布,是一种发布技术,用于减少软件新版本发布的风险。其想法是首先向少数用户发布新版本的软件,然后逐步扩大用户比例。例如,在这个图中,我们先测试10%的用户,然后逐渐将更多的用户转移到新版本,最后,当所有的用户都......
  • K8s安装ingress-nginx
    安装ingress-nginx问题ingress-nginx-controller的service通过NodePort显露出去时,需要先使用ingree-controller调度到的节点先访问一次,集群的其他节点才能正常访问,如:有master:10.191.9.21,node1:10.191.9.22,node2:10.191.9.23三个节点,ingress-controller调度到了......
  • Halcon 灰度形态学及太阳能电池片缺陷检测应用
    一、基本概念        Halcon灰度形态学是图像处理领域中的一种重要技术,它允许对图像中的灰度值进行非线性操作,这些操作取决于像素的邻域。        灰度形态学是形态学的一种推广,与二值形态学相比,它不仅在图像本身的空间尺寸上有所变化,而且图像本身的灰度值也......
  • 阿里云基于ALB实现灰度发布
    灰度发布(又称为金丝雀发布)是一种平滑过渡的发布方式,将老版本应用与新版本应用同时部署在环境中,让一部分用户继续使用老版本应用,一部分用户开始使用新版本应用,然后根据用户使用情况调整新版本流量占比,逐步把所有用户都迁移到新版本应用。 1.应用场景互联网产品需要快速......
  • ORB-SLAM2源码学习:ORBextractor.cc:IC_Angle 利用灰度质心法求解关键点方向角
    ORB特征点:特征点是由关键点和描述子两部分组成,关键点是指特征点在图像中的位置,描述子是用来描述关键点周围的像素信息。ORB关键点是在FAST关键点的基础上进行改进给像素增加了一个主方向,称为OrientedFAST。描述子在BRIEF的基础上加入了上述的方向信息,称为SteeredBRIEF。FAS......
  • ingress controller openresty lua脚本的开发
    接上篇博客:https://blog.csdn.net/weixin_34542632/article/details/143405219?spm=1001.2014.3001.5501,我们接下来一起看一下ingress网关的lua脚本开发。一些基础信息:ingresscontroller其实就是openresty,官方话术:ThismoduleisacorecomponentofOpenResty.Ifyouar......