Application Blue Green Deployment

在现代软件开发中,部署应用的新版本是开发周期中的关键环节。然而,将更新推送到生产环境可能存在风险,因为即使是小问题也可能导致严重的停机和收入损失。蓝绿发布(Blue-Green Deployment)是一种部署策略,通过确保应用新版本能够实现零停机部署,从而降低了这种风险。

蓝绿发布是一种部署策略,其中设置两个相同的环境,即“蓝色”环境和“绿色”环境。蓝色环境是生产环境,当前运行着应用的在线版本;绿色环境是非生产环境,用于部署应用的新版本。

当应用的新版本准备好部署时,会先部署到绿色环境。一旦新版本部署并测试完成,流量切换到绿色环境,使其成为新的生产环境。蓝色环境则变为非生产环境,用于部署未来的应用版本。

蓝绿发布的优势

  • 零停机:蓝绿发布允许应用新版本实现零停机部署,因为流量可以无缝地从蓝色环境切换到绿色环境。

  • 简单回滚:如果新版本出现问题,回滚到之前的版本非常简单,因为蓝色环境仍然可用。

  • 降低风险:通过使用蓝绿发布,部署新版本的风险显著降低。因为新版本可以先在绿色环境中部署和测试,然后再将流量从蓝色环境切换过去。这允许进行充分测试,减少生产环境出现问题的可能性。

  • 提高可靠性:使用蓝绿发布可以提升应用的可靠性。蓝色环境始终可用,绿色环境出现问题时可以快速识别并解决,而不会影响用户。

  • 灵活性:蓝绿发布为部署过程提供灵活性。可以并行部署多个版本的应用,方便测试和实验。

使用 Argo Rollouts 进行蓝绿发布

Argo Rollouts 是一个 Kubernetes 控制器及一组 CRD,提供了蓝绿、金丝雀、金丝雀分析、实验和渐进式交付等高级部署功能。

Argo Rollouts(可选)集成了 ingress 控制器和服务网格,利用它们的流量调度能力在更新过程中逐步切换流量到新版本。此外,Rollouts 可以查询和解析来自多种提供者的指标,以验证关键 KPI,并在更新过程中驱动自动升级或回滚。

借助 Argo Rollouts,您可以在 Alauda Container Platform (ACP) 集群上自动化蓝绿发布。典型流程包括:

  1. 定义 Rollout 资源以管理不同的应用版本。
  2. 配置 Kubernetes 服务以在蓝色(当前)和绿色(新)环境之间路由流量。
  3. 将新版本部署到绿色环境。
  4. 验证并测试新版本。
  5. 通过切换流量将绿色环境提升为生产环境。

该方法最大限度地减少停机时间,实现受控且安全的部署。

关键概念:

  • Rollout:Kubernetes 中的一种自定义资源定义(CRD),替代标准的 Deployment 资源,实现蓝绿、金丝雀等高级部署控制。

目录

前提条件

  1. ACP(Alauda Container Platform)。
  2. 由 ACP 管理的 Kubernetes 集群。
  3. 集群中已安装 Argo Rollouts。
  4. 安装 Argo Rollouts 的 kubectl 插件。
  5. 一个用于创建命名空间的项目。
  6. 集群中用于部署应用的命名空间。

操作步骤

创建部署

首先定义应用的“蓝色”版本,即用户当前访问的版本。创建一个 Kubernetes Deployment,指定适当的副本数、容器镜像版本(例如 hello:1.23.1)以及合适的标签,如 app=web

使用以下 YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: hello:1.23.1
          ports:
            - containerPort: 80

YAML 字段说明:

  • apiVersion:用于创建资源的 Kubernetes API 版本。
  • kind:指定资源类型为 Deployment。
  • metadata.name:部署名称。
  • spec.replicas:期望的 Pod 副本数。
  • spec.selector.matchLabels:定义 Deployment 管理哪些 Pod。
  • template.metadata.labels:Pod 上的标签,供 Service 选择使用。
  • spec.containers:Pod 中运行的容器列表。
  • containers.name:容器名称。
  • containers.image:运行的 Docker 镜像。
  • containers.ports.containerPort:容器暴露的端口。

