1. 概述

《Kubernetes运维:容器滚动升级》中我们提到,Kubernetes 通过探针机制为基础控制器(Deployment、Daemon、StatefulSet)提供了各自不同的滚动升级策略。 这些 Kuberntees 提供的原生能力可以一定程度的满足业务滚动升级的需求,但在一些特殊场景中,我们依然需要结合实际 Ingress Controller、Service Mesh 组件进行二次开发,以实现 ”蓝绿发布“、”金丝雀部署“等需求。

Argo Rollouts 是 Argo 项目下的一个子项目,它提供了一个叫做 RollOut 的 CRD 资源。 RollOut 是 Kubernetes Deployment 的增强,它在 Deployment 原有基础上新增了”蓝绿部署“和”金丝雀部署“ 两种高级更新方式。

Argo Rollouts 的安装过程非常简单,此处不在赘述,读者可以参考官方文档

2. Quick Start

1. Blue-Green && Canary

RollOut 支持以下四种更新策略:

  • RollingUpdate:含义和 Deployment 相同
  • Recreate:含义和 Deployment 相同
  • Blue-Green:同时部署了应用的新版本和旧版本。在部署新版本期间,只有旧版本的应用程序将接收生产流量。部署、测试过程中,开发人员可以实时将流量在切换新、旧版本的应用上切换。
  • Canary:同时部署了应用的新版本和旧版本,并且新旧版本同时接收生产流量。部署、测试过程中,开发人员可以实时控制流量在新旧版本的比例。

下图展示了应用蓝绿部署的过程,参考

下图展示了应用金丝雀部署的过程,参考

2. Getting Started

Argo Rollouts 官方在用户手册中演示了以下一个例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-demo
spec:
  replicas: 5
  strategy:
    canary:                       # 金丝雀升级策略
      steps:                      # 按以下步骤升级
        - setWeight: 20               
        - pause: {}
        - setWeight: 40
        - pause: {duration: 10}
        - setWeight: 60
        - pause: {duration: 10}
        - setWeight: 80
        - pause: {duration: 10}
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: rollouts-demo
  template:
    metadata:
      labels:
        app: rollouts-demo
    spec:
      containers:
        - name: rollouts-demo
          image: argoproj/rollouts-demo:blue
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            requests:
              memory: 32Mi
              cpu: 5m

用户初次安装上述 yaml 文件时,等价于部署了一个 5 副本的应用,这和使用 Deployments 部署完全等价。

当用户改动 Rollout 定义时服务将分阶段滚动更新,示例中 canary 更新策略参考以下的注释:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  strategy:
    canary:                       # 金丝雀升级策略
      steps:                      # 按以下步骤升级
        - setWeight: 20               # 升级 20% 的容器,该步骤完成后暂停,直到用户取消 
        - pause: {}
        - setWeight: 40               # 升级 40% 的容器,升级后等待 10s
        - pause: {duration: 10}
        - setWeight: 60               # 升级 60% 的容器,升级后等待 10s
        - pause: {duration: 10}
        - setWeight: 80               # 升级 80% 的容器,升级后等待 10s
        - pause: {duration: 10}

Rollout 在升级时相比 Deployment 允许"暂停"、“回滚"等交互,用户可以通过 kubectl 插件 kubectl-argo-rollouts 进行升级控制。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# watch rollout
kubectl argo rollouts get rollout rollouts-demo --watch

# 更新镜像
kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

# 继续执行更新
kubectl argo rollouts promote rollouts-demo

# 放弃升级
kubectl argo rollouts abort rollouts-demo

# 回滚
kubectl argo rollouts undo rollouts-demo

kubectl-argo-rollouts 提供了一个简易的 web 服务,通过以下方式启动:

1
kubectl argo rollouts dashboard

Argo Rollouts 官方将 Rollout 更新升级时用的元数据都保存在 CRD 对象中,用户在编码时可以通过编译 Rollout 对象控制升级流程。

3. 扩容

Rollout 可以实现 HPAVPA

1. HPA

HPA 模式中 argo-rollouts 根据用户定义的 HorizontalPodAutoscaler 执行扩容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-rollout-example
spec:
  maxReplicas: 6
  minReplicas: 2
  scaleTargetRef:
    apiVersion: argoproj.io/v1alpha1
    kind: Rollout
    name: example-rollout
  targetCPUUtilizationPercentage: 80

HorizontalPodAutoscaler 是 Kubernetes 原生支持的对象,argo-rollouts 3.x 之后的版本已经实现了相关功能(参考)。

2. VPA

VPA 模式中 argo-rollouts 通过 VerticalPodAutoscaler 对象实现扩容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: "autoscaling.k8s.io/v1beta2"
kind: VerticalPodAutoscaler
metadata:
  name: vpa-rollout-example
  namespace: test-vpa
spec:
  targetRef:
    apiVersion: "argoproj.io/v1alpha1"
    kind: Rollout
    name: vpa-demo-rollout
  updatePolicy:
    updateMode: "Auto"
  resourcePolicy:
    containerPolicies:
      - containerName: '*'
    minAllowed:
      cpu: 5m
      memory: 5Mi
    maxAllowed:
      cpu: 1
      memory: 500Mi
    controlledResources: ["cpu", "memory"]  

VerticalPodAutoscaler 是 Kubernetes 社区项目 kubernetes/autoscaler 提供的资源,Rollout 适配该项目从而获取了垂直扩容的能力。

4. 其他能力

参考