什么是argo rollouts

Argo-Rollout是一个Kubernetes Controller和对应一系列的CRD,提供更强大的Deployment能力。包括灰度发布、蓝绿部署、更新测试(experimentation)、渐进式交付(progressive delivery)等特性。

支持特性如下:

  • 蓝绿色更新策略
  • 金丝雀更新策略
  • 细粒度,加权流量转移
  • 自动回rollback和promotion
  • 手动判断
  • 可定制的指标查询和业务KPI分析
  • 入口控制器集成:NGINX,ALB
  • 服务网格集成:Istio,Linkerd,SMI
  • Metric provider集成:Prometheus,Wavefront,Kayenta,Web,Kubernetes Jobs

Argo原理和Deployment差不多,只是加强rollout的策略和流量控制。当spec.template发送变化时,Argo-Rollout就会根据spec.strategy进行rollout,通常会产生一个新的ReplicaSet,逐步scale down之前的ReplicaSet的pod数量。

安装

按着官方文档进行安装,官方地址为:https://argoproj.github.io/argo-rollouts/installation/#kubectl-plugin-installation

(1)在Kubernetes集群中安装argo-rollouts

  1. kubectl create namespace argo-rollouts
  2. kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml

(2)安装argo-rollouts的kubectl plugin

  1. curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
  2. chmod +x ./kubectl-argo-rollouts-linux-amd64
  3. mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

金丝雀发布

灰度发布包含Replica Shifting和Traffic Shifting两个过程。

  • Replica Shifting:版本替换
  • Traffic Shifting:流量接入

这里使用官方的demo来进行测试。例子:https://argoproj.github.io/argo-rollouts/getting-started/

Replica Shifting

部署应用

使用如下命令部署示例:

  1. kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
  2. kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

我们先看看第一个rollout.yaml的具体内容,如下:

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

可以看到除了apiVersionkind以及strategy之外,其他和Deployment无异。
strategy字段定义的是发布策略,其中:

  • setWeight:设置流量的权重
  • pause:暂停,如果里面没有跟duration: 10则表示需要手动更新,如果跟了表示等待多长时间会自动跟新。

而service.yaml文件定义的就是普通的service,如下:

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: rollouts-demo
  5. spec:
  6. ports:
  7. - port: 80
  8. targetPort: http
  9. protocol: TCP
  10. name: http
  11. selector:
  12. app: rollouts-demo

执行上面命令部署后,会在default命名空间下创建5个pod,如下:

  1. # kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. nfs-client-prosioner-598d477ff6-fmgwf 1/1 Running 2 17d
  4. rollouts-demo-7bf84f9696-4glv6 1/1 Running 0 78s
  5. rollouts-demo-7bf84f9696-7kqt6 1/1 Running 0 78s
  6. rollouts-demo-7bf84f9696-8k9hw 1/1 Running 0 78s
  7. rollouts-demo-7bf84f9696-9cz2r 1/1 Running 0 78s
  8. rollouts-demo-7bf84f9696-jvzvd 1/1 Running 0 78s

可以使用kubectl-argo-rollouts get rollout rollouts-demo命令来查看部署状态,如下:

  1. # kubectl-argo-rollouts get rollout rollouts-demo
  2. Name: rollouts-demo
  3. Namespace: default
  4. Status: Healthy
  5. Strategy: Canary
  6. Step: 8/8
  7. SetWeight: 100
  8. ActualWeight: 100
  9. Images: argoproj/rollouts-demo:blue (stable)
  10. Replicas:
  11. Desired: 5
  12. Current: 5
  13. Updated: 5
  14. Ready: 5
  15. Available: 5
  16. NAME KIND STATUS AGE INFO
  17. rollouts-demo Rollout Healthy 114s
  18. └──# revision:1
  19. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet Healthy 114s stable
  20. ├──□ rollouts-demo-7bf84f9696-4glv6 Pod Running 114s ready:1/1
  21. ├──□ rollouts-demo-7bf84f9696-7kqt6 Pod Running 114s ready:1/1
  22. ├──□ rollouts-demo-7bf84f9696-8k9hw Pod Running 114s ready:1/1
  23. ├──□ rollouts-demo-7bf84f9696-9cz2r Pod Running 114s ready:1/1
  24. └──□ rollouts-demo-7bf84f9696-jvzvd Pod Running 114s ready:1/1

