Ingress企业实战:金丝雀与蓝绿发布篇

news2024/12/23 5:21:05

背景

现如今,越来越多的应用采用了微服务架构,这也导致了应用数量相比传统模式更多,管理更加复杂,发布更加频繁,如果直接将新版本上线发布给全部用户。一旦遇到线上事故(或BUG),对用户的影响极大,解决问题周期较长,甚至有时不得不回滚到前一版本,严重影响了用户体验。为了保证整体系统的稳定,风险降到最低,我们可以采用灰度发布与蓝绿发布等不同的发布方式。

什么是金丝雀发布

金丝雀发布,又称灰度发布,是指通过让小部份用户流量引入的新版本进行测试,如果一切顺利,则可以增加(可能逐渐增加)百分比,逐步替换旧版本。如在过程中出现任何问题,则可以中止并快速回滚到旧版本。最简单的方式是随机选择百分比请求到金丝雀版本,但在更复杂的方案下,则可以基于请求的内容、特定范围的用户或其他属性等。

图片

什么是蓝绿发布

蓝绿发布,提供了一种零宕机的部署方式,是一种以可观测的方式发布应用的方式,目的减少发布过程中停止时间。在保留老版本的同时部署新版本,将两个版本同时在线,新版本和老版本相互热备,通过切换路由权重的方式(非0即100)实现应用的不同版本上线或者下线,如果有问题可以快速地回滚到老版本。这样做的好处是无需停机,并且风险较小。

图片

示例应用部署

部署示例版本:

$ cat demo.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  labels:
    app: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        imagePullPolicy: Always
        image: registry.cn-shanghai.aliyuncs.com/kubesre01/demo:v1
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: demo-svc
spec:
  type: ClusterIP
  selector:
    app: demo
  ports:
    - port: 8080
      targetPort: 8080
$ kubectl apply -f demo.yml
deployment.apps/demo created

部署新版本:

$ cat demo_new.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-new
  labels:
    app: demo-new
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-new
  template:
    metadata:
      labels:
        app: demo-new
    spec:
      containers:
      - name: demo-new
        imagePullPolicy: Always
        image: registry.cn-shanghai.aliyuncs.com/kubesre01/demo:v2
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: demo-new-svc
spec:
  type: ClusterIP
  selector:
    app: demo-new
  ports:
    - port: 8080
      targetPort: 8080

$ kubectl apply -f demo_new.yml
deployment.apps/demo_new created

创建Ingress记录:

$ cat demo-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-svc 
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-ingress.yml
ingress.networking.k8s.io/demo-ingress created

# 访问如下内容说明部署成功!
$ curl  http://demo.kubesre.com/info
{"message":"云原生运维圈!"}

到此为止,示例应用与新版本已部署完毕!

基于客户端请求头的流量切分

假设线上已运行了一套对外提供的七层demo应用,此时开发了一些新的功能,需要上线新版本demo应用,但是又不想直接替换成新版本demo应用,而是希望将请求头包含user=kubesre的客户端请求转发到新版本demo应用中,进行验证测试新版本demo应用,等测试验证通过并稳定后,可将所有流量从老版本demo应用切换到新版本demo应用中,再平滑地将老版本demo应用下线。创建新版本Ingress:

$ cat demo-new-canary.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-new-canary
  annotations:
    # 开启Canary。
    nginx.ingress.kubernetes.io/canary: "true"
    # 请求头为user
    nginx.ingress.kubernetes.io/canary-by-header: "user"
    # 请求头user的值为kubesre时,请求才会被路由到新版本服务new-new中。
    nginx.ingress.kubernetes.io/canary-by-header-value: "kubesre"

spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-new-svc
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-new-canary.yml
ingress.networking.k8s.io/demo-new-canary created

测试验证:

# 请求头为user: kubesre,访问到新的版本
$ curl -H "user: kubesre" http://demo.kubesre.com/info
{"message":"云原生运维圈!新版本"}

# 其他则访问到老的版本
$ curl  http://demo.kubesre.com/info
{"message":"云原生运维圈!"}

基于客户端来源IP的流量切分

假设线上已运行了一套对外提供的七层demo应用,此时开发了一些新的功能,需要上线新版本demo应用,又不想直接替换成新版本demo应用,而是只希望公司内部人员能访问到新版本demo应用中,进行测试验证新版本demo应用,非公司内部人员访问还是访问到老版本应用中。等公司内部人员测试验证通过并稳定后,可将所有流量从老版本demo应用切换到新版本demo应用中,再平滑地将老版本demo应用下线。创建新版本Ingress:

