首页 > 系统相关 >使用Nginx Ingress实现灰度发布和蓝绿发布

使用Nginx Ingress实现灰度发布和蓝绿发布

时间:2023-07-03 20:22:21浏览次数:50  
标签:Ingress kubernetes nginx ingress Nginx 灰度 io

应用场景  

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

场景一:切分部分用户流量到新版本

      假设线上已运行了一套对外提供七层服务的Service A,此时开发了一些新的特性,需要发布上线一个新的版本Service A',但又不想直接替换原有的Service A,而是期望将Header中包含foo=bar或者Cookie中包含foo=bar的用户请求转发到新版本Service A'中。待运行一段时间稳定后,再逐步全量上线新版本,平滑下线旧版本。示意图如下:

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

      假设线上已运行了一套对外提供七层服务的Service B,此时修复了一些问题,需要发布上线一个新的版本Service B',但又不想直接替换原有的Service B,而是期望将20%的流量切换到新版本Service B'中。待运行一段时间稳定后,再将所有的流量从旧版本切换到新版本中,平滑下线旧版本。

注解说明

     Nginx Ingress支持通过配置注解(Annotations)来实现不同场景下的发布和测试,可以满足灰度发布、蓝绿发布、A/B测试等业务场景。具体实现过程如下:为服务创建两个Ingress,一个为常规Ingress,另一个为带nginx.ingress.kubernetes.io/canary: "true"注解的Ingress,称为Canary Ingress;为Canary Ingress配置流量切分策略Annotation,两个Ingress相互配合,即可实现多种场景的发布和测试。Nginx Ingress的Annotation支持以下几种规则:

  • nginx.ingress.kubernetes.io/canary-by-header

      基于Header的流量切分,适用于灰度发布。如果请求头中包含指定的header名称,并且值为“always”,就将该请求转发给Canary Ingress定义的对应后端服务。如果值为“never”则不转发,可用于回滚到旧版本。如果为其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。

  • nginx.ingress.kubernetes.io/canary-by-header-value

     必须与canary-by-header一起使用,可自定义请求头的取值,包含但不限于“always”或“never”。当请求头的值命中指定的自定义值时,请求将会转发给Canary 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

     基于Cookie的流量切分,适用于灰度发布。与canary-by-header类似,该annotation用于cookie,仅支持“always”和“never”,无法自定义取值。

  • nginx.ingress.kubernetes.io/canary-weight

     基于服务权重的流量切分,适用于蓝绿部署。表示Canary Ingress所分配流量的百分比,取值范围[0-100]。例如,设置为100,表示所有流量都将转发给Canary Ingress对应的后端服务。

以上注解规则会按优先级进行评估,优先级为:canary-by-header -> canary-by-cookie -> canary-weight。
当Ingress被标记为Canary Ingress时,除了nginx.ingress.kubernetes.io/load-balance和nginx.ingress.kubernetes.io/upstream-hash-by外,所有其他非Canary的注解都将被忽略。
更多内容请参阅官方文档Annotations。

前提条件

  • 使用Nginx Ingress实现灰度发布的集群,需安装nginx-ingress插件作为Ingress Controller,并且对外暴露统一的流量入口。详细操作可参考安装插件
  • 已上传Nginx镜像至容器镜像服务。为方便观测流量切分效果,Nginx镜像包含新旧两个版本,欢迎页分别为“Old Nginx”和“New Nginx”。

资源创建方式

本文提供以下两种方式使用YAML部署Deployment和Service:

  • 方式1:在创建无状态工作负载向导页面,单击右侧“YAML创建”,再将本文示例的YAML文件内容输入编辑窗中。
  • 方式2:将本文的示例YAML保存为文件,再使用kubectl指定YAML文件进行创建。例如:kubectl create -f xxx.yaml。

步骤1:部署两个版本的服务

在集群中部署两个版本的Nginx服务,并通过Nginx Ingress对外提供七层域名访问。

1、创建第一个版本的Deployment和Service,本文以old-nginx为例。YAML示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: old-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: old-nginx
  template:
    metadata:
      labels:
        app: old-nginx
    spec:
      containers:
      - image: {your_repository}/nginx:old  # 容器使用的镜像为:nginx:old
        name: container-0
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
      imagePullSecrets:
      - name: default-secret

---

apiVersion: v1
kind: Service
metadata:
  name: old-nginx
spec:
  selector:
    app: old-nginx
  ports:
  - name: service0
    targetPort: 80
    port: 8080
    protocol: TCP
  type: NodePort

2、创建第二个版本的Deployment和Service,本文以new-nginx为例。YAML示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: new-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: new-nginx
  template:
    metadata:
      labels:
        app: new-nginx
    spec:
      containers:
      - image: {your_repository}/nginx:new  # 容器使用的镜像为:nginx:new
        name: container-0
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
      imagePullSecrets:
      - name: default-secret