可以看到该版本被标记为stable,而且STATUS为healthy。还可以在命令后面加一个--watch来实时监控服务状态,完整命令为kubectl argo rollouts get rollout rollouts-demo --watch

更新应用

接下来对应用进行更新。对应用进行更新和更新用Deployment部署的应用一样,更新镜像即可。argo rollouts插件有一个set image命令来更新镜像,如下:

  1. kubectl argo rollouts set image rollouts-demo \
  2. rollouts-demo=argoproj/rollouts-demo:yellow

更新过后,我们可以通过观察kubectl argo rollouts get rollout rollouts-demo --watch服务状态,如下:

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Paused
  4. Message: CanaryPauseStep
  5. Strategy: Canary
  6. Step: 1/8
  7. SetWeight: 20
  8. ActualWeight: 20
  9. Images: argoproj/rollouts-demo:blue (stable)
  10. argoproj/rollouts-demo:yellow (canary)
  11. Replicas:
  12. Desired: 5
  13. Current: 5
  14. Updated: 1
  15. Ready: 5
  16. Available: 5
  17. NAME KIND STATUS AGE INFO
  18. rollouts-demo Rollout Paused 9m12s
  19. ├──# revision:2
  20. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 44s canary
  21. └──□ rollouts-demo-789746c88d-l4gmd Pod Running 44s ready:1/1
  22. └──# revision:1
  23. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet Healthy 9m12s stable
  24. ├──□ rollouts-demo-7bf84f9696-4glv6 Pod Running 9m12s ready:1/1
  25. ├──□ rollouts-demo-7bf84f9696-8k9hw Pod Running 9m12s ready:1/1
  26. ├──□ rollouts-demo-7bf84f9696-9cz2r Pod Running 9m12s ready:1/1
  27. └──□ rollouts-demo-7bf84f9696-jvzvd Pod Running 9m12s ready:1/1

可以看到多了一个revision:2,而且该版本被标记为canary,而且状态是Status: Paused,canary接入流量为20%。

部署之所以处于Paused阶段,是因为我们在rollout.yaml中定义了发布第一个版本后会暂停,这时候需要手动接入接下来的更新。

argo rollouts提供了promote来进行后续的更新,命令如下:

  1. kubectl argo rollouts promote rollouts-demo

然后我们可以在watch界面,看到如下的更新过程。

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Paused
  4. Message: CanaryPauseStep
  5. Strategy: Canary
  6. Step: 3/8
  7. SetWeight: 40
  8. ActualWeight: 40
  9. Images: argoproj/rollouts-demo:blue (stable)
  10. argoproj/rollouts-demo:yellow (canary)
  11. Replicas:
  12. Desired: 5
  13. Current: 5
  14. Updated: 2
  15. Ready: 5
  16. Available: 5
  17. NAME KIND STATUS AGE INFO
  18. rollouts-demo Rollout Paused 15m
  19. ├──# revision:2
  20. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 6m46s canary
  21. ├──□ rollouts-demo-789746c88d-l4gmd Pod Running 6m46s ready:1/1
  22. └──□ rollouts-demo-789746c88d-67dwp Pod Running 19s ready:1/1
  23. └──# revision:1
  24. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet Healthy 15m stable
  25. ├──□ rollouts-demo-7bf84f9696-4glv6 Pod Running 15m ready:1/1
  26. ├──□ rollouts-demo-7bf84f9696-8k9hw Pod Running 15m ready:1/1
  27. ├──□ rollouts-demo-7bf84f9696-9cz2r Pod Running 15m ready:1/1
  28. └──□ rollouts-demo-7bf84f9696-jvzvd Pod Terminating 15m ready:1/1

