首页 > 系统相关 >Ingress-Nginx 灰度(金丝雀)发布

Ingress-Nginx 灰度(金丝雀)发布

时间:2023-06-25 19:33:15浏览次数:41  
标签:ingress kubernetes Nginx 金丝雀 canary nginx 灰度 io new

使用 Ingress-Nginx 进行灰度(金丝雀)发布

Ingress-Nginx Canary介绍

Nginx Ingress Controller 作为项目对外的流量入口和项目中各个服务的反向代理。
官方文档概述:Annotations - Ingress-Nginx Controller (kubernetes.github.io)

Nginx Annotations 的几种 Canary 规则:

Annotation                                                                  说明
nginx.ingress.kubernetes.io/canary              必须设置该Annotation值为true,否则其它规则将不会生效。取值:true:启用canary功能。false:不启用canary功能。
nginx.ingress.kubernetes.io/canary-by-header    表示基于请求头的名称进行灰度发布。请求头名称的特殊取值:  always:无论什么情况下,流量均会进入灰度服务。 never:无论什么情况下,流量均不会进入灰度服务。 若没有指定请求头名称的值,则只要该头存在,都会进行流量转发。
nginx.ingress.kubernetes.io/canary-by-header-value    表示基于请求头的值进行灰度发布。 需要与canary-by-header头配合使用。
nginx.ingress.kubernetes.io/canary-by-header-pattern    表示基于请求头的值进行灰度发布,并对请求头的值进行正则匹配。 需要与canary-by-header头配合使用。 取值为用于匹配请求头的值的正则表达式。
nginx.ingress.kubernetes.io/canary-by-cookie    表示基于Cookie进行灰度发布。例如,nginx.ingress.kubernetes.io/canary-by-cookie: foo。 Cookie内容的取值:  always:当foo=always,流量会进入灰度服务。 never:当foo=never,流量不会进入灰度服务。 只有当Cookie存在,且值为always时,才会进行流量转发。
nginx.ingress.kubernetes.io/canary-weight    表示基于权重进行灰度发布。 取值范围:0~权重总值。 若未设定总值,默认总值为100。
nginx.ingress.kubernetes.io/canary-weight-total    表示设定的权重总值。 若未设定总值,默认总值为100。

注意:不同灰度方式的优先级 由高到低 为:

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

二、ingress-nginx Canary实现

2.1、基于客户端请求的流量切分场景

假设当前线上环境,您已经有一套服务Service V1对外提供7层服务,此时上线了一些新的特性,需要发布上线一个新的版本Service V2。
希望将请求头中包含foo=bar或者Cookie中包含foo=bar的客户端请求转发到Service V2服务中。
待运行一段时间稳定后,可将所有的流量从Service V1切换到Service V2服务中,再平滑地将Service V1服务下线。

2.2、实现方式:

通过上面的annotation来实现灰度发布,其 思路如下:
在集群中部署两套系统,一套是stable版本(old-nginx),一套是canary版本(new-nginx),两个版本都有自己的service;
定义两个ingress配置,一个正常提供服务,一个增加canary的annotation;
待canary版本无误后,将其切换成stable版本,并且将旧的版本下线,流量全部接入新的stable版本

old-nginx 创建Deployment、Service、Ingress。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: old-nginx
  namespace: nginx-gray
  labels:
    run: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      run: old-nginx
  template:
    metadata:
      labels:
        run: old-nginx
    spec:
      containers:
      - name: old-nginx
        image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: old-nginx
  namespace: nginx-gray
spec:
  selector:
    run: old-nginx
  type: ClusterIP
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name:  old-nginx
  namespace: nginx-gray
spec:
  rules:
    - host: nginx.kubernets.cn
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            serviceName: old-nginx
            servicePort: 80
View Code

测试验证:(预期输出:old)

# curl -H "Host: nginx.kubernets.cn" http://nginx.kubernets.cn

灰度发布新版本服务:

new-nginx 创建Deployment、Service。

设置访问新版本服务的路由规则。
设置满足特定规则的客户端才能访问新版本服务。以下示例仅请求头中满足foo=bar的客户端请求才能路由到新版本服务。

[root@master1 nginx-gray]# cat new-new-nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: new-nginx
  namespace: nginx-gray
  labels:
    run: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      run: new-nginx
  template:
    metadata:
      labels:
        run: new-nginx
    spec:
      containers:
      - name: new-nginx
        image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
        imagePullPolicy: Always
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: new-nginx
  namespace: nginx-gray
spec:
  selector:
    run: new-nginx
  type: ClusterIP
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name:  new-nginx-ingress
  namespace: nginx-gray
  annotations:
# 开启Canary。
    nginx.ingress.kubernetes.io/canary: "true"
#请求头为foo。
    nginx.ingress.kubernetes.io/canary-by-header: "foo"
# 请求头foo的值为bar时,请求才会被路由到新版本服务new-nginx中。
    nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
# 在满足上述匹配规则的基础上仅允许50%的流量会被路由到新版本服务new-nginx中。
#    nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
  rules:
    - host: nginx.kubernets.cn
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            serviceName: new-nginx
            servicePort: 80

按照header头信息转发流量:

# 正常访问:
$ curl -H "Host: nginx.kubernets.cn" http://nginx.kubernets.cn
old
# 访问新的服务:
$ curl -H "Host: nginx.kubernets.cn" -H "foo: bar" http://nginx.kubernets.cn
new