---

apiVersion: v1
kind: Service
metadata:
  name: new-nginx
spec:
  selector:
    app: new-nginx
  ports:
  - name: service0
    targetPort: 80
    port: 8080
    protocol: TCP
  type: NodePort

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

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: gray-release
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx    # 使用Nginx型Ingress
    kubernetes.io/elb.port: '80'
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: '/'
            backend:
              serviceName: old-nginx      # 指定后端服务为old-nginx
              servicePort: 80

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

其中,<EXTERNAL_IP>为Nginx Ingress对外暴露的IP。

预期输出:

Old Nginx

步骤2:灰度发布新版本服务

       设置访问新版本服务的流量切分策略。云容器引擎CCE支持设置以下三种策略,实现灰度发布和蓝绿发布,您可以根据实际情况进行选择。

基于Header的流量切分基于Cookie的流量切分基于服务权重的流量切分

       基于Header、Cookie和服务权重三种流量切分策略均可实现灰度发布;基于服务权重的流量切分策略,调整新服务权重为100%,即可实现蓝绿发布。您可以在下述示例中了解具体使用方法。

注意:
示例中,有以下两点需要注意:
相同服务的Canary Ingress仅能够定义一个,从而使后端服务最多支持两个版本。
即使流量完全切到了Canary Ingress上,旧版服务仍需存在,否则会出现报错。

基于Header的流量切分

    以下示例仅Header中包含Region且值为bj或gz的请求才能转发到新版本服务。

1、创建Canary Ingress,指向新版本的后端服务,并增加annotation。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: canary-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"                       # 启用Canary
    nginx.ingress.kubernetes.io/canary-by-header: "Region"   
    nginx.ingress.kubernetes.io/canary-by-header-pattern: "bj|gz"    # Header中包含Region且值为bj或gz的请求转发到Canary Ingress
    kubernetes.io/elb.port: '80'
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: '/'
            backend:
              serviceName: new-nginx      # 指定后端服务为new-nginx
              servicePort: 80

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

$ curl -H "Host: www.example.com" -H "Region: bj" http://<EXTERNAL_IP>
New Nginx
$ curl -H "Host: www.example.com" -H "Region: sh" http://<EXTERNAL_IP>
Old Nginx
$ curl -H "Host: www.example.com" -H "Region: gz" http://<EXTERNAL_IP>
New Nginx
$ curl -H "Host: www.example.com" http://<EXTERNAL_IP>
Old Nginx

其中,<EXTERNAL_IP>为Nginx Ingress对外暴露的IP。

可以看出,仅当Header中包含Region且值为bj或gz的请求才由新版本服务响应。

基于Cookie的流量切分

     以下示例仅Cookie中包含user_from_bj的请求才能转发到新版本服务。

1、创建Canary Ingress,指向新版本的后端服务,并增加annotation。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: canary-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"                      # 启用Canary
    nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_bj"    # Cookie中包含user_from_bj的请求转发到Canary Ingress
    kubernetes.io/elb.port: '80'
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: '/'
            backend:
              serviceName: new-nginx      # 指定后端服务为new-nginx
              servicePort: 80

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

$ curl -s -H "Host: www.example.com" --cookie "user_from_bj=always" http://<EXTERNAL_IP>
New Nginx
$ curl -s -H "Host: www.example.com" --cookie "user_from_gz=always" http://<EXTERNAL_IP>
Old Nginx
$ curl -s -H "Host: www.example.com" http://<EXTERNAL_IP>
Old Nginx

其中,<EXTERNAL_IP>为Nginx Ingress对外暴露的IP。

可以看出,仅当Cookie中包含user_from_bj且值为always的请求才由新版本服务响应。

基于服务权重的流量切分

示例1:仅允许20%的流量被转发到新版本服务中,实现灰度发布。

1、创建Canary Ingress,并增加annotation,将20%的流量导入新版本的后端服务

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: canary-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"         # 启用Canary
    nginx.ingress.kubernetes.io/canary-weight: "20"    # 将20%的流量转发到Canary Ingress
    kubernetes.io/elb.port: '80'
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: '/'
            backend:
              serviceName: new-nginx      # 指定后端服务为new-nginx
              servicePort: 80

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

$ for i in {1..20}; do curl -H "Host: www.example.com" http://<EXTERNAL_IP>; done;
Old Nginx
Old Nginx
Old Nginx
New Nginx
Old Nginx
New Nginx
Old Nginx
New Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
New Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx

其中,<EXTERNAL_IP>为Nginx Ingress对外暴露的IP。

可以看出,有4/20的几率由新版本服务响应,符合20%服务权重的设置。