因为后续的更新在pause阶段只暂停10s,所以会依次自动更新完,不需要手动介入,待更新完后整体的状态如下:

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Healthy
  4. Strategy: Canary
  5. Step: 8/8
  6. SetWeight: 100
  7. ActualWeight: 100
  8. Images: argoproj/rollouts-demo:yellow (stable)
  9. Replicas:
  10. Desired: 5
  11. Current: 5
  12. Updated: 5
  13. Ready: 5
  14. Available: 5
  15. NAME KIND STATUS AGE INFO
  16. rollouts-demo Rollout Healthy 17m
  17. ├──# revision:2
  18. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 8m35s stable
  19. ├──□ rollouts-demo-789746c88d-l4gmd Pod Running 8m35s ready:1/1
  20. ├──□ rollouts-demo-789746c88d-67dwp Pod Running 2m8s ready:1/1
  21. ├──□ rollouts-demo-789746c88d-k7mfk Pod Running 106s ready:1/1
  22. ├──□ rollouts-demo-789746c88d-glbfb Pod Running 94s ready:1/1
  23. └──□ rollouts-demo-789746c88d-d7m4f Pod Running 83s ready:1/1
  24. └──# revision:1
  25. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet ScaledDown 17m

可以看到第一个版本已经下线,第二个版本的状态为Healthy,而且镜像被标记为stable

终止更新

如果在更新应用的过程中,最新的应用有问题,需要终止更新需要怎么做呢?

我们先使用下面命令发布新版本应用,如下:

  1. kubectl argo rollouts set image rollouts-demo \
  2. rollouts-demo=argoproj/rollouts-demo:red

然后更新动作会在第一次更新的时候处于Paused状态,现在我们可以用abort来终止发布,如下:

  1. kubectl argo rollouts abort rollouts-demo

待执行完命令后,可以在watch页面,看到如下信息:

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Degraded
  4. Message: RolloutAborted: Rollout is aborted
  5. Strategy: Canary
  6. Step: 0/8
  7. SetWeight: 0
  8. ActualWeight: 0
  9. Images: argoproj/rollouts-demo:yellow (stable)
  10. Replicas:
  11. Desired: 5
  12. Current: 5
  13. Updated: 0
  14. Ready: 5
  15. Available: 5
  16. NAME KIND STATUS AGE INFO
  17. rollouts-demo Rollout Degraded 21m
  18. ├──# revision:3
  19. └──⧉ rollouts-demo-6f75f48b7 ReplicaSet ScaledDown 90s canary
  20. ├──# revision:2
  21. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 13m stable
  22. ├──□ rollouts-demo-789746c88d-l4gmd Pod Running 13m ready:1/1
  23. ├──□ rollouts-demo-789746c88d-67dwp Pod Running 6m46s ready:1/1
  24. ├──□ rollouts-demo-789746c88d-k7mfk Pod Running 6m24s ready:1/1
  25. ├──□ rollouts-demo-789746c88d-glbfb Pod Running 6m12s ready:1/1
  26. └──□ rollouts-demo-789746c88d-nntc9 Pod Running 18s ready:1/1
  27. └──# revision:1
  28. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet ScaledDown 21m

最终应用会回退到稳定版本。

但是我们可以看到Status是Degraded状态而并非Healthy状态,我们有必须要将其变成Healthy状态。最简单的办法就是执行如下命令重新发布一下版本:

  1. kubectl argo rollouts set image rollouts-demo \
  2. rollouts-demo=argoproj/rollouts-demo:yellow

