【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解

文章目录

    • 一、理论:实现灰度发布的几种场景
      • 1、场景一:将新版本灰度给部分用户
      • 2、场景二:按照比例流程给新版本
      • 3、实现灰度发布字段解释
    • 二、实践:
      • 1、实验前提环境
      • 2、基于Request Header(请求头)进行流量分割
      • 3、基于Cookie进行流量切分
      • 4、基于服务权重进行流量切分

一、理论:实现灰度发布的几种场景

1、场景一:将新版本灰度给部分用户

假设线上运行了一套对外提供 7 层服务的 Service A 服务,后来开发了个新版本 Service AA需要上线,但不想直接替换掉原来的 Service A,希望先灰度一小部分用户,等运行一段时间足够稳定了再逐渐全量上线新版本,最后平滑下线旧版本。

这个时候就可以利用 Nginx Ingress 基于 Header 或 Cookie 进行流量切分的策略来发布,业务使用 Header 或 Cookie 来标识不同类型的用户,我们通过配置 Ingress 来实现让带有指定 Header 或 Cookie 的请求被转发到新版本,其它的仍然转发到旧版本,从而实现将新版本灰度给部分用户。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YovV1ZHC-1690282841190)(D:\MD归档文档\IMG\image-20230723212305644.png)]

2、场景二:按照比例流程给新版本

假设线上运行了一套对外提供 7 层服务的 Service B 服务,后来修复了一些问题,需要灰度上线一个新版本 Service BB,但又不想直接替换掉原来的 Service B而是让先切 10% 的流量到新版本。

等观察一段时间稳定后再逐渐加大新版本的流量比例直至完全替换旧版本,最后再滑下线旧版本,从而实现切一定比例的流量给新版本。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1e0djcFR-1690282841192)(D:\MD归档文档\IMG\image-20230723212449420.png)]

3、实现灰度发布字段解释

Ingress-Nginx是一个K8S ingress工具,支持配置Ingress Annotations来实现不同场景下的灰度发布和测试。 Nginx Annotations 支持以下几种Canary规则:

假设我们现在部署了两个版本的服务,老版本和canary版本

  • nginx.ingress.kubernetes.io/canary-by-header:基于Request Header的流量切分,适用于灰度发布以及 A/B 测试。当Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口。

  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。

  • nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。权重为60意味着60%流量转到canary。权重为 100 意味着所有请求都将被发送到 Canary 入口。

  • nginx.ingress.kubernetes.io/canary-by-cookie:基于 Cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always时,它将被路由到 Canary 入口;当 cookie 值设置为 never时,请求不会被发送到 Canary 入口。

二、实践:

1、实验前提环境

1、增加V1环境:

cat v1.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-v1
spec:replicas: 1selector:matchLabels:app: nginxversion: v1template:metadata:labels:app: nginxversion: v1spec:containers:- name: nginximage: "openresty/openresty:centos"imagePullPolicy: IfNotPresentports:- name: httpprotocol: TCPcontainerPort: 80volumeMounts:    # 挂载卷- mountPath: /usr/local/openresty/nginx/conf/nginx.confname: configsubPath: nginx.confvolumes:          # 定义卷,引用configMap- name: configconfigMap:name: nginx-v1
---
apiVersion: v1
kind: ConfigMap
metadata:labels:app: nginxversion: v1name: nginx-v1
data:nginx.conf: |-worker_processes  1;events {accept_mutex on;multi_accept on;use epoll;worker_connections  1024;}http {ignore_invalid_headers off;server {listen 80;location / {access_by_lua 'local header_str = ngx.say("nginx-v1")';}}}
---
apiVersion: v1
kind: Service
metadata:name: nginx-v1
spec:type: ClusterIPports:- port: 80protocol: TCPname: httpselector:app: nginxversion: v1

2、增加V2环境:

cat v2.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-v2
spec:replicas: 1selector:matchLabels:app: nginxversion: v2template:metadata:labels:app: nginxversion: v2spec:containers:- name: nginximage: "openresty/openresty:centos"imagePullPolicy: IfNotPresentports:- name: httpprotocol: TCPcontainerPort: 80volumeMounts:- mountPath: /usr/local/openresty/nginx/conf/nginx.confname: configsubPath: nginx.confvolumes:- name: configconfigMap:name: nginx-v2
---
apiVersion: v1
kind: ConfigMap
metadata:labels:app: nginxversion: v2name: nginx-v2
data:nginx.conf: |-worker_processes  1;events {accept_mutex on;multi_accept on;use epoll;worker_connections  1024;}http {ignore_invalid_headers off;server {listen 80;location / {access_by_lua 'local header_str = ngx.say("nginx-v2")';}}}
---
apiVersion: v1
kind: Service
metadata:name: nginx-v2
spec:type: ClusterIPports:- port: 80protocol: TCPname: httpselector:app: nginxversion: v2

3、执行YAML文件

kubectl apply -f v1.yaml 
kubectl apply -f v2.yaml 

4、验证Pod是启动

kubectl get pods -o wide

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFyIkrU2-1690282841192)(D:\MD归档文档\IMG\image-20230725170445927.png)]

5、验证,请求Pod内容

curl http://10.244.247.2
curl http://10.244.84.134

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2zh1NApP-1690282841193)(D:\MD归档文档\IMG\image-20230725170540411.png)]

如上图,请求不同版本的环境,返回不同版本号,表示无误。

2、基于Request Header(请求头)进行流量分割

1、创建v1版本的ingress规则

cat v1-ingress.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-v1
spec:ingressClassName: nginxrules:- host: qinzt.ingress.comhttp:paths:- path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"pathType:  Prefixbackend:  #配置后端服务service:name: nginx-v1port:number: 80

执行YAML文件:

kubectl apply -f v1-ingress.yaml

访问验证一下:16.32.15.201:30080是我ingress-nginx访问地址

curl -H "Host: qinzt.ingress.com" http://16.32.15.201:30080
nginx-v1

2、创建ingress规则,基于Request Header进行流量分割

cat v2-request.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-header: "Region" #基于Request Header的流量切分nginx.ingress.kubernetes.io/canary-by-header-pattern: "cd|sz" #Header信息中带有 Region=cd,Region=sz的转发到此ingressname: nginx-request-v2
spec:ingressClassName: nginxrules:- host: qinzt.ingress.comhttp:paths:- path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"pathType:  Prefixbackend:  #配置后端服务service:name: nginx-v2port:number: 80

执行YAML文件:

kubectl apply -f v2-request.yaml

访问验证一下:16.32.15.201:30080是我ingress-nginx访问地址

curl -H "Host: qinzt.ingress.com" -H "Region: cd" http://16.32.15.201:30080
curl -H "Host: qinzt.ingress.com" -H "Region: sz" http://16.32.15.201:30080

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJ252M5a-1690282841193)(D:\MD归档文档\IMG\image-20230725173228547.png)]

OK,可以看到上图,携带Region: cdRegion: sz请求头消息,会转发到V2环境。

3、基于Cookie进行流量切分

与前面 Header 类似,不过使用 Cookie 就无法自定义 value 了,这里以模拟灰度成都地域用户为例,仅将带有名为 user_from_cd 的 cookie 的请求转发给当前V2环境 。

1、先删除前面基于 Header 的流量切分的 Ingress

kubectl delete -f v2-request.yaml

2、创建基于cookie 转发的ingress规则

cat v2-cookie.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_cd" # 匹配cookie携带user_from_cd,使用此ingress规则name: nginx-cookie-v2
spec:ingressClassName: nginxrules:- host: qinzt.ingress.comhttp:paths:- path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"pathType:  Prefixbackend:  #配置后端服务service:name: nginx-v2port:number: 80

执行YAML文件

kubectl apply -f v2-cookie.yaml 

3、测试验证,http://16.32.15.201:30080是我ingress nginx地址

curl -s -H "Host: qinzt.ingress.com" --cookie "user_from_cd=always" http://16.32.15.201:30080
nginx-v2curl -s -H "Host: qinzt.ingress.com" --cookie "user_from_bj=always" http://16.32.15.201:30080
nginx-v1

