【GitOps系列】在 GitOps 工作流中实现蓝绿发布

news2024/9/22 4:16:39

文章目录

      • 前言
      • 蓝绿发布概述
      • 手动实现蓝绿发布
        • 创建蓝色环境
        • 创建蓝色环境 Ingressroute
        • 部署绿色环境
        • 切换到绿色环境
      • 蓝绿发布自动化
        • 安装 Argo Rollout
        • 创建 Rollout 对象
        • 创建 Service 和 Ingress
        • 访问蓝色环境
        • 发布自动化
      • 访问 Argo Rollout Dashboard
      • 自动化原理
      • 结语

前言

在前几篇【GitOps系列】文章中,通过构建 GitOps 工作流实现了自动发布。不过,我们并没有专门去关注新老版本在做更新时是如何切换流量的?这是因为 Kubernetes 的 Service 和 Pod 滚动更新机制自动帮助我们完成了这部分的工作。
在实际的生产环境中,为了提高发布的可靠性,我们通常需要借助发布策略来更加精细地控制流量切换。在几种发布策略中,蓝绿发布是较为简单且容易理解的一种,所以,本次主要介绍如何在 GitOps 工作流中实施蓝绿发布?

什么是蓝绿发布?

蓝绿发布核心思想是: 为应用提供两套环境,并且可以很方便地对它们进行流量切换。
在一次实际发布过程中,新版本的应用将以“绿色”环境部署到生产环境中,但在流量切换之前它并不接收外部流量。当我们完成“绿色”环境的测试之后,可以通过流量切换的方式让“绿色”环境接收外部请求,而旧的“蓝色”环境并不会立即销毁,而是作为灾备来使用。一旦发布过程产生故障,我们就可以将流量立即切换到旧的“蓝色”环境下。
这种部署方式比较适合那些存在兼容问题,或者因为状态原因导致不能很好地使用 Kubernetes 滚动更新的应用。还有的项目希望在更新时部署一个新的版本,同时控制流量切换过程;或者是在发布出现问题时快速回滚。蓝绿发布也是不错的选择。

蓝绿发布概述

在这里插入图片描述

上述架构图中,我们对同一个应用部署了两个版本的环境,称之为蓝绿环境,流量通过 Ingress-Nginx 进入到 Service,然后再由它将流量转发至 Pod。在没有切换流量之前,“蓝色”环境负责接收外部请求流量。
需要进行流量切换时,只要调整 Ingress 策略就可以让“绿色”环境接收外部流量,如下图所示。
在这里插入图片描述

手动实现蓝绿发布

通过一个例子来说明如何使用 Kubernetes 原生的 Deployment 和 Service 来进行蓝绿发布.

创建蓝色环境

cat blue_deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue
  labels:
    app: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: blue
  template:
    metadata:
      labels:
        app: blue
    spec:
      containers:
      - name: demo
        image: argoproj/rollouts-demo:blue
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: blue-service
  labels:
    app: blue
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  selector:
    app: blue
  type: ClusterIP

kubectl wait pods -l app=blue --for condition=Ready --timeout=90s
pod/blue-69f5b46c99-5lkc4 condition met
pod/blue-69f5b46c99-dl7t5 condition met
pod/blue-69f5b46c99-n7sdk condition met

创建蓝色环境 Ingressroute

cat blue_ingressroute.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: demo-ingress
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`bluegreen.demo`) && PathPrefix(`/`)
      kind: Rule
      services:
        - name: blue-service
          port: 80

访问蓝色环境demo http://bluegreen.demo/
在这里插入图片描述

demo页面中,浏览器每秒钟会向后端发出 50 个请求,蓝色的方块代表后端返回接口的内容为 blue,对应 blue 版本的镜像,代表蓝色环境。

部署绿色环境

cat green_deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: green
  labels:
    app: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: green
  template:
    metadata:
      labels:
        app: green
    spec:
      containers:
      - name: demo
        image: argoproj/rollouts-demo:green
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: green-service
  labels:
    app: green
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  selector:
    app: green
  type: ClusterIP