执行过后,可以看到其状态立即变成Healthy,并且没有创建新的副本、新的版本,如下:

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Healthy
  4. Strategy: Canary
  5. Step: 8/8
  6. SetWeight: 100
  7. ActualWeight: 100
  8. Images: argoproj/rollouts-demo:yellow (stable)
  9. Replicas:
  10. Desired: 5
  11. Current: 5
  12. Updated: 5
  13. Ready: 5
  14. Available: 5
  15. NAME KIND STATUS AGE INFO
  16. rollouts-demo Rollout Healthy 40m
  17. ├──# revision:4
  18. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 32m stable
  19. ├──□ rollouts-demo-789746c88d-l4gmd Pod Running 32m ready:1/1
  20. ├──□ rollouts-demo-789746c88d-67dwp Pod Running 26m ready:1/1
  21. ├──□ rollouts-demo-789746c88d-k7mfk Pod Running 25m ready:1/1
  22. ├──□ rollouts-demo-789746c88d-glbfb Pod Running 25m ready:1/1
  23. └──□ rollouts-demo-789746c88d-nntc9 Pod Running 19m ready:1/1
  24. ├──# revision:3
  25. └──⧉ rollouts-demo-6f75f48b7 ReplicaSet ScaledDown 20m
  26. └──# revision:1
  27. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet ScaledDown 40m

回退应用

有时候在应用上线过后,有些BUG并没有发现,这时候要回退怎么办呢?argo rollouts有一个undo命令,可以进行回退。

比如我们要将版本回退到第一个版本,则执行一下命令:

  1. kubectl-argo-rollouts undo rollouts-demo --to-revision=1

然后通过watch界面可以看到如下信息:

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Paused
  4. Message: CanaryPauseStep
  5. Strategy: Canary
  6. Step: 1/8
  7. SetWeight: 20
  8. ActualWeight: 20
  9. Images: argoproj/rollouts-demo:blue (canary)
  10. argoproj/rollouts-demo:yellow (stable)
  11. Replicas:
  12. Desired: 5
  13. Current: 5
  14. Updated: 1
  15. Ready: 5
  16. Available: 5
  17. NAME KIND STATUS AGE INFO
  18. rollouts-demo Rollout Paused 45m
  19. ├──# revision:5
  20. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet Healthy 45m canary
  21. └──□ rollouts-demo-7bf84f9696-bn2lz Pod Running 36s ready:1/1
  22. ├──# revision:4
  23. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 36m stable
  24. ├──□ rollouts-demo-789746c88d-l4gmd Pod Running 36m ready:1/1
  25. ├──□ rollouts-demo-789746c88d-67dwp Pod Running 30m ready:1/1
  26. ├──□ rollouts-demo-789746c88d-k7mfk Pod Running 29m ready:1/1
  27. └──□ rollouts-demo-789746c88d-glbfb Pod Running 29m ready:1/1
  28. └──# revision:3
  29. └──⧉ rollouts-demo-6f75f48b7 ReplicaSet ScaledDown 25m

首先revision为1的版本标记没有,重新创建了一个为5的标记,而且第一步处于暂停状态,然后我们执行promote命令继续后续的更新,如下:

  1. kubectl argo rollouts promote rollouts-demo

然后我们可以看到如下信息:

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Healthy
  4. Strategy: Canary
  5. Step: 8/8
  6. SetWeight: 100
  7. ActualWeight: 100
  8. Images: argoproj/rollouts-demo:blue (stable)
  9. Replicas:
  10. Desired: 5
  11. Current: 5
  12. Updated: 5
  13. Ready: 5
  14. Available: 5
  15. NAME KIND STATUS AGE INFO
  16. rollouts-demo Rollout Healthy 48m
  17. ├──# revision:5
  18. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet Healthy 48m stable
  19. ├──□ rollouts-demo-7bf84f9696-bn2lz Pod Running 3m21s ready:1/1
  20. ├──□ rollouts-demo-7bf84f9696-xn6dr Pod Running 56s ready:1/1
  21. ├──□ rollouts-demo-7bf84f9696-w58vm Pod Running 44s ready:1/1
  22. ├──□ rollouts-demo-7bf84f9696-fns8d Pod Running 33s ready:1/1
  23. └──□ rollouts-demo-7bf84f9696-qt6f9 Pod Running 22s ready:1/1
  24. ├──# revision:4
  25. └──⧉ rollouts-demo-789746c88d ReplicaSet ScaledDown 39m
  26. └──# revision:3
  27. └──⧉ rollouts-demo-6f75f48b7 ReplicaSet ScaledDown 27m