$ cat demo-new-canary.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-new-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Forwarded-For"
    # 假设客户端来源IP为123.456.789.123
    nginx.ingress.kubernetes.io/canary-by-header-value: "123.456.789.123"
    
spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-new-svc
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-new-canary.yml
ingress.networking.k8s.io/demo-new-canary created

测试验证:

# 通过请求头模拟来源IP,真实环境不需要
$ curl -H "X-Forwarded-For:123.456.789.123" http://demo.kubesre.com/info
{"message":"云原生运维圈!新版本"}

# 其他则访问到老的版本
$ curl  http://demo.kubesre.com/info
{"message":"云原生运维圈!"}

基于服务权重的流量切分

假设线上已运行了一套对外提供的七层demo应用,此时修复了一些问题,需要上线新版本demo应用,又不想直接替换成新版本demo应用,而是希望将20%的流量切换新版本。待运行一段时间稳定后,可将所有流量从老版本demo应用切换到新版本demo应用中,再平滑地将老版本demo应用下线。创建新版本Ingress:

$ cat demo-new-canary.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-new-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Forwarded-For"
    # 将20%的流量转发到新版本
    nginx.ingress.kubernetes.io/canary-weight: "20"
    
spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-new-svc
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-new-canary.yml
ingress.networking.k8s.io/demo-new-canary created

测试验证:

# 可以看出,有4/20的几率由新版本服务响应,符合20%服务权重的设置。
$ for i in {1..20}; do curl http://demo.kubesre.com/info; done;
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!新版本"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!新版本"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!新版本"}{
"message":"云原生运维圈!新版本"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}

注解说明

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。

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

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

相关文章

哪些客户适合打Cold Call?

都知道Cold Call是外贸营销中一种重要的销售方式,相比邮件跟进,它可以可实时交流,获取需求,解决问题,展示人情味,提升好感度,提高转化率。但由于陌生性,当下如果没有需求的话&#x…

“万恶”之源的KieServices,获取代码就一行,表面代码越少里面东西就越多,本以为就是个简单的工厂方法,没想到里面弯弯绕绕这么多东西

Drools用户手册看了得有一段时间了,现在开始看源码了,因为每次使用drools都会看见这么一段代码: 代码段1 起手代码 KieServices ks KieServices.Factory.get(); 那我就从这段代码出发开始研究drools的源码吧,这么一小段代码起初…

文件操作/IO

文件 文件是一种在硬盘上存储数据的方式,操作系统帮我们把硬盘的一些细节都封装起来了,程序员只需要了解文件相关的接口即可,相当于操作文件就是间接的操作硬盘了 硬盘用来存储数据,和内存相比硬盘的存储空间更大,访问…

代码运行出现:No module named ‘torch_geometric‘

这是没有torch_geometric库导致的,但是不能像一般库安装‘pip install 库名’或者‘conda install 库名’进行安装,经常会报错!!! 需要先安装四个小部件再安装torch_geometric,具体安装步骤如下: step 1:查看自己环境…

简约时尚的健康手表,智能守护每一刻,dido Y60上手

智能手表是现在很流行的一种智能设备,很多品牌都推出了各种各样的产品,但是大部分都更侧重功能和运动的方面,健康监测往往只是配角,而随着人们对自己的健康越来越重视,有些朋友只是单纯的需要一块专业的健康监测手表。…

SIFT 算法 | 如何在 Python 中使用 SIFT 进行图像匹配

介绍 人类通过记忆和理解来识别物体、人和图像。你看到某件事的次数越多,你就越容易记住它。此外,每当一个图像在你的脑海中弹出时,它就会将该项目或图像与一堆相关的图像或事物联系起来。如果我告诉你我们可以使用一种称为 SIFT 算法的技术来教机器做同样的事情呢? 尽管…

部署私有知识库项目FastGPT

FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景。 项目源码: GitHub - c121914yu/FastGPT: A platform that uses the Open…

【推荐】7个可以改变我们在3dMax中工作方式的插件