可以看到只有cookie=user_from_cd的才会转发到V2的ingress

4、基于服务权重进行流量切分

基于服务权重的直接定义需要导入的流量比例,这里以导入 10% 流量到 v2 环境版本为。

1、删除上面基于cookie的ingress规则

kubectl delete -f v2-cookie.yaml

2、创建基于权重流量分配的ingress规则

cat v2-weight.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "10"name: nginx-weight-v2
spec:ingressClassName: nginxrules:- host: qinzt.ingress.comhttp:paths:- path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"pathType:  Prefixbackend:  #配置后端服务service:name: nginx-v2port:number: 80

执行YAML文件:

kubectl apply -f v2-weight.yaml

3、测试验证

for i in {1..10}; do curl -H "Host: qinzt.ingress.com" http://16.32.15.201:30080; done;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XaTyjsQD-1690282841194)(D:\MD归档文档\IMG\image-20230725183809515.png)]

OK,如上图大约10%的记录会请求到V2环境上面

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

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

相关文章

93.qt qml-自定义Table优化(新增:水平拖拽/缩放自适应/选择使能/自定义委托)

之前我们更新了90.qt qml-Table表格组件(支持表头表尾固定/自定义颜色/自定义操作按钮/排序)_qml 表格_诺谦的博客-CSDN博客 但是一直没出源码,是因为该demo还存在问题,那就是表头表尾固定下,如果是半透明状态下,会看到表头表尾固定后的内容,所以只能重构代码,不能使用重…

Vue3组合式API+TypeScript写法入门

文章目录 前言1.reactive2.ref3.props4.computed5.emit6.watch总结 前言 参考Vue3官网. 本篇以组合式API为例, 但不包含setup语法糖式写法. 原本打算结合class-component, Vue3不推荐就不用了: OverView|Vue Class Component. 而且是不再推荐基于类的组件写法, 推荐单文件组件…

Android App 持续集成性能测试:启动流量

目录 前言: get app UID 获取流量数据 获得启动流量数据 总结 前言: Jenkins 是一种开源的持续集成工具,可以帮助我们更加方便地进行软件开发和测试工作。通过 API 远程管理 Jenkins 可以帮助我们更加方便地进行 Jenkins 的配置和管理工…

react实现路由跳转动画

下载插件 npm i react-transition-group 配置路由 import { createBrowserRouter as ReactRouter,Navigate } from "react-router-dom";import App from ../App.js import Login from "../view/login.js"; import Home from "../home.js"; co…

了解 3DS MAX 3D摄像机跟踪设置:第 4 部分

推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 转到合成>新合成以创建新合成。 将“宽度”和“高度”值分别设置为 1280 和 720。将帧速率设置为 25,将持续时间设置为 12 秒。单…

Flask 文件上传,删除上传的文件

目录结构 app.py from flask import Flask, request, render_template, redirect, url_for import osapp Flask(__name__) BASE_DIR os.getcwd() UPLOAD_FOLDER os.path.join(BASE_DIR, testfile)app.route(/) def home():files os.listdir(UPLOAD_FOLDER)return render_t…

欧盟新规,燃油噩梦?2025年起,高速公路每60公里设立一处快充站

根据外媒The Verge报道,欧洲电动汽车用户将获得更多便捷的待遇,同时还能减少有害温室气体排放,这得益于欧盟理事会最新通过的法规。 根据欧盟的法规要求,自2025年起,TEN-T高速公路系统在欧洲将需要每隔60公里设立一座高…

Langchain 和 Chroma 的集成

Langchain 和 Chroma 的集成 1. Chroma2. 基本示例​3. 基本示例(包括保存到磁盘)4. 将 Chroma Client 传递到 Langchain ​5. 基本示例(使用 Docker 容器)6. 更新和删除7. 带分数的相似性搜索​ 1. Chroma Chroma 是一个人工智能原生开源矢量数据库,专注于开发人员…

ES6基础知识六:你是怎么理解ES6中 Promise的?使用场景?