Images可以看到回退到我们最初版本为blue的镜像了。

Traffic Shifting

上面我们并没有接入外部流量,仅仅是在内部使用展示了金丝雀部署过程,下面我们接入外部流量进行测试。

Argo-Rollout主要集成了IngressServiceMesh两种流量控制方法。

目前Ingress支持ALB和NGINX ingress。但是我使用的是nginx ingress。

部署应用

我们依然使用官方的例子进行展示。

首先删除上面的例子。

  1. kubectl delete -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
  2. kubectl delete -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

然后重新部署一个官方的例子,如下:

  1. kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/rollout.yaml
  2. kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/services.yaml
  3. kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/ingress.yaml

这个例子包含1个rollout,2个service,1个ingress。

它们的配置文件分别如下。
rollout.yaml,为了便与测试,我将权重改为了50

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Rollout
  3. metadata:
  4. name: rollouts-demo
  5. spec:
  6. replicas: 1
  7. strategy:
  8. canary:
  9. canaryService: rollouts-demo-canary
  10. stableService: rollouts-demo-stable
  11. trafficRouting:
  12. nginx:
  13. stableIngress: rollouts-demo-stable
  14. steps:
  15. - setWeight: 50
  16. - pause: {}
  17. revisionHistoryLimit: 2
  18. selector:
  19. matchLabels:
  20. app: rollouts-demo
  21. template:
  22. metadata:
  23. labels:
  24. app: rollouts-demo
  25. spec:
  26. containers:
  27. - name: rollouts-demo
  28. image: argoproj/rollouts-demo:blue
  29. ports:
  30. - name: http
  31. containerPort: 8080
  32. protocol: TCP
  33. resources:
  34. requests:
  35. memory: 32Mi
  36. cpu: 5m

services.yaml

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: rollouts-demo-canary
  5. spec:
  6. ports:
  7. - port: 80
  8. targetPort: http
  9. protocol: TCP
  10. name: http
  11. selector:
  12. app: rollouts-demo
  13. # This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:
  14. # rollouts-pod-template-hash: 7bf84f9696
  15. ---
  16. apiVersion: v1
  17. kind: Service
  18. metadata:
  19. name: rollouts-demo-stable
  20. spec:
  21. ports:
  22. - port: 80
  23. targetPort: http
  24. protocol: TCP
  25. name: http
  26. selector:
  27. app: rollouts-demo
  28. # This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.:
  29. # rollouts-pod-template-hash: 789746c88d

ingress.yaml

  1. apiVersion: networking.k8s.io/v1beta1
  2. kind: Ingress
  3. metadata:
  4. name: rollouts-demo-stable
  5. annotations:
  6. kubernetes.io/ingress.class: nginx
  7. spec:
  8. rules:
  9. - host: rollouts-demo.local
  10. http:
  11. paths:
  12. - path: /
  13. backend:
  14. # Reference to a Service name, also specified in the Rollout spec.strategy.canary.stableService field
  15. serviceName: rollouts-demo-stable
  16. servicePort: 80

从配置文件可以看出Rollout里分别用canaryServicestableService分别定义了该应用灰度的Service Name(rollouts-demo-canary)和当前版本的Service Name(rollouts-demo-stable)。而且rollouts-demo-canary 和 rollouts-demo-stable的service的内容是一样的。selector中暂时没有填上pod-template-hash,Argo-Rollout Controller会根据实际的ReplicaSet hash来修改该值。

