K8S Deployment 实现 金丝雀(灰度) 发布

embedded/2025/2/7 5:42:23/

一、何为金丝雀(灰度)发布

金丝雀发布(Canary Release)是一种软件部署策略,它允许在生产环境中以可控的方式逐步引入新的软件版本,从而降低新版本发布带来的风险。

1.1、起源与概念

  • 起源:该术语源于17世纪英国煤矿工人的做法,他们会携带金丝雀下井。由于金丝雀对瓦斯等有毒气体非常敏感,当井下有毒气体浓度升高时,金丝雀会先出现不适甚至死亡,从而为矿工提供危险预警。在软件发布中,金丝雀发布的原理类似,先向一小部分用户发布新版本,以此作为 “金丝雀” 来提前发现潜在问题。
  • 概念:在金丝雀发布过程中,新版本软件首先会在一小部分用户或服务器上进行部署和测试。通过监控这部分用户的反馈和相关指标(如性能、错误率等),评估新版本的稳定性和兼容性。如果一切正常,再逐步扩大新版本的使用范围,直到完全替换旧版本;若出现问题,则可以及时回滚,避免影响大部分用户。
  • 图示:如下图所示,某服务当前版本为v1,现在新版本v2要上线。为确保流量在服务升级过程中平稳无损,采用金丝雀发布方案,逐步将流量从老版本迁移至新版本。

       

1.2、实现步骤

  1. 环境准备:确保生产环境稳定运行,同时准备好新版本的软件。可以使用容器编排工具(如 Kubernetes)来管理不同版本的部署。
  2. 选择金丝雀组:确定一小部分用户或服务器作为金丝雀组。可以根据用户特征(如地理位置、用户类型等)或服务器标识进行划分。
  3. 部署新版本:将新版本软件部署到金丝雀组中。在这个阶段,旧版本仍然为大部分用户提供服务。
  4. 监控与评估:密切监控金丝雀组的各项指标,如响应时间、吞吐量、错误率等。收集用户反馈,及时发现新版本可能存在的问题。
  5. 决策与扩展:根据监控结果和评估数据,决定是否继续扩大新版本的使用范围。如果新版本表现良好,则逐步增加使用新版本的用户或服务器数量;如果出现严重问题,则立即回滚到旧版本。

1.3、优点

  • 降低风险:通过先在小范围内测试新版本,可以提前发现并解决潜在的问题,避免对大量用户造成影响。
  • 快速反馈:能够快速收集到真实用户对新版本的反馈,有助于及时调整和优化软件。
  • 灵活控制:可以根据实际情况灵活调整新版本的推广速度和范围,确保发布过程可控。

1.4、缺点

  • 管理复杂:需要对不同版本的软件进行管理和监控,增加了运维的复杂性。有时候应用,它不仅仅只有镜像,还包括它所依赖的中间件环境,倘若新旧版本依赖的环境配置不同,采用金丝雀发布,无疑增加了管理的复杂度。
  • 资源消耗:在发布过程中,需要同时维护旧版本和新版本的环境,会消耗更多的资源。

 二、镜像准备

假设有如下三个节点的 K8S 集群:

k8s31master 是控制节点

k8s31node1、k8s31node2 是工作节点

容器运行时是 containerd

使用 springboot 打包两个镜像 hellok8s-1.0.jar.gzhellok8s-2.0.jar.gz

hellok8s:1.0

@RestController
public class HelloController {@GetMapping("/sayHello")@ResponseBodypublic String sayHello() {# 蓝return "Hello,I am Blue";}
}

hellok8s:2.0

@RestController
public class HelloController {@GetMapping("/sayHello")@ResponseBodypublic String sayHello() {# 绿return "Hello,I am Green";}
}

它们的区别仅在输出的问候信息不同,一个 Blue、一个 Green.

  •  导入镜像
# node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import hellok8s-1.0.jar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images import hellok8s-2.0.jar.gz
# node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import hellok8s-1.0.jar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images import hellok8s-2.0.jar.gz

三、Deployment 实现

  • deploy-blue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-blue
spec:replicas: 3selector:matchLabels:app: hellok8sversion: "1.0"template:metadata:labels:app: hellok8sversion: "1.0"spec:containers:- name: hellok8simage: hellok8s:1.0imagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:httpGet:path: /port: 8080initialDelaySeconds: 5periodSeconds: 10readinessProbe:httpGet:path: /port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:httpGet:path: /port: 8080initialDelaySeconds: 5periodSeconds: 10

 镜像版本现在是 1.0。

  • 运行并查看
kubectl apply -f deploy-blue.yaml
kubectl get pod -owide

  • 在另一个终端开启监控
kubectl get pod -owide -w

