基于Argo-CD的Gitops最佳实践

Argo-CD是社区非常流行的Gitops的发布工具。本文介绍如何在ACS集群使用Argo-CD完成Gitops部署、升级、回滚的最佳实践。

前提条件

发布第一个应用

场景说明

  1. gitops-demo示例包含社区的echoserver服务和对应的Deployment、Service配置。

  2. 示例包含两个主要镜像版本标签(tag):v1和v2,分别对应echoserver不同版本的镜像。

  3. 使用Argo-CD能够以Gitops的方式部署v1版本,并随后升级到v2版本。

  4. 示例包含一个v3 tag,该版本的echoserver将会启动失败,可以通过Argo-CD快速回滚到v2。

步骤一:部署Argo-CD

  1. 使用Helm一键部署Argo-CD服务。

    helm repo add argo https://argoproj.github.io/argo-helm
    helm repo update
    helm install argo argo/argocd
  2. 执行以下命令,下载Argo-CD CLI命令行工具。

    MAC命令示例如下。更多安装详情,请参见cli_installation

    brew install argocd
  3. 执行以下命令,通过LoadBalancer暴露Argo-CD Server服务。

    # 将argocd server Service开启LoadBalancer。
    kubectl patch svc argo-argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
    
    # 获取argocd server LoadBalancer EXTERNAL-IP。
    kubectl get svc -n argocd argo-argocd-server
    NAME                 TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE
    argo-argocd-server   LoadBalancer   x.x.x.x       x.x.x.x          80/TCP,443/TCP   170m
  4. 通过LoadBalancer external-ip访问Argo-CD Server服务。

    image.png

  5. 通过CLI获取Argo-CD Server的密码。

    kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
    jZaiw3hoIR # 密码

    image.png

  6. 通过argocd命令行登录Argo-CD服务。

    $  argocd login {loadbalancer external-ip}
    Username: admin
    Password:
    'admin:login' logged in successfully

步骤二:创建Gitops Application应用

  1. 通过argocd命令行添加Git Repo。

    $ argocd repo add https://gitee.com/AliyunContainerService/acs-samples.git --name gitops-demo
    Repository 'https://gitee.com/AliyunContainerService/acs-samples.git' added
  2. 获取Argo-CD管理的Cluster列表。

    argocd cluster list

    预期输出:

    SERVER                          NAME        VERSION  STATUS   MESSAGE                                                  PROJECT
    https://kubernetes.default.svc  in-cluster           Unknown  Cluster has no applications and is not being monitor

    本篇场景没有external-cluster,因此后续都可以使用kubernetes.default.svc实现对当前集群的部署。

  3. 执行以下命令,通过Application方式创建应用,其中revision为v1版本的tag。

    argocd app create gitops-demo --repo https://gitee.com/AliyunContainerService/acs-samples.git --project default --sync-policy none --revision v1 --path argo-demo --dest-namespace default --dest-server https://kubernetes.default.svc

    预期输出:

    application 'gitops-demo' created
  4. 执行以下命令,同步echoserver服务,将echoserver部署到K8s集群。

    argocd app sync gitops-demo

    预期输出:

    Name:               gitops-demo
    Project:            default
    Server:             https://kubernetes.default.svc
    Namespace:          default
    URL:                https://39.105.XXX.XXX/applications/gitops-demo
    Repo:               https://gitee.com/AliyunContainerService/acs-samples.git
    Target:             v1
    Path:               argo-demo/config
    SyncWindow:         Sync Allowed
    Sync Policy:        <none>
    Sync Status:        Synced to v1 (db29c76)
    Health Status:      Healthy
    
    Operation:          Sync
    Sync Revision:      db29c76e1550b0921d08dc4ffc19ba57246b2910
    Phase:              Succeeded
    Start:              2023-11-22 19:53:43 +0800 CST
    Finished:           2023-11-22 19:53:45 +0800 CST
    Duration:           2s
    Message:            successfully synced (all tasks run)
    
    GROUP  KIND        NAMESPACE  NAME         STATUS  HEALTH   HOOK  MESSAGE
           Service     default    echo-server  Synced  Healthy        service/echo-server configured
    apps   Deployment  default    echo-server  Synced  Healthy        deployment.apps/echo-server configured       ingress.networking.k8s.io/ingress-demo created
    
  5. 在ArgoCD UI的Applications中,单击gitops-demo查看应用详情。

    image.png