当我们创建完ingress后,Rollout Controller会根据ingress rollouts-demo-stable内容,自动创建一个ingress用了灰度的流量,名字为--canary,所以这里多了一个ingress rollouts-demo-rollouts-demo-stable-canary,将流量导向Canary Service(rollouts-demo-canary)。如下:

  1. # kubectl get ingress
  2. NAME HOSTS ADDRESS PORTS AGE
  3. rollouts-demo-rollouts-demo-stable-canary rollout-demo.coolops.cn 80 9m25s
  4. rollouts-demo-stable rollout-demo.coolops.cn 80 4m12s

rollouts-demo-rollouts-demo-stable-canary的内容如下:

  1. # kubectl get ingress rollouts-demo-rollouts-demo-stable-canary -o yaml
  2. apiVersion: extensions/v1beta1
  3. kind: Ingress
  4. metadata:
  5. annotations:
  6. kubernetes.io/ingress.class: traefik
  7. nginx.ingress.kubernetes.io/canary: "true"
  8. nginx.ingress.kubernetes.io/canary-weight: "0"
  9. creationTimestamp: "2020-12-09T02:21:52Z"
  10. generation: 2
  11. name: rollouts-demo-rollouts-demo-stable-canary
  12. namespace: default
  13. ownerReferences:
  14. - apiVersion: argoproj.io/v1alpha1
  15. blockOwnerDeletion: true
  16. controller: true
  17. kind: Rollout
  18. name: rollouts-demo
  19. uid: 4e74913b-5c89-4275-8f4c-768f23c63c34
  20. resourceVersion: "15681411"
  21. selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/rollouts-demo-rollouts-demo-stable-canary
  22. uid: bc66dfc4-6e98-419b-a288-f67e1233ef3e
  23. spec:
  24. rules:
  25. - host: rollout-demo.coolops.cn
  26. http:
  27. paths:
  28. - backend:
  29. serviceName: rollouts-demo-canary
  30. servicePort: 80
  31. path: /

通过域名访问,可以看到如下界面。
image.png

更新应用

现在通过以下命令来进行应用更新操作。

  1. kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

然后通过状态窗口可以看到如下信息。

  1. Name: rollouts-demo
  2. Namespace: default
  3. Status: Paused
  4. Message: CanaryPauseStep
  5. Strategy: Canary
  6. Step: 1/2
  7. SetWeight: 50
  8. ActualWeight: 50
  9. Images: argoproj/rollouts-demo:blue (stable)
  10. argoproj/rollouts-demo:yellow (canary)
  11. Replicas:
  12. Desired: 1
  13. Current: 2
  14. Updated: 1
  15. Ready: 2
  16. Available: 2
  17. NAME KIND STATUS AGE INFO
  18. rollouts-demo Rollout Paused 2m13s
  19. ├──# revision:2
  20. └──⧉ rollouts-demo-789746c88d ReplicaSet Healthy 89s canary
  21. └──□ rollouts-demo-789746c88d-spn4s Pod Running 89s ready:1/1
  22. └──# revision:1
  23. └──⧉ rollouts-demo-7bf84f9696 ReplicaSet Healthy 2m stable
  24. └──□ rollouts-demo-7bf84f9696-7rwkx Pod Running 2m ready:1/1

