使用argo-rollouts实现金丝雀发布(下)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 使用argo-rollouts实现金丝雀发布

回退应用


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


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


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


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


Name:            rollouts-demo
Namespace:       default
Status:          ॥ Paused
Message:         CanaryPauseStep
Strategy:        Canary
  Step:          1/8
  SetWeight:     20
  ActualWeight:  20
Images:          argoproj/rollouts-demo:blue (canary)
                 argoproj/rollouts-demo:yellow (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       1
  Ready:         5
  Available:     5
NAME                                       KIND        STATUS        AGE  INFO
⟳ rollouts-demo                            Rollout     ॥ Paused      45m  
├──# revision:5                                                           
│  └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy     45m  canary
│     └──□ rollouts-demo-7bf84f9696-bn2lz  Pod         ✔ Running     36s  ready:1/1
├──# revision:4                                                           
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy     36m  stable
│     ├──□ rollouts-demo-789746c88d-l4gmd  Pod         ✔ Running     36m  ready:1/1
│     ├──□ rollouts-demo-789746c88d-67dwp  Pod         ✔ Running     30m  ready:1/1
│     ├──□ rollouts-demo-789746c88d-k7mfk  Pod         ✔ Running     29m  ready:1/1
│     └──□ rollouts-demo-789746c88d-glbfb  Pod         ✔ Running     29m  ready:1/1
└──# revision:3                                                           
   └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown  25m


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


kubectl argo rollouts promote rollouts-demo


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


Name:            rollouts-demo
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          argoproj/rollouts-demo:blue (stable)
Replicas:
  Desired:       5
  Current:       5
  Updated:       5
  Ready:         5
  Available:     5
NAME                                       KIND        STATUS        AGE    INFO
⟳ rollouts-demo                            Rollout     ✔ Healthy     48m    
├──# revision:5                                                             
│  └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy     48m    stable
│     ├──□ rollouts-demo-7bf84f9696-bn2lz  Pod         ✔ Running     3m21s  ready:1/1
│     ├──□ rollouts-demo-7bf84f9696-xn6dr  Pod         ✔ Running     56s    ready:1/1
│     ├──□ rollouts-demo-7bf84f9696-w58vm  Pod         ✔ Running     44s    ready:1/1
│     ├──□ rollouts-demo-7bf84f9696-fns8d  Pod         ✔ Running     33s    ready:1/1
│     └──□ rollouts-demo-7bf84f9696-qt6f9  Pod         ✔ Running     22s    ready:1/1
├──# revision:4                                                             
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  • ScaledDown  39m    
└──# revision:3                                                             
   └──⧉ rollouts-demo-6f75f48b7            ReplicaSet  • ScaledDown  27m


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


Traffic Shifting


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


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


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


部署应用


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


首先删除上面的例子。


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


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


kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/rollout.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/nginx/services.yaml
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


apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-demo
spec:
  replicas: 1
  strategy:
    canary:
      canaryService: rollouts-demo-canary
      stableService: rollouts-demo-stable
      trafficRouting:
        nginx:
          stableIngress: rollouts-demo-stable
      steps:
      - setWeight: 50
      - pause: {}
  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


services.yaml


apiVersion: v1
kind: Service
metadata:
  name: rollouts-demo-canary
spec:
  ports:
  - port: 80
    targetPort: http
    protocol: TCP
    name: http
  selector:
    app: rollouts-demo
    # This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:
    # rollouts-pod-template-hash: 7bf84f9696
---
apiVersion: v1
kind: Service
metadata:
  name: rollouts-demo-stable
spec:
  ports:
  - port: 80
    targetPort: http
    protocol: TCP
    name: http
  selector:
    app: rollouts-demo
    # This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.:
    # rollouts-pod-template-hash: 789746c88d


ingress.yaml


apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: rollouts-demo-stable
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: rollouts-demo.local
    http:
      paths:
      - path: /
        backend:
          # Reference to a Service name, also specified in the Rollout spec.strategy.canary.stableService field
          serviceName: rollouts-demo-stable
          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)。如下:


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


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


# kubectl get ingress rollouts-demo-rollouts-demo-stable-canary -o yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "0"
  creationTimestamp: "2020-12-09T02:21:52Z"
  generation: 2
  name: rollouts-demo-rollouts-demo-stable-canary
  namespace: default
  ownerReferences:
  - apiVersion: argoproj.io/v1alpha1
    blockOwnerDeletion: true
    controller: true
    kind: Rollout
    name: rollouts-demo
    uid: 4e74913b-5c89-4275-8f4c-768f23c63c34
  resourceVersion: "15681411"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/rollouts-demo-rollouts-demo-stable-canary
  uid: bc66dfc4-6e98-419b-a288-f67e1233ef3e
spec:
  rules:
  - host: rollout-demo.coolops.cn
    http:
      paths:
      - backend:
          serviceName: rollouts-demo-canary
          servicePort: 80
        path: /


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


640.png


更新应用


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


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


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


Name:            rollouts-demo
Namespace:       default
Status:          ॥ Paused
Message:         CanaryPauseStep
Strategy:        Canary
  Step:          1/2
  SetWeight:     50
  ActualWeight:  50
Images:          argoproj/rollouts-demo:blue (stable)
                 argoproj/rollouts-demo:yellow (canary)
Replicas:
  Desired:       1
  Current:       2
  Updated:       1
  Ready:         2
  Available:     2
