1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【GitOps系列】在 GitOps 工作流中实现蓝绿发布

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

时间:2020-02-02 18:50:04

相关推荐

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

文章目录

前言蓝绿发布概述手动实现蓝绿发布创建蓝色环境创建蓝色环境 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/v1kind: Deploymentmetadata:name: bluelabels:app: bluespec:replicas: 3selector:matchLabels:app: bluetemplate:metadata:labels:app: bluespec:containers:- name: demoimage: argoproj/rollouts-demo:blueimagePullPolicy: Alwaysports:- containerPort: 8080---apiVersion: v1kind: Servicemetadata:name: blue-servicelabels:app: bluespec:ports:- protocol: TCPport: 80targetPort: 8080selector:app: bluetype: ClusterIPkubectl wait pods -l app=blue --for condition=Ready --timeout=90spod/blue-69f5b46c99-5lkc4 condition metpod/blue-69f5b46c99-dl7t5 condition metpod/blue-69f5b46c99-n7sdk condition met

创建蓝色环境 Ingressroute

cat blue_ingressroute.yaml apiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:name: demo-ingressspec:entryPoints:- webroutes:- match: Host(`bluegreen.demo`) && PathPrefix(`/`)kind: Ruleservices:- name: blue-serviceport: 80

访问蓝色环境demohttp://bluegreen.demo/

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

部署绿色环境

cat green_deployment.yaml apiVersion: apps/v1kind: Deploymentmetadata:name: greenlabels:app: greenspec:replicas: 3selector:matchLabels:app: greentemplate:metadata:labels:app: greenspec:containers:- name: demoimage: argoproj/rollouts-demo:greenimagePullPolicy: Alwaysports:- containerPort: 8080---apiVersion: v1kind: Servicemetadata:name: green-servicelabels:app: greenspec:ports:- protocol: TCPport: 80targetPort: 8080selector:app: greentype: ClusterIPkubectl wait pods -l app=green --for condition=Ready --timeout=90spod/green-58c4957f75-86kd7 condition metpod/green-58c4957f75-ftlg2 condition metpod/green-58c4957f75-xkr4m condition met

切换到绿色环境

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

cat green_ingress.yaml apiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:name: demo-ingressspec:entryPoints:- webroutes:- match: Host(`bluegreen.demo`) && PathPrefix(`/`)kind: Ruleservices:- name: green-serviceport: 80kubectl 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-rolloutskubectl apply -n argo-rollouts -f //argoproj/argo-rollouts/releases/latest/download/install.yamlcustomresourcedefinition.apiextensions.k8s.io/analysisruns.argoproj.io createdcustomresourcedefinition.apiextensions.k8s.io/analysistemplates.argoproj.io createdcustomresourcedefinition.apiextensions.k8s.io/clusteranalysistemplates.argoproj.io createdcustomresourcedefinition.apiextensions.k8s.io/experiments.argoproj.io createdcustomresourcedefinition.apiextensions.k8s.io/rollouts.argoproj.io createdserviceaccount/argo-rollouts createdclusterrole.rbac.authorization.k8s.io/argo-rollouts createdclusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-admin createdclusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-edit createdclusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-view createdclusterrolebinding.rbac.authorization.k8s.io/argo-rollouts createdconfigmap/argo-rollouts-config createdsecret/argo-rollouts-notification-secret createdservice/argo-rollouts-metrics createddeployment.apps/argo-rollouts createdkubectl wait --for=condition=Ready pods --all -n argo-rollouts --timeout=300spod/argo-rollouts-577dd4d6bc-7vbsz condition met

创建 Rollout 对象

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

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

cat blue-green-rollout.yamlapiVersion: argoproj.io/v1alpha1kind: Rolloutmetadata:name: bluegreen-demolabels:app: bluegreen-demospec:replicas: 3revisionHistoryLimit: 1selector:matchLabels:app: bluegreen-demotemplate:metadata:labels:app: bluegreen-demospec:containers:- name: bluegreen-demoimage: argoproj/rollouts-demo:blueimagePullPolicy: Alwaysports:- name: httpcontainerPort: 8080protocol: TCPresources:requests:memory: 32Micpu: 5mstrategy:blueGreen:autoPromotionEnabled: trueactiveService: bluegreen-demokubectl apply -f blue-green-rollout.yamlrollout.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: v1kind: Servicemetadata:name: bluegreen-demolabels:app: bluegreen-demospec:ports:- port: 80targetPort: httpprotocol: TCPname: httpselector:app: bluegreen-demokubectl apply -f blue-green-service.yaml service/bluegreen-demo created

ingressroute资源:

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

cat blue-green-ingress.yamlapiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:name: bluegreen-demospec:entryPoints:- webroutes:- match: Host(`bluegreen.auto`) && PathPrefix(`/`)kind: Ruleservices:- name: bluegreen-demoport: 80kubectl 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-demoimage: argoproj/rollouts-demo:greenkubectl apply -f blue-green-rollout.yamlrollout.argoproj.io/bluegreen-demo configured

几秒钟后,所有请求都变成了绿色方格,这表示蓝绿发布的自动化过程已经完成。

相比较手动的方式,在使用 Argo Rollout 进行蓝绿发布的过程中,我们不再需要手动去切换流量,除了更新镜像版本以外,我们也无需关注其他的 Kubernetes 对象。

访问 Argo Rollout Dashboard

下载链接:/argoproj/argo-rollouts/releases

./kubectl-argo-rollouts-linux-amd64 versionkubectl-argo-rollouts: v1.5.1+839f05dBuildDate: -05-24T19:09:27ZGitCommit: 839f05d46f838c04b44eff0e573227d40e89ac7dGitTreeState: cleanGoVersion: go1.19.9Compiler: gcPlatform: linux/amd64启用Dashboard:kubectl argo rollouts dashboardtime="-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 的选择器来对流量进行切换的。这种方式将蓝绿发布的过程变成了更新镜像的操作,极大降低了蓝绿发布的门槛。

最后,需要注意的是:如果你希望在微服务架构下实施蓝绿发布,那么情况会复杂得多,你需要关注整个微服务链路的蓝绿流量的切换过程,并且在数据库层面也需要考虑对蓝绿发布的支持和适配情况,使数据库在升级过程中能够同时支持蓝绿(新旧)应用。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。