然后可以看到rollouts-demo-rollouts-demo-stable-canary的ingress的annotations中新增了两个参数,如下:

  1. # kubectl get ingress rollouts-demo-rollouts-demo-stable-canary -o yaml
  2. apiVersion: extensions/v1beta1
  3. kind: Ingress
  4. metadata:
  5. annotations:
  6. kubernetes.io/ingress.class: nginx
  7. nginx.ingress.kubernetes.io/canary: "true"
  8. nginx.ingress.kubernetes.io/canary-weight: "50"
  9. creationTimestamp: "2020-12-09T03:01:04Z"
  10. generation: 1
  11. name: rollouts-demo-rollouts-demo-stable-canary
  12. namespace: default
  13. ownerReferences:
  14. - apiVersion: argoproj.io/v1alpha1
  15. blockOwnerDeletion: true
  16. controller: true
  17. kind: Rollout
  18. name: rollouts-demo
  19. uid: 4d956f2a-9e15-4453-b918-926c4a75f884
  20. resourceVersion: "15686969"
  21. selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/rollouts-demo-rollouts-demo-stable-canary
  22. uid: c9242819-d088-4fc4-bd4d-8870360fa96e
  23. spec:
  24. rules:
  25. - host: rollout-demo.coolops.cn
  26. http:
  27. paths:
  28. - backend:
  29. serviceName: rollouts-demo-canary
  30. servicePort: 80
  31. path: /

然后通过网页,可以看到如下的输出展示。
image.png

然后可以通过验证结果来判断是否继续还是终止。
如果继续使用如下命令:

  1. kubectl argo rollouts promote rollouts-demo

如果终止使用如下命令:

  1. kubectl argo rollouts abort rollouts-demo

写在最后

目前我还在测试阶段,并没有实际接入使用。通过测试来看,Argo-Rollout提供更加强大的Deployment,包含比较适合运维的金丝雀发布和蓝绿发布功能,要使用蓝绿发布,仅需要配置rollout,如下:

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Rollout ##部署完rollout后就有了这个kind 资源,这个资源和deployment类似也是管理你的副本集的,所以不能像deployment那样在k8s界面看见,只能通过kubectl命令行
  3. metadata:
  4. name: rollout-bluegreen
  5. namespace: rollout-test
  6. spec:
  7. template:
  8. spec:
  9. terminationGracePeriodSeconds: 30
  10. containers:
  11. - resources: #{}
  12. requests:
  13. cpu: "1"
  14. memory: "2Gi"
  15. limits:
  16. cpu: "2"
  17. memory: "2Gi"
  18. terminationMessagePolicy: File
  19. imagePullPolicy: Always
  20. name: rollout-bluegreen
  21. image: argoproj/rollouts-demo:green #nginx:1.17.1
  22. schedulerName: default-scheduler
  23. securityContext: {}
  24. dnsPolicy: ClusterFirst
  25. restartPolicy: Always
  26. metadata:
  27. labels:
  28. app: rollout-bluegreen
  29. selector:
  30. matchLabels:
  31. app: rollout-bluegreen
  32. replicas: 2
  33. strategy:
  34. blueGreen: ##蓝绿启用配置
  35. activeService: rollout-bluegreen-active #生效的服务,需要自己创建建本代码最下面service资源。
  36. previewService: rollout-bluegreen-preview #配置预览服务,同理需要自己创建
  37. autoPromotionEnabled: true ##是否直接切换,如为true,会在新版本变绿后直接切换到对外服务。
  38. scaleDownDelayRevisionLimit: 0
  39. previewReplicaCount: 1 #新版本的pod数量,设为一个从而控制资源消耗
  40. rollingUpdate:
  41. maxUnavailable: 25%
  42. maxSurge: 25%
  43. type: RollingUpdate
  44. revisionHistoryLimit: 2
  45. progressDeadlineSeconds: 600
  46. ---
  47. apiVersion: v1
  48. kind: Service
  49. metadata:
  50. name: rollout-bluegreen-active
  51. namespace: rollout-test
  52. spec:
  53. sessionAffinity: None
  54. selector:
  55. app: rollout-bluegreen
  56. ports:
  57. - protocol: TCP
  58. port: 80
  59. targetPort: 8080
  60. type: LoadBalancer

整体使用还是比较丝滑,如果测试通过后续考虑集成进CD中。更多内容可以到https://argoproj.github.io/argo-rollouts/进行学习。