Argo-CD是社区非常流行的Gitops的发布工具。本文介绍如何在ACS集群使用Argo-CD完成Gitops部署、升级、回滚的最佳实践。
前提条件
已创建一个ACS集群,用于部署Argo-CD和业务服务。具体操作,请参见创建ACS集群。
已准备部署应用YAML到Git repo。本文使用一个Gitee仓库gitops-demo。
已安装CoreDNS组件。具体操作,请参见管理组件。
重要未安装CoreDNS组件将导致Argo-CD不能正常工作。
发布第一个应用
场景说明
gitops-demo示例包含社区的echoserver服务和对应的Deployment、Service配置。
示例包含两个主要镜像版本标签(tag):v1和v2,分别对应echoserver不同版本的镜像。
使用Argo-CD能够以Gitops的方式部署v1版本,并随后升级到v2版本。
示例包含一个v3 tag,该版本的echoserver将会启动失败,可以通过Argo-CD快速回滚到v2。
步骤一:部署Argo-CD
使用Helm一键部署Argo-CD服务。
helm repo add argo https://argoproj.github.io/argo-helm helm repo update helm install argo argo/argocd
执行以下命令,下载Argo-CD CLI命令行工具。
MAC命令示例如下。更多安装详情,请参见cli_installation。
brew install argocd
执行以下命令,通过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
通过LoadBalancer external-ip访问Argo-CD Server服务。
通过CLI获取Argo-CD Server的密码。
kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d jZaiw3hoIR # 密码
通过argocd命令行登录Argo-CD服务。
$ argocd login {loadbalancer external-ip} Username: admin Password: 'admin:login' logged in successfully
步骤二:创建Gitops Application应用
通过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
获取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实现对当前集群的部署。
执行以下命令,通过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
执行以下命令,同步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
在ArgoCD UI的Applications中,单击gitops-demo查看应用详情。
步骤三:升级到v2版本
通过ArgoCD CLI将echoserver升级到v2版本。
argocd app sync gitops-demo --revision v2
通过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
通过ArgoCD CLI将echoserver升级到v3版本。
argocd app sync gitops-demo --revision v3
通过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
通过ArgoCD CLI快速回滚到v2版本。
argocd app sync gitops-demo --revision v2
执行以下命令,查看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弹性伸缩应用。
步骤一:创建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)表明正常。
步骤二:对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%。
步骤三:Keda自动对应用进行扩容
Keda监听到应用的CPU使用率超过50%后,会触发HPA对应用进行扩容。通过ACS控制台可以看到 echoserver已经有两个实例(初始化只有一个Pod)。
通过ACS控制台,还可以看到伸缩事件详情。
步骤四:业务低峰时自动缩容
等到业务低峰时,Keda监测到Pod的CPU使用率比较低,会自动对业务进行缩容。通过ACS控制台可以看到对应的CPU指标以及当前应用只有一个Pod实例。