kubectl wait pods -l app=green --for condition=Ready --timeout=90s
pod/green-58c4957f75-86kd7 condition met
pod/green-58c4957f75-ftlg2 condition met
pod/green-58c4957f75-xkr4m condition met

切换到绿色环境

现在,当绿色环境已经准备好接收外部流量时,我们就可以通过调整 Ingress 策略来切换流量了

cat green_ingress.yaml 
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: demo-ingress
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`bluegreen.demo`) && PathPrefix(`/`)
      kind: Rule
      services:
        - name: green-service
          port: 80
          
kubectl apply -f green_ingress.yaml 

将 backend.service 字段由原来的 blue-service 修改为了 green-service,这表示将 Ingress 接收到的外部请求转发到绿色环境的 Service 中,以此达到流量切换的目的。
看到请求将逐渐从蓝色切换到绿色,如下图所示:
在这里插入图片描述
过几秒钟后,请求已经完全变为绿色,这表示流量已经完全从蓝色环境切换到了绿色环境。
在这里插入图片描述
到这里,蓝绿发布就已经完成了。

蓝绿发布自动化

到这里,我们都是通过创建 Kubernetes 原生对象并修改 Ingress 策略的方式来完成蓝绿发布的。这存在一些缺点,首先,在更新过程中,我们一般只关注镜像版本的变化,而不会去操作 Ingress 策略;其次,这种方式不利于将蓝绿发布和 GitOps 流水线进行整合。
接下来,我们来看看如何通过 Argo Rollout 工具来自动化蓝绿发布的过程。

安装 Argo Rollout

Argo Rollout 是一款专门提供 Kubernetes 高级部署能力的自动化工具,它可以独立运行,同时也可以和 ArgoCD 协同在 GitOps 流水线中来使用。

kubectl create ns argo-rollouts
kubectl apply -n argo-rollouts -f https://ghproxy.com/https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
customresourcedefinition.apiextensions.k8s.io/analysisruns.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/analysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/clusteranalysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/experiments.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/rollouts.argoproj.io created
serviceaccount/argo-rollouts created
clusterrole.rbac.authorization.k8s.io/argo-rollouts created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-admin created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-edit created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-view created
clusterrolebinding.rbac.authorization.k8s.io/argo-rollouts created
configmap/argo-rollouts-config created
secret/argo-rollouts-notification-secret created
service/argo-rollouts-metrics created
deployment.apps/argo-rollouts created

kubectl wait --for=condition=Ready pods --all -n argo-rollouts --timeout=300s
pod/argo-rollouts-577dd4d6bc-7vbsz condition met

创建 Rollout 对象

和手动实施蓝绿发布的过程不同的是,为了实现自动化,Argo Rollout 采用了自定义资源(CRD)的方式来管理工作负载。

首先,需要先创建 Rollout 对象。将下面的内容保存为 blue-green-service.yaml 文件

cat blue-green-rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: bluegreen-demo
  labels:
    app: bluegreen-demo
spec:
  replicas: 3
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: bluegreen-demo
  template:
    metadata:
      labels:
        app: bluegreen-demo
    spec:
      containers:
      - name: bluegreen-demo
        image: argoproj/rollouts-demo:blue
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        resources:
          requests:
            memory: 32Mi
            cpu: 5m
  strategy:
    blueGreen:
      autoPromotionEnabled: true
      activeService: bluegreen-demo

kubectl apply -f blue-green-rollout.yaml
rollout.argoproj.io/bluegreen-demo created

在这个 Rollout 对象中,它大部分的字段定义和 Kubernetes 原生的 Deployment 工作负载并没有太大的区别,只是将 apiVersion 从apps/v1修改为 argoproj.io/v1alpha1,同时将 kind 字段从 Deployment 修改为 Rollout,并且增加了strategy字段。在容器配置方面,Rollout 对象同样也使用了argoproj/rollouts-demo:blue来创建蓝色环境。
需要留意的是,strategy 字段是用来定义部署策略的。其中,autoPromotionEnabled 字段表示自动实施蓝绿发布,activeService 用来关联蓝绿发布的 Service,也就是我们在后续要创建的 Service 名称。
总结来说,当我们将这段 Rollout 对象应用到集群内之后,Argo Rollout 首先会创建 Kubernetes 原生对象 ReplicaSet,然后,ReplicaSet 会创建对应的 Pod。为了帮助你理解,你可以将它与之前手动实施蓝绿发布过程中创建的 Deployment 工作负载进行对比,如下图所示:
在这里插入图片描述