示例2:允许所有的流量被转发到新版本服务中,实现蓝绿发布。

1、创建Canary Ingress,并增加annotation,将100%的流量导入新版本的后端服务。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: canary-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"          # 启用Canary
    nginx.ingress.kubernetes.io/canary-weight: "100"    # 所有流量均转发到Canary Ingress
    kubernetes.io/elb.port: '80'
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: '/'
            backend:
              serviceName: new-nginx      # 指定后端服务为new-nginx
              servicePort: 80

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

$ for i in {1..10}; do curl -H "Host: www.example.com" http://<EXTERNAL_IP>; done;
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx

其中,<EXTERNAL_IP>为Nginx Ingress对外暴露的IP。

可以看出,所有的访问均由新版本服务响应,成功实现了蓝绿发布。

标签:Ingress,kubernetes,nginx,ingress,Nginx,灰度,io
From: https://www.cnblogs.com/deny/p/17523919.html

相关文章

  • 图片怎么转灰度图?在线转灰度图(批量)
    功能地址在线图片转灰度图,,图像识别语料生成,批量免费|TOFORU在线工具软件定制地址:https://tool.toforu.com/f/img_gray.html功能说明在线图片转灰度图,,图像识别语料生成,批量免费。功能使用原图上传转灰度处理后相关知识灰度图是一种将彩色图像转换为黑白图......
  • nginx下https绑定kkFileView
     需求用https域名访问kkFileView预览附件  实现用nginx代理添加https证书+key加上对应的端口(默认443可能不能用)。转发到kkFileView启动的默认端口。  总结:要用到nginx+https证书+kkFileView配置   nginx  kkfileview官网配置http://kkfilevi......
  • windows安装nginx服务
    https://www.cnblogs.com/lizhenfeng/p/17109915.htmlhttps://blog.csdn.net/qgbihc/article/details/121805661安装服务xxServer.exeinstall......
  • 在 CentOS 上安装 Nginx
    要在CentOS上安装Nginx,请按照以下步骤进行操作:1.更新系统软件包:sudoyumupdate2.安装EPEL存储库(ExtraPackagesforEnterpriseLinux):sudoyuminstallepel-release3.安装Nginx:sudoyuminstallnginx4.启动Nginx服务:sudosystemctlstartnginx5.设置Nginx开机启......
  • CentOS 9 x64 使用 Nginx、Supervisor 部署 Go/Golang 服务
    前言在CentOS9x64系统上,可以通过以下步骤来部署Golang服务。1.安装必要的软件包安装以下软件包:Golang:Golang编程语言Nginx:Web服务器Supervisor:进程管理工具Git:版本控制工具EPEL:扩展软件包可以通过以下命令来安装:yum-yupdateyuminstallnginxgolangepel-......
  • CentOS 9 x64 使用 Nginx、Supervisor 部署 Go/Golang 服务
    前言在CentOS9x64系统上,可以通过以下步骤来部署Golang服务。1.安装必要的软件包安装以下软件包:Golang:Golang编程语言Nginx:Web服务器Supervisor:进程管理工具Git:版本控制工具EPEL:扩展软件包可以通过以下命令来安装:yum-yupdateyuminstallnginxgolangepel......
  • MacOS M1 环境下的 Nginx + docker php-fpm7.4 部署fastadmin
    DokerfileFROMphp:7.4-fpm#php版本低于8的话安装swoole建议指定版本RUNapt-getupdate&&apt-getinstall-y\libfreetype6-dev\libjpeg62-turbo-dev\libpng-dev\libzip-dev\libssl-dev\git\unzip\&&do......
  • nginx和php的配置,解释php文件
    nginx和php环境安装好,安装步骤在此省略# 这里新加的# PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI协议默认配置.# Fastcgi服务器和程序(PHP,Python)沟通的协议.location~.php${root/usr/share/nginx/html;fastcgi_pass127.0.0.1:9000;fastcgi_index......
  • nginx安装
    nginx安装nginx安装(centos)在线安装下载nginx下载地址:https://nginx.org/en/download.html例如以1.22.1为例,下载地址:https://nginx.org/download/nginx-1.22.1.tar.gz解压nginx压缩包tar-zxvfnginx-1.22.0.tar.gz批量执行安装命令sudoyuminstall-ygcc-c++pcre......
  • Nginx 配置基础入门
    Nginx是什么Nginx("enginex")是一个高性能的HTTP和反向代理服务器,特点是占有内存少,并发能力强。Nginx官网:http://nginx.org/Nginx安装Nginx官网下载地址:http://nginx.org/en/download.html其中nginx-1.23.4这一列是Linux版本。Windows安装解压Nginx压缩包后,目录如下:启动nginx的方法1......