一、介绍 Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大 在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码 doSomething(function(resu…

[ 容器 ] Harbor 私有仓库的部署与管理

目录 一、什么是Harbor二、Harbor的特性三、Harbor的构成四、Harbor 部署五、关于 Harbor.cfg 配置文件中有两类参数:所需参数和可选参数六、维护管理Harbor 一、什么是Harbor Harbor 是 VMware 公司开源的企业级 Docker Registry 项目,其目标是帮助用户…

jQuery的DOM操作之笔记总结

jQuery的DOM操作之笔记总结 首先我们来介绍一下什么是DOM 简述: 1.DOM全称Document Object Model(文档对象模型)。 2.每个文档都是一棵DOM结构的树,文档里的很多元素,就像树上的很多节点,或是分叉的树枝…

知识库数据导出为excel-使用JavaScript实现在浏览器中导出Excel文件

我们智能客服知识库机器人已经开发完成,后端数据库是使用的qdrant向量数据库,但是该数据库并没有导出备份功能,所以我按简单的纯前端实现知识库导出excel数据 使用第三方库(如SheetJS) SheetJS是一个流行的JavaScript库,可帮助处理…

腾讯云 Cloud Studio 实战训练营——快速构建React完成点餐H5页面

目录 ​编辑 一、前言 1、什么是腾讯云 Cloud Studio 2、本文实验介绍 二、前期准备工作 1、注册 Cloud Studio 2、初始化工作空间 三、开发一个简版的点餐系统页面 1、安装依赖 1.1、安装 antd-mobile 1.2、安装 less 和 less-loader 1.3、暴露 webpack 配置文件 …

OpenCV实现照片换底色处理

目录 1.导言 2.引言 3.代码分析 4.优化改进 5.总结 1.导言 在图像处理领域,OpenCV是一款强大而广泛应用的开源库,能够提供丰富的图像处理和计算机视觉功能。本篇博客将介绍如何利用Qt 编辑器调用OpenCV库对照片进行换底色处理,实现更加…

Stable Diffusion生成艺术二维码

Stable Diffusion生成艺术二维码 文章会有浏览问题,点击此处查看原文 首先需要一个Stable Diffusion服务环境,《Stable Diffusion服务环境搭建(远程服务版)》如果你已经有了那就忽略 一、准备一个比较好的二维码底图 首先解析二…

STC12C5A系列单片机片内看门狗的应用

wdt.c #include "wdt.h"void wdt_init(void) {WDT_CONTR 0x24; // 0010 0100 - 1.1377s }void wdt_feed(void) {WDT_CONTR | 0x10; // 喂狗 }wdt.h #ifndef _WDT_H_ #define _WDT_H_#include "stc12c5a60s2.h"// 函数声明 extern void wdt_init(void); …

uniapp开启消息通知/提示(使用uniPush)

亲爱的小伙伴们,最近对uniPush有稍许研究,当前研究出一些心得,现在分项给大家,希望对大家的uniapp之路有所帮助。本次的教程是教会你如何使用uniPush自定义消息通知,同时还附带添加消息提示音添加,多的不说…

【Spring MVC学习】连接 接收请求参数 响应返回参数

目录 前言:认识Spring MVC 🌷1、什么是MVC? 一、建立连接(5个注解) 🌷1、RequestMapping注解:注册接⼝的路由映射(默认返回页面) 🌷2、ResponseBody注解&#xff1a…

unity调用c++dll时变量处理问题

在C中为了处理方便可以将有些局部变量变为全局变量。 以下面三个变量为例 如果还有新全局变量需要这其来赋值,就会有问题。 如下面的body1_ptr为了dll生成处理方便,变为全局变量后,这个指针变赋值就会有问题。 因为geometry_path这个只在调…

Ubuntu22.04上部署Lua开发环境

需求背景 想在Ubuntu22.04上搭建一下Lua的开发环境,其实步骤比较简单的,此文章也适用于Ubuntu主机环境搭建Lua,如果想在在Ubuntu内部署一个容器,然后在容器内搭建Lua的环境,可以先参考容器的创建过程 ubuntu22.04上如何创建有pri…