创建 Service 和 Ingress

cat blue-green-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: bluegreen-demo
  labels:
    app: bluegreen-demo
spec:
  ports:
  - port: 80
    targetPort: http
    protocol: TCP
    name: http
  selector:
    app: bluegreen-demo

kubectl apply -f blue-green-service.yaml 
service/bluegreen-demo created

ingressroute资源:

和之前创建的 Ingress 对象不同的是,这里使用 bluegreen.auto 域名,以便和之前创建的 Ingress 域名区分开,记得做域名解析。

cat blue-green-ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: bluegreen-demo
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`bluegreen.auto`) && PathPrefix(`/`)
      kind: Rule
      services:
        - name: bluegreen-demo
          port: 80

kubectl apply -f blue-green-ingress.yaml 

访问蓝色环境

访问由 Argo Rollout 创建的蓝色环境了。 http://bluegreen.auto
在这里插入图片描述

发布自动化

现在,假设我们需要更新到绿色环境,在 Argo Rollout 的帮助下,你只需要修改 Rollout 对象中的镜像版本就可以了,流量切换过程将由 Argo Rollout 自动控制。
要更新到绿色环境,你需要编辑 blue-green-rollout.yaml 文件的 image 字段,将 blue 修改为 green 版本。

containers:
- name: bluegreen-demo
  image: argoproj/rollouts-demo:green

kubectl apply -f blue-green-rollout.yaml
rollout.argoproj.io/bluegreen-demo configured

在这里插入图片描述

几秒钟后,所有请求都变成了绿色方格,这表示蓝绿发布的自动化过程已经完成。
相比较手动的方式,在使用 Argo Rollout 进行蓝绿发布的过程中,我们不再需要手动去切换流量,除了更新镜像版本以外,我们也无需关注其他的 Kubernetes 对象。

访问 Argo Rollout Dashboard

下载链接:https://github.com/argoproj/argo-rollouts/releases

./kubectl-argo-rollouts-linux-amd64 version
kubectl-argo-rollouts: v1.5.1+839f05d
  BuildDate: 2023-05-24T19:09:27Z
  GitCommit: 839f05d46f838c04b44eff0e573227d40e89ac7d
  GitTreeState: clean
  GoVersion: go1.19.9
  Compiler: gc
  Platform: linux/amd64

启用Dashboard:
kubectl argo rollouts dashboard
time="2023-07-30T14:59:54+08:00" level=info msg="Argo Rollouts Dashboard is now available at http://localhost:3100/rollouts"

在这里插入图片描述
点击进入 Rollout 的详情界面,可以通过图形化的方式来查看 Rollout 的信息或进行回滚操作,非常Nice!!!
在这里插入图片描述

自动化原理

Argo Rollout 为什么能够帮助我们自动切换流量呢?接下来,我为你详细分析一下它的工作原理。
在刚开始创建蓝色环境时,Ingress、Service 和 Rollout 的关系是下图这样:
在这里插入图片描述
在这个例子中,当 Rollout 对象创建后,Argo Rollout 将会随之创建 ReplicaSet 对象,名称为 blue-green-fbc7b7f55,这个 ReplicaSet 会在创建 Pod 时额外为 Pod 打上rollouts-pod-template-hash=fbc7b7f55的标签,同时为 Service 添加rollouts-pod-template-hash=fbc7b7f55选择器,这样,就打通了从 Ingress 到 Pod 的请求链路。
当我们修改 Rollout 对象的镜像版本后,Argo Rollout 将会重新创建一个新的 ReplicaSet 对象,名称为 bluegreen-demo-7d6459646d,新的 ReplicaSet 也会在创建 Pod 时额外为 Pod 打上rollouts-pod-template-hash=7d6459646d标签。这时候蓝绿环境的 ReplicaSet 同时存在。
当绿色环境的 Pod 全部就绪之后,Argo Rollout 会将 Service 原来的选择器删除,并添加rollouts-pod-template-hash=7d6459646d的选择器,这样就将 Service 指向了绿色环境的 Pod,从而达到了切换流量的目的。同时,Argo Rollout 还会将蓝色环境的 ReplicaSet 副本数缩容为 0,但并不删除它,而是把它作为灾备。如下图所示:
在这里插入图片描述
这样,当我们需要重新回滚到蓝色环境时,Argo Rollout 只需调整蓝色环境的 ReplicaSet 副本数并且修改 Service 的选择器,就可以达到快速回滚的目的。