  •  执行更新并暂停
kubectl set image deploy deploy-blue hellok8s=hellok8s:2.0 && kubectl rollout pause deploy deploy-blue
  • set image 命令用来给工作负载更新镜像。命令格式为:
kubectl set image deploy deploy-name container-name=image-name:image-tag
  • && 表示上一条命令执行成功之后才执行下一条命令
  • rollout pause 命令用来暂停滚动更新过程。命令格式为:
kubectl rollout pause deploy deploy-name
  •  查看监控

  • 一个新的pod会被创建,与此同时所有旧的pod还在运行。
  • 一旦新的pod成功运行,服务的一部分请求将被切换到新的pod。这样相当于运行了一个金丝雀版本。金丝雀发布是一种可以将应用程序的出错版本和其影响到的用户的风险化为最小的技术。与其直接向每个用户发布新版本,不如用新版本替换一个或一小部分的pod。通过这种方式,在升级的初期只有少数用户会访问新版本。验证新版本是否正常工作之后,可以将剩余的pod继续升级或者回滚到上一个的版本。
  • 查看 部署详情

       会发现 paused 被系统设置为 true

kubectl get deploy deploy-blue -ojson

  • 执行回滚

倘若这个时候,我们发现版本有问题,想回滚怎么办?

kubectl rollout undo deploy deploy-blue

它会提示你,要先恢复(resume)rollout 过程,然后才能执行回滚命令。

  • 恢复 Rollout
kubectl rollout resume deployment/deploy-blue
  •  查看监控

 可以看到,所有的 pod,都已被更新成新版。

  • 执行回滚

现在就可以正常回滚了。

kubectl rollout undo deploy deploy-blue

四、总结

Deployment pause 的金丝雀发布是一种伪金丝雀发布。它有一下几个问题:

  • 在滚动升级过程中,想要在⼀个确切的位置暂停滚动升级无法做到。
  • 无法实现流量的按比例分配。
  • 需要恢复更新才能执行回滚。相当于将有问题的版本全部更新完才能回滚,将影响面扩大化了。

在现代云原生环境中,有许多其他工具和技术可以帮助实现金丝雀发布,

如Kubernetes的服务网格Istio、负载均衡器配置等。这些工具允许细粒度控制流量分配,使得从A/B测试到完整的金丝雀发布变得更为容易实现。


http://www.ppmy.cn/embedded/160213.html

相关文章

Linux 源码编译安装httpd 2.4,提供系统服务管理脚本并测试

第一种方式 1. 下载 Apache HTTP Server 源代码 首先,从 Apache 官网 下载最新版本的 httpd 2.4 源码,或者直接使用 wget 下载: [rootlocalhost ~]# wget https://downloads.apache.org/httpd/httpd-2.4.36.tar.gz # 解压 [rootlocalhost ~…

【深度学习】基于MXNet的多层感知机的实现

多层感知机 结构组成 大致由三层组成:输入层-隐藏层-输出层,其中隐藏层大于等于一层 其中,隐藏层和输出层都是全连接 隐藏层的层数和神经元个数也是超参数 多层隐藏层,在本质上仍等价于单层神经网络(可从输出方程…

面向对象程序设计-实验1

6-1 求两个或三个整数中的最大数&#xff0c;用带默认参数的函数实现 本题要求实现一个带默认参数的函数&#xff0c;求两个或三个整数中的最大数 代码清单&#xff1a; #include <iostream> using namespace std; int main() { int max( int a,int b,int c0); int …

ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务

目录 一、ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务 1. app.Services 2. GetRequiredService() 3. Init() 二、应用场景 三、依赖注入使用拓展 1、使用场景 2、使用步骤 1. 定义服务接口和实现类 2. 注册服务到依赖注入容器 3. 使用依赖注入获取并…

springboot/ssm互联网智慧医院体检平台web健康体检管理系统Java代码编写

springboot/ssm互联网智慧医院体检平台web健康体检管理系统Java代码编写 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&am…

深度剖析八大排序算法

欢迎并且感谢大家指出我的问题&#xff0c;由于本人水平有限&#xff0c;有些内容写的不是很全面&#xff0c;只是把比较实用的东西给写下来&#xff0c;如果有写的不对的地方&#xff0c;还希望各路大牛多多指教&#xff01;谢谢大家&#xff01;&#x1f970; 在计算机科学领…

【LLM-agent】(task4)搜索引擎Agent

note 新增工具&#xff1a;搜索引擎Agent 文章目录 note一、搜索引擎AgentReference 一、搜索引擎Agent import os from dotenv import load_dotenv# 加载环境变量 load_dotenv() # 初始化变量 base_url None chat_model None api_key None# 使用with语句打开文件&#xf…

C 语言雏启:擘画代码乾坤,谛观编程奥宇之初瞰

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一课主要是让大家初步了解C语言&#xff0c;了解我们的开发环境&#xff0c;main函数&#xff0c;库…