使用 kubectl 应用配置:

kubectl apply -f deployment.yaml

这将搭建生产环境。

另外,也可以使用 Helm Chart 创建部署和服务。

创建蓝色服务

创建一个 Kubernetes Service,用于暴露蓝色部署。该服务根据匹配标签将流量转发到蓝色 Pod。初始时,服务选择器指向带有 app=web 标签的 Pod。

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

YAML 字段说明:

  • apiVersion:用于创建 Service 的 Kubernetes API 版本。
  • kind:资源类型为 Service。
  • metadata.name:Service 名称。
  • spec.selector:根据标签选择 Pod 以路由流量。
  • ports.protocol:使用的协议(TCP)。
  • ports.port:Service 暴露的端口。
  • ports.targetPort:容器接收流量的端口。

使用以下命令应用:

kubectl apply -f web-service.yaml

这允许外部访问蓝色部署。

验证蓝色部署

通过列出 Pod 确认蓝色部署运行正常:

kubectl get pods -l app=web

检查所有预期副本(2个)均处于 Running 状态,确保应用已准备好提供服务。

验证流量路由到蓝色

确认 web 服务正确将流量转发到蓝色部署。执行:

kubectl describe service web | grep Endpoints

输出应列出蓝色 Pod 的 IP 地址,这些即为接收流量的端点。

创建 Rollout

接下来,创建 Argo Rollouts 的 Rollout 资源,使用 BlueGreen 策略。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-bluegreen
spec:
  replicas: 2
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: web
  workloadRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
    scaleDown: onsuccess
  strategy:
    blueGreen:
      activeService: web
      autoPromotionEnabled: false

YAML 字段说明:

  • spec.selector:Pod 的标签选择器。现有 ReplicaSet 中被此选择器选中的 Pod 将受此 Rollout 影响。必须与 Pod 模板标签匹配。

  • workloadRef:指定工作负载引用及缩容策略。

    • scaleDown:指定迁移到 Rollout 后是否缩减工作负载(Deployment)。可选值:
      • "never":不缩减 Deployment。
      • "onsuccess":Rollout 健康后缩减 Deployment。
      • "progressively":Rollout 扩容时逐步缩减 Deployment,若 Rollout 失败则恢复 Deployment。
  • strategy:部署策略,支持 BlueGreenCanary

    • blueGreen:蓝绿部署策略定义。
      • activeService:指定在升级时更新新模板哈希的服务。此字段为蓝绿策略必填。
      • autoPromotionEnabled:禁用自动升级新版本,部署将在升级前暂停。默认行为是 ReplicaSet 完全就绪后自动升级。可用命令 kubectl argo rollouts promote ROLLOUT 恢复升级。

使用以下命令应用:

kubectl apply -f rollout.yaml

这将为部署设置蓝绿策略的 Rollout。

验证 Rollout

创建 Rollout 后,Argo Rollouts 会创建一个与 Deployment 模板相同的新 ReplicaSet。当新 ReplicaSet 的 Pod 健康时,Deployment 会缩容至 0。

使用以下命令确认 Pod 正常运行:

kubectl argo rollouts get rollout rollout-bluegreen
Name:            rollout-bluegreen
Namespace:       default
Status: Healthy
Strategy:        BlueGreen
Images:          hello:1.23.1 (stable, active)
Replicas:
  Desired:       2
  Current:       2
  Updated:       2
  Ready:         2
  Available:     2

NAME                                           KIND        STATUS     AGE  INFO
 rollout-bluegreen                            Rollout Healthy  95s