结语

首先通过手动的方式实践了蓝绿发布的过程。这个过程的核心是部署两套 Deployment 和 Service,同时通过修改 Ingress 策略来实现切换流量。
但手动的方式并不适合与 GitOps 流水线结合使用,所以又介绍了通过 Argo Rollout 将蓝绿发布自动化的方法。
要将手动过程切换到自动化过程其实也非常简单,我们只需要安装 Argo Rollout,并修改 Deployment 对象的 apiVersion 和 Kind 字段,然后增加 strategy 字段配置蓝绿发布策略就可以了。
然后分析了 Argo Rollout 实现自动化蓝绿发布的原理。和手动修改 Ingress 策略来实现的蓝绿发布不同的是,它主要是通过自动修改 Service 的选择器来对流量进行切换的。这种方式将蓝绿发布的过程变成了更新镜像的操作,极大降低了蓝绿发布的门槛。
最后,需要注意的是:如果你希望在微服务架构下实施蓝绿发布,那么情况会复杂得多,你需要关注整个微服务链路的蓝绿流量的切换过程,并且在数据库层面也需要考虑对蓝绿发布的支持和适配情况,使数据库在升级过程中能够同时支持蓝绿(新旧)应用。

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

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

相关文章

Netty学习(四)

文章目录 四. 优化与源码1. 优化1.1 扩展序列化算法jdk序列化与反序列化Serializer & AlgorithmConfigapplication.properties MessageCodecSharableMessage(抽象类) 测试序列化测试反序列化测试 1.2 参数调优1)CONNECT_TIMEOUT_MILLIS2&…

最强,自动化测试-自定义日志类及日志封装(实战)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 在自定义日志之前…

【机器学习】习题3.3Python编程实现对数几率回归

参考代码 结合自己的理解,添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt from sklearn import linear_model导入数据,进行数据处理和特征工程 # 1.数据处理&#x…

Windows系统如何修改文件日期属性

