应用蓝绿发布
在现代软件开发中,部署应用的新版本是开发周期中的关键环节。然而,将更新发布到生产环境可能存在风险,因为即使是小问题也可能导致严重的停机和收入损失。蓝绿部署是一种能够降低此类风险的部署策略,可确保应用的新版本实现零停机部署。
蓝绿部署是一种部署策略,在这种策略中会设置两个完全相同的环境,即“蓝”环境和“绿”环境。蓝环境是生产环境,当前正在运行应用的线上版本;绿环境是非生产环境,用于部署应用的新版本。
当应用的新版本准备就绪后,会将其部署到绿环境。新版本完成部署和测试后,流量会切换到绿环境,使其成为新的生产环境。随后,蓝环境将成为非生产环境,用于部署应用的后续版本。
蓝绿发布的优势
-
零停机:蓝绿部署可在零停机的情况下部署应用的新版本,因为流量可以无缝地从蓝环境切换到绿环境。
-
轻松回滚:如果应用的新版本存在问题,可以轻松回滚到上一版本,因为蓝环境仍然可用。
-
降低风险:采用蓝绿部署可以显著降低部署应用新版本的风险。这是因为在流量从蓝环境切换之前,可以先在绿环境中部署并测试新版本。这样可以进行全面测试,减少生产环境出现问题的可能性。
-
提高可靠性:采用蓝绿部署可以提高应用的可靠性。这是因为蓝环境始终可用,即使绿环境出现问题,也可以快速发现并解决,而不会影响用户。
-
灵活性:蓝绿部署为部署过程提供了灵活性。可以并行部署应用的多个版本,从而便于测试和试验。
使用 Alauda Container Platform Progressive Delivery 进行蓝绿发布
Argo Rollouts 是 Alauda Container Platform Progressive Delivery 使用的上游 Kubernetes 控制器。它为 Kubernetes 提供蓝绿、金丝雀、金丝雀分析、实验和渐进式交付等高级部署功能。
Argo Rollouts 可以选择与 ingress 控制器和服务网格集成,利用其流量整形能力,在更新期间逐步将流量切换到新版本。此外,Rollouts 可以查询和解析来自各种提供商的指标,以验证关键 KPI,并在更新期间驱动自动提升或回滚。
借助 Alauda Container Platform Progressive Delivery,您可以在 Alauda Container Platform (ACP) 集群上自动执行蓝绿发布。典型流程包括:
- 定义 Rollout 资源,以管理不同的应用版本。
- 配置 Kubernetes 服务,以在蓝色(当前)环境和绿色(新)环境之间路由流量。
- 将新版本部署到绿色环境。
- 验证并测试新版本。
- 通过切换流量,将绿色环境提升为生产环境。
这种方式可以最大限度地减少停机时间,并实现受控且安全的部署。
关键概念:
- Rollout:Kubernetes 中用于替代标准 Deployment 资源的自定义资源定义 (CRD),支持蓝绿、金丝雀部署等高级部署控制。
前提条件
- ACP (Alauda Container Platform)。
- 由 ACP 管理的 Kubernetes 集群。
- 集群中已安装 Argo Rollouts。
- Argo Rollouts kubectl 插件。
- 用于在其中创建命名空间的项目。
- 集群中用于部署应用的命名空间。
操作步骤
创建 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 选择 Pod。spec.containers:每个 Pod 中要运行的容器。containers.name:容器名称。containers.image:要运行的容器镜像。containers.ports.containerPort:容器公开的端口。
使用 kubectl 应用配置:
这将建立生产环境。
或者,也可以使用 Helm Chart 创建 deployments 和 services。
创建蓝色 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。
验证蓝色 Deployment
通过列出 Pod,确认 blue deployment 正常运行:
检查所有预期副本(2 个)是否处于 Running 状态。这可确保应用已准备好接收流量。
验证到蓝色环境的流量路由
确保 web Service 正确地将流量转发到蓝色 deployment。使用以下命令:
输出应列出蓝色 Pod 的 IP 地址。这些是接收流量的端点。
创建 Rollout
接下来,使用 BlueGreen 策略创建 Argo Rollouts 的 Rollout 资源。
YAML 字段说明:
-
spec.selector:Pod 的标签选择器。Pod 被此选择器选中的现有 ReplicaSet 将受到此 Rollout 的影响。它必须与 Pod 模板的标签匹配。 -
workloadRef:指定要应用于 Rollout 的工作负载引用和缩容策略。scaleDown:指定工作负载(Deployment)在迁移到 Rollout 后是否缩容。可选值包括:- "never":Deployment 不缩容。
- "onsuccess":Rollout 变为 healthy 后,Deployment 缩容。
- "progressively":随着 Rollout 扩容,Deployment 逐步缩容。如果 Rollout 失败,Deployment 将重新扩容。
-
strategy:Rollout 策略,支持BlueGreen和Canary策略。blueGreen:BlueGreenRollout 策略定义。activeService:指定在提升时使用新模板哈希值更新的 Service。对于 blueGreen 更新策略,此字段为必需项。autoPromotionEnabled:autoPromotionEnabled 禁用新堆栈的自动提升,方法是在提升前立即暂停 Rollout。如果省略,则默认行为是在 ReplicaSet 完全就绪/可用后立即提升新堆栈。可以使用以下命令恢复 Rollout:kubectl argo rollouts promote ROLLOUT
使用以下命令应用:
这将为使用 BlueGreen 策略的 deployment 设置 Rollout。
验证 Rollout
创建 Rollout 后,Argo Rollouts 将创建一个使用与 deployment 相同模板的新 ReplicaSet。当新 ReplicaSet 的 Pod 处于 healthy 状态时,deployment 将缩容为 0。
使用以下命令确保 Pod 正常运行:
web Service 将把流量转发到 Rollout 创建的 Pod。使用以下命令:
准备绿色 Deployment
接下来,将应用的新版本准备为绿色 deployment。使用新的镜像版本(例如 hello:1.23.2)更新 deployment web。
YAML 字段说明:
- 与原始 deployment 相同,但以下字段除外:
containers.image:更新为新的镜像版本。
使用以下命令应用:
这将设置用于测试的新应用版本。
Rollout 将创建一个新的 ReplicaSet 来管理绿色 Pod,而流量仍然转发到蓝色 Pod。使用以下命令进行验证:
当前共有 4 个 Pod 正在运行,分别对应蓝色版本和绿色版本。当前活动 Service 是蓝色版本,Rollout 过程已暂停。
如果使用 Helm Chart 部署应用,请使用 Helm 工具将应用升级到绿色版本。
将 Rollout 提升为绿色环境
绿色版本准备就绪后,提升 Rollout,将流量切换到绿色 Pod。使用以下命令:
要验证 Rollout 是否已完成:
如果活动的 Images 已更新为 hello:1.23.2,并且蓝色 ReplicaSet 已缩容为 0,则表示 Rollout 已完成。
由 Alauda 修改,2026-10-21。
Argo® 是 LF Projects, LLC 的注册商标。
Alauda 是独立供应商。本产品不隶属于 LF Projects, LLC,也未获得其认可或赞助。所有商标均归其各自所有者所有,仅用于标识目的。