NAME                                       KIND        STATUS     AGE    INFO
⟳ rollouts-demo                            Rollout     ॥ Paused   2m13s  
├──# revision:2                                                          
│  └──⧉ rollouts-demo-789746c88d           ReplicaSet  ✔ Healthy  89s    canary
│     └──□ rollouts-demo-789746c88d-spn4s  Pod         ✔ Running  89s    ready:1/1
└──# revision:1                                                          
   └──⧉ rollouts-demo-7bf84f9696           ReplicaSet  ✔ Healthy  2m     stable
      └──□ rollouts-demo-7bf84f9696-7rwkx  Pod         ✔ Running  2m     ready:1/1


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


# kubectl get ingress rollouts-demo-rollouts-demo-stable-canary -o yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "50"
  creationTimestamp: "2020-12-09T03:01:04Z"
  generation: 1
  name: rollouts-demo-rollouts-demo-stable-canary
  namespace: default
  ownerReferences:
  - apiVersion: argoproj.io/v1alpha1
    blockOwnerDeletion: true
    controller: true
    kind: Rollout
    name: rollouts-demo
    uid: 4d956f2a-9e15-4453-b918-926c4a75f884
  resourceVersion: "15686969"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/rollouts-demo-rollouts-demo-stable-canary
  uid: c9242819-d088-4fc4-bd4d-8870360fa96e
spec:
  rules:
  - host: rollout-demo.coolops.cn
    http:
      paths:
      - backend:
          serviceName: rollouts-demo-canary
          servicePort: 80
        path: /


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


640.png


然后可以通过验证结果来判断是否继续还是终止。


如果继续使用如下命令:


kubectl argo rollouts promote rollouts-demo


如果终止使用如下命令:


kubectl argo rollouts abort rollouts-demo


写在最后


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


apiVersion: argoproj.io/v1alpha1
kind: Rollout  ##部署完rollout后就有了这个kind 资源,这个资源和deployment类似也是管理你的副本集的,所以不能像deployment那样在k8s界面看见,只能通过kubectl命令行
metadata:
  name: rollout-bluegreen
  namespace: rollout-test
spec:
  template:
    spec:
      terminationGracePeriodSeconds: 30
      containers:
      - resources: #{}
          requests:
            cpu: "1"
            memory: "2Gi"
          limits:
            cpu: "2"
            memory: "2Gi"
        terminationMessagePolicy: File
        imagePullPolicy: Always
        name: rollout-bluegreen
        image: argoproj/rollouts-demo:green #nginx:1.17.1
      schedulerName: default-scheduler
      securityContext: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    metadata:
      labels:
        app: rollout-bluegreen
  selector:
    matchLabels:
      app: rollout-bluegreen
  replicas: 2
  strategy:
    blueGreen:  ##蓝绿启用配置
      activeService: rollout-bluegreen-active   #生效的服务,需要自己创建建本代码最下面service资源。
      previewService: rollout-bluegreen-preview  #配置预览服务,同理需要自己创建
      autoPromotionEnabled: true  ##是否直接切换,如为true,会在新版本变绿后直接切换到对外服务。
      scaleDownDelayRevisionLimit: 0
      previewReplicaCount: 1  #新版本的pod数量,设为一个从而控制资源消耗
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
    type: RollingUpdate
  revisionHistoryLimit: 2
  progressDeadlineSeconds: 600
---
apiVersion: v1
kind: Service
metadata:
  name: rollout-bluegreen-active
  namespace: rollout-test
spec:
  sessionAffinity: None
  selector:
    app: rollout-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: LoadBalancer


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

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
监控 安全 Perl
Istio 升级新方式:金丝雀升级
Istio 1.6 推出了渐进式的升级方式:金丝雀升级,为相对头疼的 Istio 升级问题提供了一种解决方案。
914 0
|
20天前
|
Kubernetes 监控 数据可视化
k8s学习--使用argo-rollouts实现金丝雀发布
k8s学习--使用argo-rollouts实现金丝雀发布
|
测试技术 微服务 负载均衡
微服务部署:蓝绿部署、滚动部署、灰度发布、金丝雀发布
在项目迭代的过程中,不可避免需要”上线“。上线对应着部署,或者重新部署;部署对应着修改;修改则意味着风险。 目前有很多用于部署的技术,有的简单,有的复杂;有的得停机,有的不需要停机即可完成部署。
2865 0
|
2月前
|
Kubernetes 监控 测试技术
在K8S中,如何实现金丝雀发布(灰度发布)?蓝绿发布?
在K8S中,如何实现金丝雀发布(灰度发布)?蓝绿发布?
|
Kubernetes 容器
K8s 金丝雀发布
K8s 金丝雀发布
106 0
|
Kubernetes Cloud Native Java
灰度发布、蓝绿部署、金丝雀都是啥?
在滚动部署中,应用的新版本逐步替换旧版本。实际的部署发生在一段时间内。在此期间,新旧版本会共存,而不会影响功能和用户体验。这个过程可以更轻易的回滚和旧组件不兼容的任何新组件。
灰度发布、蓝绿部署、金丝雀都是啥?
|
Kubernetes 测试技术 UED
灰度(金丝雀)发布、蓝绿部署、滚动发布
灰度(金丝雀)发布、蓝绿部署、滚动发布
|
Prometheus Kubernetes 负载均衡
Kruise Rollout v0.3.0:教你玩转 Deployment 分批发布和流量灰度
Kruise Rollout v0.3.0:教你玩转 Deployment 分批发布和流量灰度
Kruise Rollout v0.3.0:教你玩转 Deployment 分批发布和流量灰度
|
Kubernetes 负载均衡 监控
Kubernetes 实现灰度和蓝绿发布
Kubernetes 实现灰度和蓝绿发布
1186 1
|
运维 Kubernetes 负载均衡
kubernetes 灰度发布
kubernetes 灰度发布
512 1