原生应用蓝绿发布
在现代软件开发中,部署应用的新版本是开发周期中的关键部分。然而,将更新发布到生产环境可能存在风险,因为即使是很小的问题也可能导致显著的停机时间和收入损失。蓝绿发布是一种部署策略,它通过确保应用的新版本可以零停机时间部署来缓解这种风险。
蓝绿发布是一种部署策略,其中会设置两个相同的环境:“蓝色”环境和“绿色”环境。蓝色环境是生产环境,应用的当前运行版本就在这里运行;绿色环境是非生产环境,新版本的应用会部署到这里。
当应用的新版本准备好部署时,它会被部署到绿色环境中。新版本部署并测试完成后,流量会切换到绿色环境,使其成为新的生产环境。随后,蓝色环境会变为非生产环境,未来版本的应用可以部署到这里。
蓝绿发布的优势
-
零停机时间:蓝绿发布允许新版本的应用以零停机时间部署,因为流量会无缝地从蓝色环境切换到绿色环境。
-
易于回滚:如果应用的新版本出现问题,回滚到前一个版本很容易,因为蓝色环境仍然可用。
-
降低风险:通过使用蓝绿发布,部署应用新版本的风险会显著降低。这是因为新版本可以先在绿色环境中部署和测试,然后再将流量从蓝色环境切换过来。这使得可以进行充分测试,并减少生产环境中出现问题的可能性。
-
提高可靠性:通过使用蓝绿发布,应用的可靠性会提高。这是因为蓝色环境始终可用,而且绿色环境中的任何问题都可以被快速识别和解决,而不会影响用户。
-
灵活性:蓝绿发布为部署过程提供了灵活性。一个应用的多个版本可以并排部署,便于进行测试和实验。
使用 Argo Rollouts 进行蓝绿发布
Argo Rollouts 是一个 Kubernetes 控制器和一组 CRD,可为 Kubernetes 提供蓝绿发布、金丝雀发布、金丝雀分析、实验以及渐进式交付等高级部署能力。
Argo Rollouts 可以(可选地)与 ingress controllers 和 service meshes 集成,利用它们的流量整形能力,在更新期间逐步将流量切换到新版本。此外,Rollouts 还可以查询并解释来自各种提供方的指标,以验证关键 KPI,并在更新期间驱动自动晋升或回滚。
借助 Argo Rollouts,你可以在 Alauda Container Platform(ACP)集群上自动化蓝绿发布。典型流程包括:
- 定义 Rollout 资源来管理不同的应用版本。
- 配置 Kubernetes Service,在蓝色(当前)和绿色(新)环境之间路由流量。
- 将新版本部署到绿色环境。
- 验证和测试新版本。
- 通过切换流量,将绿色环境晋升为生产环境。
这种方式可以最大限度地减少停机时间,并实现受控且安全的发布。
关键概念:
- Rollout:Kubernetes 中的一个自定义资源定义(CRD),用于替代标准的 Deployment 资源,从而实现蓝绿发布、金丝雀发布等高级部署控制。
前提条件
- ACP(Alauda Container Platform)。
- 由 ACP 管理的 Kubernetes 集群。
- 集群中已安装 Argo Rollouts。
- Argo Rollouts kubectl 插件。
- 一个用于创建 namespace 的 project。
- 集群中用于部署应用的 namespace。
操作步骤
创建 Deployment
首先定义应用的“蓝色”版本。这是用户当前访问的版本。创建一个 Kubernetes Deployment,并设置合适的副本数、容器镜像版本(例如 hello:1.23.1)以及正确的标签,例如 app=web。
使用以下 YAML:
YAML 字段说明:
apiVersion:用于创建该资源的 Kubernetes API 版本。kind:指定这是一个 Deployment 资源。metadata.name:Deployment 的名称。spec.replicas:期望的 pod 副本数量。spec.selector.matchLabels:定义 Deployment 如何查找要管理的 pod。template.metadata.labels:应用到 pod 上的标签,由 Service 用于选择它们。spec.containers:在每个 pod 中运行的容器。containers.name:容器名称。containers.image:要运行的容器镜像。containers.ports.containerPort:容器暴露的端口。
使用 kubectl 应用该配置:
这会设置生产环境。
另外,你也可以使用 Helm Chart 来创建 Deployment 和 Service。
创建 Blue Service
创建一个 Kubernetes Service 来暴露蓝色 Deployment。该 Service 会根据匹配标签将流量转发到蓝色 pod。最初,Service 的 selector 目标是带有 app=web 标签的 pod。
YAML 字段说明:
apiVersion:用于创建该 Service 的 Kubernetes API 版本。kind:指定该资源是一个 Service。metadata.name:Service 的名称。spec.selector:根据标签识别要路由流量的 pod。ports.protocol:使用的协议(TCP)。ports.port:Service 暴露的端口。ports.targetPort:流量被转发到容器上的端口。
使用以下命令应用它:
这使外部可以访问蓝色 Deployment。
验证 Blue Deployment
通过列出 pod 来确认 blue Deployment 运行正常:
检查所有预期的副本数(2)是否都处于 Running 状态。这可以确保应用已准备好提供流量服务。
验证到 Blue 的流量路由
确保 web Service 正确地将流量转发到蓝色 Deployment。使用以下命令:
输出应列出蓝色 pod 的 IP 地址。这些就是接收流量的端点。
创建 Rollout
接下来,创建使用 BlueGreen 策略的 Argo Rollouts Rollout 资源。
YAML 字段说明:
-
spec.selector:pod 的标签选择器。当前选中的 pod 所属的现有 ReplicaSet 都会受此 Rollout 影响。它必须与 pod 模板的标签匹配。 -
workloadRef:指定要应用到 Rollout 的工作负载引用和缩容策略。scaleDown:指定在迁移到 Rollout 后,是否缩减工作负载(Deployment)。可选项如下:"never":Deployment 不会被缩减。"onsuccess":当 Rollout 变为 healthy 后,Deployment 会被缩减。"progressively":随着 Rollout 扩容,Deployment 会同步缩容。如果 Rollout 失败,Deployment 会重新扩容。
-
strategy:Rollout 策略,支持BlueGreen和Canary策略。blueGreen:BlueGreenRollout 策略定义。activeService:指定在晋升时使用新模板哈希更新的 Service。此字段是 blueGreen 更新策略的必填项。autoPromotionEnabled:通过在晋升前立即暂停 Rollout 来禁用新版本的自动晋升。如果省略,则默认行为是在 ReplicaSet 完全 ready/available 后立即晋升新版本。可使用以下命令恢复 Rollout:kubectl argo rollouts promote ROLLOUT
使用以下命令应用它:
这会为该 Deployment 设置使用 BlueGreen 策略的 Rollouts。
验证 Rollouts
创建 Rollout 后,Argo Rollouts 会使用与 Deployment 相同的模板创建一个新的 ReplicaSet。当新 ReplicaSet 的 pod 处于 healthy 状态时,Deployment 会被缩减为 0。
使用以下命令确保 pod 运行正常:
Service web 会将流量转发到 Rollouts 创建的 pod。使用以下命令:
准备 Green Deployment
接下来,将应用的新版本准备为绿色部署。使用新的镜像版本更新 Deployment web(例如 hello:1.23.2)。
YAML 字段说明:
- 与原始 Deployment 相同,唯一的区别是:
containers.image:更新为新的镜像版本。
使用以下命令应用它:
这会为测试设置新版本的应用。
Rollouts 会创建一个新的 ReplicaSet 来管理绿色 pod,而流量仍然会转发到蓝色 pod。使用以下命令进行验证:
目前有 4 个 pod 在运行,分别是蓝色和绿色版本。而 active service 仍然指向蓝色版本,Rollout 流程处于暂停状态。
如果你使用 Helm Chart 来部署应用,请使用 helm 工具将应用升级到绿色版本。
将 Rollout 晋升到 Green
当绿色版本准备就绪后,晋升 Rollout 以将流量切换到绿色 pod。使用以下命令:
要验证 Rollout 是否已完成:
如果 active Images 已更新为 hello:1.23.2,并且蓝色 ReplicaSet 已缩减到 0,则表示 Rollout 已完成。