winr键,输入powershell,在弹出的命令窗口输入命令,案例如下: file_address E:\_OrderingProject\\PIC1101\ldv1s_0830_ec_result.tiftime_change "07/12/2022 20:42:23" 修改文件创建时间:creationtime $(Get-Item fi…

COMSOL三维Voronoi图泰森多边形3D模型轴压模拟及建模教程

多晶体模型采用三维Voronoi算法生成,试件尺寸为150150300mm棱柱模型,对晶格指定五种不同材料,实现晶格间的差异性。 对试件进行力学模拟,下侧为固定边界,限制z方向的位移,上表面通过给定位移的方式实现轴…

P2P网络NAT穿透原理(打洞方案)

1.关于NAT NAT技术(Network Address Translation,网络地址转换)是一种把内部网络(简称为内网)私有IP地址转换为外部网络(简称为外网)公共IP地址的技术,它使得一定范围内的多台主机只…

某拍房数据采集

某拍房数据采集 某拍房数据采集声明1.逆向目标2.寻找加密位置3.分析加密参数4.python代码书写 某拍房数据采集 声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的…

yo!这里是Linux常见命令总结

目录 前言 常见命令 ls指令 pwd指令 cd指令 touch指令 tree指令 mkdir指令&&rmdir指令 rm指令 man指令 cp指令 mv指令 echo指令 cat指令&&tac指令 more指令 less指令 head指令&&tail指令 find指令 grep指令 alias指令&&u…

NAT原理(网络地址转换)

NAT原理 网络地址转换(Network Address Translation,简称NAT) 是一种网络通信协议,它是在网络层上对IP地址进行转换的技术。 NAT技术可以将内部网络中的私有IP地址转换为公共IP地址,以便内部网络中的设备能够访问互…

2023-07-30力扣每日一题

链接: 142. 环形链表 II 题意: 求链表是否有环,并给出入环的点 解: 哈希关联标记或者快慢指针 快慢指针逻辑:设入环前长度a,快慢相遇时指针在b,环长度为c,fast2*slow&#xff…

前端学习--vue2--1-基础配置

写在前面: 好久没写了,做实习每天上班都没啥时间写,1个半月前开始系统学习前端,然后做了半个月主要的前端实习了wk。也行,当复习了,后端也还是搞了点。 本文介绍vue2的一些基础和配置,配置只写…

【C++】——类和对象

目录 面向过程和面向对象的初步认识类的引入类的定义类的访问限定符及封装类的作用域类的实例化this指针类的6个默认成员函数构造函数析构函数 面向过程和面向对象的初步认识 C语言是面向过程的,关注的是过程,分析求解问题的步骤,通过函数调用…

你还不会反射吧,快来吧!!!

首先&#xff1a; 1.加载类&#xff1a; //练习获取字节码对象的3种方式 //Class<Student> studentClass Student.class; //Class<? extends Student> aClass new Student().getClass(); Class<?> clazz Class.forName("TestT.Student"); 2.获…

[C++] 类与对象(上)

目录 1、前言 2、类的引入 3、类的定义 3.1 类的两种定义方式 4、类的访问限定符 5、类的作用域 6、类的实例化 7、类对象模型 7.1 内存对齐规则 7.1 类对象的存储方式 8、this指针 8.1 this指针的特性 8.2 this指针是否可以为空 1、前言 C语言是面向过程的&#…

网络运维基础问题及解答

前言 本篇文章是对于网络运维基础技能的一些常见问题的解答&#xff0c;希望能够为进行期末复习或者对网络运维感兴趣的同学或专业人员提供一定的帮助。 问题及解答 1. 列举 3 种常用字符编码&#xff0c;简述怎样在 str 和 bytes 之间进行编码和解码。 答&#xff1a;常用的…

Python读取多个栅格文件并提取像元的各波段时间序列数据与变化值

本文介绍基于Python语言&#xff0c;读取文件夹下大量栅格遥感影像文件&#xff0c;并基于给定的一个像元&#xff0c;提取该像元对应的全部遥感影像文件中&#xff0c;指定多个波段的数值&#xff1b;修改其中不在给定范围内的异常值&#xff0c;并计算像元数值在每一景遥感影…

【C++】-动态内存管理

作者&#xff1a;小树苗渴望变成参天大树 作者宣言&#xff1a;认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言一、C内存管理方式1.1 new/delete操作内置类型 总结 前言 今天再讲一个…

【禁用外键】为什么互联网大厂禁用外键约束?详谈外键的优缺点和使用场景

导航&#xff1a; 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式常见面试题源码 目录 一、外键介绍 1.1 概述 1.2 练习 1.2.1 数据准备 1.2.2 验证有外键时&#xff0c;删除记录要维护外键 1.2…

Python批量下载主播照片,实现人脸识别, 进行颜值评分,制作颜值排行榜

昨晚一回家&#xff0c;表弟就神神秘秘的跟我说&#xff0c;发现一个高颜值网站&#xff0c;非要拉着我研究一下她们的颜值高低。 我心想&#xff0c;这还得要我一个个慢慢看&#xff0c;太麻烦了~ 于是反手用Python给他写了一个人脸识别代码&#xff0c;把她们的照片全部爬下…

06-行向量列向量_向量的运算 加法,数乘,减法,转置

行向量和列向量 行向量是按行把向量排开&#xff08;横着来写&#xff09;&#xff0c; 列向量是按列把向量排开&#xff08;竖着来写&#xff09; 在数学中我们更多的把数据写成列向量&#xff0c;在编程语言中更多的把数据存成行向量! 如果想在编程语言中把行向量转化成列…