​以下给大家介绍的这些插件,将改变我们在3d Max中的工作方式,让生活更加轻松。 Glue Utility(粘合实用程序) 这些年来,这个工具改变了我的游戏规则。它使我能够执行许多任务,否则这些任务要么是不可能…

在矩池云使用 ChatGLM2-6B ptuning

本文参考 ChatGLM2-6B 官方文档,在矩池云复现了对于 ChatGLM2-6B 模型基于 P-Tuning v2 的微调。P-Tuning v2 将需要微调的参数量减少到原来的 0.1%,再通过模型量化、Gradient Checkpoint 等方法,最低只需要 7GB 显存即可运行。 官方文档地址…

一百五十六、Kettle——Linux上安装的Kettle9.3连接ClickHouse数据库(亲测,附流程截图)

一、目标 kettle9.3在Linux上安装好后,需要与ClickHouse数据库建立连接 二、前提准备 (一)在Linux已经安装好kettle并可以启动kettle (二)已知kettle和ClickHouse版本 1、kettle版本是9.3 2、ClickHouse版本是21…

深度学习优化器

1、什么是优化器 优化器用来寻找模型的最优解。 2、常见优化器 2.1. 批量梯度下降法BGD(Batch Gradient Descent) 2.1.1、BGD表示 BGD 采用整个训练集的数据来计算 cost function 对参数的梯度: 假设要学习训练的模型参数为W,代价函数为J(W),…

项目管理工具探析:详细介绍四种常用选择

市场上的项目管理工具,主要是解决项目计划制定、任务协作、文档协作这几方面的问题, 下面简单聊聊一些自己用过的工具: 1、Excel/在线协作表格 如果项目简单,任务数少,没什么依赖,那么就可以用Excel来做项目…

静电放电发生器的操控模式和释放模式有哪些方式

静电放电是一种自然现象 ,当两种不同介电强度的材料相互摩擦时,就会产生静电电荷,当其中一种材料上的静电荷积累到一定程度,在与另外一个物体接触时,就会通过这个物体到大地的阻抗而进行放电。静电放电及影响是电子设备…

四大运营商的大流量卡测评,看完您会选哪个运营商?

很多朋友都说网上的流量卡资费是真的便宜,但是小编认为资费便宜归便宜,但是运营商的小心思也有不少。 ​ 今天小编就带大家看一看三大运营商推出的正规流量卡都有哪些小心思? 首先,移动推出的线上大流量卡数量是最少的&#xff…

算法|Day37 动态规划5

LeetCode 1049- 最后一块石头的重量 II 题目链接:力扣 题目描述:有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量…

Blazor : Component parameter should be auto property,无法修改get;set;

文章目录 Blazor 无法在get;set;里面定义方法 Blazor 无法在get;set;里面定义方法 Blazor Component组件 其实原因就是微软觉得你在get;set;里面放自定义逻辑,太容易出现无限父子回调的问题。如果你要在get时候进行某种逻辑,那你就在OnParameterSetAs…

归并排序 与 计数排序

目录 1.归并排序 1.1 递归实现归并排序: 1.2 非递归实现归并排序 1.3 归并排序的特性总结: 1.4 外部排序 2.计数排序 2.1 操作步骤: 2.2 计数排序的特性总结: 3. 7种常见比较排序比较 1.归并排序 基本思想: 归并排序(MERGE-SORT)是建立在归并操作上的一种…

Qgis统计面要素内点的数量,不同类型点的数量

简单: 统计面要素内点的数量。 工具栏直接搜索:统计点在多边形中的数量 统计面要素内不同类型点的数量。 查看QGIS-11 “按位置连接属性工具”——“按类别统计工具”——pandas透视表统计 数据透视表参考链接 参考链接: QGIS入门-9 统计面…

leetcode375. 猜数字大小 II(动态规划-java)

猜数字大小 II lc - 375 猜数字大小 II题目描述暴力递归 记忆化搜索代码演示动态规划 动态规划 lc - 375 猜数字大小 II 题目描述 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。 你来猜我选了哪个数字。 如果你猜到正确的数字&…

开学季 | 新生入学必备好物,快来看看你漏掉了哪些!

一转眼年就过完了,又到了开学季。有很多学生又要重新走进校园,开始自己的学生宿舍生活。作为一个从初中就开始住宿舍的过来人,有一些东西确实是我当时在学校里用过的,非常好用的神器,可以非常好的帮助我们生活、学习或…