步骤三:升级到v2版本

  1. 通过ArgoCD CLI将echoserver升级到v2版本。

    argocd app sync gitops-demo --revision v2
  2. 通过ArgoCD CLI查看应用部署状态。

    argocd app get gitops-demo

    预期输出:

    Name:               gitops-demo
    Project:            default
    Server:             https://kubernetes.default.svc
    Namespace:          default
    URL:                https://39.105.XXX.XXX/applications/gitops-demo
    Repo:               https://gitee.com/AliyunContainerService/acs-samples.git
    Target:             v1
    Path:               argo-demo/config
    SyncWindow:         Sync Allowed
    Sync Policy:        <none>
    Sync Status:        OutOfSync from v1 (db29c76)
    Health Status:      Healthy
    
    GROUP  KIND        NAMESPACE  NAME         STATUS     HEALTH   HOOK  MESSAGE
           Service     default    echo-server  Synced     Healthy        service/echo-server unchanged
    apps   Deployment  default    echo-server  OutOfSync  Healthy        deployment.apps/echo-server configured

    argo-cd服务能够观察deployment的状态。如果是在升级的过程中deployment状态将是 Progressing,当升级完成时会变化为Healthy状态。

(可选)步骤四:升级v3失败,回滚到v2

  1. 通过ArgoCD CLI将echoserver升级到v3版本。

    argocd app sync gitops-demo --revision v3
  2. 通过kubectl CLI,查看v3版本Pod是否启动失败。

    kubectl get pods

    预期输出:

    NAME                           READY   STATUS         RESTARTS   AGE
    echo-server-6bb9dcf678-wphsf   0/1     ErrImagePull   0          53s
    echo-server-6d6455bfd6-6n9wj   1/1     Running        0          2m49
  3. 通过ArgoCD CLI快速回滚到v2版本。

    argocd app sync gitops-demo --revision v2
  4. 执行以下命令,查看Pod状态。

    kubectl get pods

    预期输出:

    NAME                           READY   STATUS    RESTARTS   AGE
    echo-server-6d6455bfd6-6n9wj   1/1     Running   0          3m24s

    可以看到Pod已经回滚,且状态为Running

结合PDB进行应用的高可用防护

PDB(PodDisruptionBudget)可以通过定义minAvailable方式来对应用进行最小可用副本数的防护,在ACS上面的应用我们推荐配置PDB来保护一些驱逐场景下应用的最小可用副本数,进而保证应用至少有一些Pod可以持续的对外提供服务。例如,如下配置表明任何时间至少有一个Pod可用。

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: echoserver-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: echo-server

基于CPU使用率的弹性伸缩

ACS的一大特点就是弹性,即业务可以根据峰值情况来动态的扩缩容业务Pod数量,既能满足业务高峰期时的容量要求,又可能在业务低峰期时降低成本。

本示例通过社区开源的组件Keda对应用的CPU使用率进行监控,当CPU使用率大于50%时进行扩容,当CPU使用率小于50%时进行缩容。

前提条件

  • 已在组件管理页面,安装Metrics Server组件。具体操作,请参见管理组件

  • 已通过Helm安装部署Keda弹性伸缩应用。

    展开查看部署相关命令

    helm repo add kedacore https://kedacore.github.io/charts
    
    helm repo update
    
    kubectl create namespace keda
    
    helm install keda kedacore/keda --namespace keda

步骤一:创建Keda ScaledObject资源

如下配置通过scaleTargetRef指定生效的Deployment Name,Triggers部分则配置为基于CPU使用率来进行弹性伸缩,当超过50%时,则进行扩容。关于ScaleObject配置详情,请参见社区文档

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: cpu-scaledobject
spec:
  maxReplicaCount: 10
  minReplicaCount: 1
  pollingInterval: 10
  cooldownPeriod: 2
  scaleTargetRef:
    name: echo-server
  triggers:
    - type: cpu
      metricType: Utilization # Allowed types are 'Utilization' or 'AverageValue'
      metadata:
        value: "50"

将该资源部署到ACS集群之后,也可以通过ACS控制台来查看该ScaleObject是否正常工作,生成如下的弹性伸缩(HPA)表明正常。

image.png

步骤二:对echo-server服务进行HTTP压测

Apache Bench是Apache自带的压测工具,使用它可以进行HTTP请求的压测。执行以下命令,可以快速提高echoserver服务的CPU使用率。

ab -n 100000000 -c 1000 -k http://{echo-server loadbalance ip}:8080/apis/echo

您可以通过ACS控制台,查看echoserver服务CPU使用率快速上涨到75%。

image.png

步骤三:Keda自动对应用进行扩容

Keda监听到应用的CPU使用率超过50%后,会触发HPA对应用进行扩容。通过ACS控制台可以看到 echoserver已经有两个实例(初始化只有一个Pod)。

image.png

通过ACS控制台,还可以看到伸缩事件详情。

image.png

步骤四:业务低峰时自动缩容

等到业务低峰时,Keda监测到Pod的CPU使用率比较低,会自动对业务进行缩容。通过ACS控制台可以看到对应的CPU指标以及当前应用只有一个Pod实例。

image.png

image.png