可以看到,仅请求头中满足foo=bar的客户端请求才能路由到新版本服务。

需求:请求头中满足foo=bar的客户端请求,若不包含该请求头,再将50%的流量路由到新版本服务中。

测试验证:(几乎可以达到50%请求分布)

# curl -H "Host: nginx.kubernets.cn" http://nginx.kubernets.cn
new
# curl -H "Host: nginx.kubernets.cn" http://nginx.kubernets.cn
old

系统运行一段时间后,当新版本服务已经稳定并且符合预期后,需要下线老版本的服务 ,仅保留新版本服务在线上运行。

为了达到该目标,需要将旧版本的Service指向新版本服务的Deployment,并且删除旧版本的Deployment和新版本的Service。

三、金丝雀发布的高级功能

如上只简单介绍了一些ingress开源默认支持的Annotation。
日常工作中基于开源ingress-nginx实线的高级功能:
通过修改nginx.ingress.kubernetes.io/configuration-snippet配置,并且配置正则实现:
当header头中有关键字(foo 或 new)字段的时候,自动将流量转发至new-nginx;
nginx.ingress.kubernetes.io/configuration-snippet (用于插入 location 块代码段);
nginx.ingress.kubernetes.io/server-snippet (用于插入 server 块中的代码段);

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name:  new-nginx-ingress
  namespace: nginx-gray
  annotations:
    #nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/configuration-snippet: |
          if ($http_name ~ "^.*foo$|^.*new$") {
              proxy_pass http://new-nginx.nginx-gray:80;
              break;  
          }  
spec:
  rules:
    - host: nginx.kubernets.cn
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            serviceName: old-nginx
            servicePort: 80             
        - path: /
          pathType: Prefix
          backend:
            serviceName: new-nginx
            servicePort: 80

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:ingress,kubernetes,Nginx,金丝雀,canary,nginx,灰度,io,new
From: https://www.cnblogs.com/yypc/p/17503780.html

相关文章

  • nginx
    Nginx是一种高性能的Web服务器软件,它可以作为反向代理服务器、负载均衡器、HTTP缓存、静态资源服务器等用途。Nginx的主要作用包括:静态资源服务器:Nginx支持快速、高效地响应静态文件的请求,包括HTML页面、CSS文件、图片等。它可以快速地将静态资源缓存起来,提高Web应用的访问速度......
  • Nginx https配置http的图片服务
    1.在Nginx配置网站的https服务#HTTPSserver#server{listen443ssl;server_namelocalhost,10.11.1.68;ssl_certificateca.crt;ssl_certificate_keyca.key;ssl_session_cacheshared:SSL:1m;......
  • Keepalived+Nginx 高可用集群架构
                                  Keepalived+Nginx高可用集群(主从模式)                                             ......
  • 【Nginx】- 优化实践
    Nginx的优化Linux安装Nginx安装依赖包//一键安装下面四个依赖gcc/zlib/prec-devel/opensslyum-yinstallgcczlibzlib-develpcre-developensslopenssl-devel因为Nginx依赖于gcc的编译环境,所以,需要安装编译环境来使Nginx能够编译起来yuminstallgcc-c++Nginx......
  • 数字图像处理《3、灰度变换与空间滤波》
      第三章:空间域处理1、 空间域处理是指在图像的像素上操作,主要分为灰度变换和空间滤波:灰度变换的主要目的是对比度处理和阀值处理;空间滤波的主要目的是改善图像的性能,如锐化图像;2、 基本的灰度变换函数:图像反转、对数变换、伽马变换、分段线性变换;3、 还有基于直方图的灰度......
  • Nginx的stub_status
    Nginx的stub_status模块是一个官方提供的一个用于实时监控Nginx服务器状态信息的模块。它通过HTTP接口提供了一个简单的页面,展示了当前Nginx服务器的关键性能指标和连接状态。启用stub_status模块后,可以通过访问特定的URL来获取Nginx的状态信息。默认情况下,该URL为http://y......
  • 如何在nginx增加健康检查接口?
    在docker中部署的nginx或者在nginx部署的nginx一般是需要一个健康检查接口的 这样的话,就可以确定容器当前的状态是否是健康的 那么,如何给nginx增加一个健康检查的接口呢? 接下来呢,我们就演示一个在nginx中如何增加健康检查的接口 1、打开nginx的配置文件(nginx.conf) ......
  • k8s 创建nginx
    1、在kubenetes集群中创建一个pod创建nginx,拉取镜像kubectlcreatedeploymentnginx--image=nginx2、查看镜像是否下载成功kubectlgetpodstatus为running表示拉取完成 3、暴露Nginx端口kubectlexposedeploymentnginx--port=80--type=NodePort4、查看Nginx端口......
  • ubuntu安装nginx建立静态站
    版本:服务器ubuntu20.04本地windows10远程工具xshell71、nginx官网 http://nginx.org/en/docs/2、点击installingnginx3、点击 InstallationonLinux下的packages4、点击Ubuntu5、开始傻瓜式操作,一定!一定!一定!使用root安装和使用nginx哦!我以下所有执行都是roo......
  • 3分钟了解MacBook m1芯片使用docker安装nginx
    1、先安装nginxdockerpullnginx2、创建目录mkdir-p/Users/benjie/software/nginx/confmkdir-p/Users/benjie/software/nginx/logsmkdir-p/Users/benjie/software/nginx/html3、启动nginx实例,为了复制配置dockerrun--namenginx-p80:80-dnginx:latest4、......