└──# revision:1
   └──⧉ rollout-bluegreen-595d4567cc           ReplicaSet Healthy  18s  stable,active
      ├──□ rollout-bluegreen-595d4567cc-mc769  Pod Running  8s   ready:1/1
      └──□ rollout-bluegreen-595d4567cc-zdc5x  Pod Running  8s   ready:1/1

服务 web 会将流量转发给 Rollouts 创建的 Pod。使用命令:

kubectl describe service web | grep Endpoints

准备绿色部署

接下来,准备应用的新版本作为绿色部署。更新 Deployment web,使用新镜像版本(例如 hello:1.23.2)。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: hello:1.23.2
          ports:
            - containerPort: 80

YAML 字段说明:

  • 与原部署相同,唯一不同的是:
    • containers.image:更新为新镜像版本。

使用以下命令应用:

kubectl apply -f deployment.yaml

这将搭建新版本应用以供测试。

Rollouts 会创建新的 ReplicaSet 管理绿色 Pod,流量仍然转发到蓝色 Pod。使用以下命令验证:

kubectl argo rollouts get rollout rollout-bluegreen
Name:            rollout-bluegreen
Namespace:       default
Status: Paused
Message:         BlueGreenPause
Strategy:        BlueGreen
Images:          hello:1.23.1 (stable, active)
                 hello:1.23.2
Replicas:
  Desired:       2
  Current:       4
  Updated:       2
  Ready:         2
  Available:     2

NAME                                           KIND        STATUS     AGE  INFO
 rollout-bluegreen                            Rollout Paused   14m
├──# revision:2
  └──⧉ rollout-bluegreen-776b688d57           ReplicaSet Healthy  24s
     ├──□ rollout-bluegreen-776b688d57-kxr66  Pod Running  23s  ready:1/1
     └──□ rollout-bluegreen-776b688d57-vv7t7  Pod Running  23s  ready:1/1
└──# revision:1
   └──⧉ rollout-bluegreen-595d4567cc           ReplicaSet Healthy  12m  stable,active
      ├──□ rollout-bluegreen-595d4567cc-mc769  Pod Running  12m  ready:1/1
      └──□ rollout-bluegreen-595d4567cc-zdc5x  Pod Running  12m  ready:1/1

当前共有 4 个 Pod 运行,包含蓝色和绿色版本。活动服务指向蓝色版本,Rollout 处于暂停状态。

如果使用 Helm Chart 部署应用,可使用 Helm 工具将应用升级到绿色版本。

升级 Rollout 到绿色

当绿色版本准备就绪,执行升级操作,将流量切换到绿色 Pod。使用命令:

kubectl argo rollouts promote rollout-bluegreen

验证升级是否完成:

kubectl argo rollouts get rollout rollout-bluegreen
Name:            rollout-bluegreen
Namespace:       default
Status: Healthy
Strategy:        BlueGreen
Images:          hello:1.23.2 (stable, active)
Replicas:
  Desired:       2
  Current:       2
  Updated:       2
  Ready:         2
  Available:     2

NAME                                           KIND        STATUS         AGE   INFO
 rollout-bluegreen                            Rollout Healthy      3h2m
├──# revision:2
  └──⧉ rollout-bluegreen-776b688d57           ReplicaSet Healthy      168m  stable,active
     ├──□ rollout-bluegreen-776b688d57-kxr66  Pod Running      168m  ready:1/1
     └──□ rollout-bluegreen-776b688d57-vv7t7  Pod Running      168m  ready:1/1
└──# revision:1
   └──⧉ rollout-bluegreen-595d4567cc           ReplicaSet ScaledDown   3h1m
      ├──□ rollout-bluegreen-595d4567cc-mc769  Pod Terminating  3h    ready:1/1
      └──□ rollout-bluegreen-595d4567cc-zdc5x  Pod Terminating  3h    ready:1/1

如果活动 Images 更新为 hello:1.23.2,且蓝色 ReplicaSet 缩容为 0,表示 Rollout 已完成。