-
使用 Argo CD 探索 GitOps
Argo CD 是一个用于 Kubernetes 的声明式 GitOps 持续交付工具。
管理 Kubernetes 集群的复杂性可能是一项艰巨的任务,尤其是在跨多个环境部署和同步应用程序时。为了研究如何更好地应对此类挑战,我决定研究流行的 GitOps 持续交付工具 Argo CD。Argo CD 是一款开源 GitOps 持续交付工具,可为 Kubernetes 集群管理带来便利性和自动化。借助此工具,工程师可以利用 GitOps 的强大功能,以声明方式定义 Git 存储库中 Kubernetes 集群的所需状态,从而实现高效、自动化的应用程序部署。
让我们通过回顾 Argo CD 在自己的项目文档中的解释来开始这篇文章。
Argo CD 被实现为 Kubernetes 控制器,它持续监控正在运行的应用程序并将当前的实时状态与所需的目标状态进行比较。Argo CD 报告并可视化差异,同时提供自动或手动将实时状态同步回所需目标状态的方法。对 Git 存储库中所需目标状态所做的任何修改都可以自动应用并反映在指定的目标环境中。
换句话说,Argo CD 是 Kubernetes 的声明式 GitOps 持续交付工具。让我们更深入地了解这实际上意味着什么。
GitOps 是一种软件开发和交付流程,强调使用 Git 存储库作为定义系统所需状态(例如云基础设施或软件应用程序)的事实来源。在这个持续交付过程中,整个交付流程(从代码提交到部署)都是使用 Git 实现自动化和版本控制的。系统的所需状态(包括基础设施、配置和/或应用程序源)被定义为代码并捕获为存储库中的提交。一旦提交,声明的系统状态可以使用 GitOps 部署工具与系统实时持续同步。其结果是一个可靠的持续交付流程,使 DevOps 团队能够以自动化和可审核的方式快速、自信地部署代码更改。
Argo CD 是一个基于 GitOps 的持续交付工具,在同步系统状态时采用“pull”模式。“pull”模式是目标环境从源代码控制存储库“pull”最新提交并根据声明的系统状态自动更新自身。这与“push”模式相反,“push”模式将更改从开发环境推送到目标环境。
持续交付的“pull”模型如下所示:
这里的意义在于,“push”模式要求交付机制提供对目标环境的入站网络访问,而“pull”模式仅需要出站网络访问。出站连接被认为风险较小,因为内部网络通常通过对发起网络通信的受信任实体授予最小权限的访问控制来保护自身。入站连接会带来更大的安全风险,因为它们源自外部、不受信任的网络,并且可能包含恶意流量。
在更高层面上,Argo CD 部署过程按以下方式工作:
- 开发人员向受监控的 Git 存储库进行提交。
- Argo CD 识别提交,克隆存储库,将当前系统状态与提交中声明的系统状态进行比较,然后将所需的更改应用于集群的配置。
- Kubernetes 会将应用清单中包含的配置与当前资源进行协调,并进行所需的更改以实现所需的集群状态。
- Argo CD 将持续监控当前状态与受监控存储库中声明的状态的同步状态。
请注意,此工作流程总结遗漏了通常执行持续集成的重要步骤。持续集成流程用于自动构建和测试应用程序代码,以确保在生产部署之前满足要求和标准。除了这个简单的定义之外,我将在另一个时间点对此主题进行更深入的讨论。
让我们继续快速浏览一下构成 Argo CD 架构的三个主要组件。
API 和Web服务器
API 服务器是一个 gRPC/REST 服务器,它公开 Web UI、CLI 和 CI/CD 系统使用的 API。
存储库服务器
存储库服务器是一项内部服务,用于维护保存应用程序清单的 Git 存储库的本地缓存。它负责生成和返回 Kubernetes 清单。
应用控制器
应用控制器是一个 Kubernetes 控制器,它持续监视正在运行的应用程序,并将当前的实时状态与所需的目标状态(如存储库中指定的)进行比较。它检测偏离声明配置的应用程序状态,并可以选择采取纠正措施。它负责为生命周期事件(PreSync、Sync、PostSync)调用任何用户定义的钩子。
Argo CD 支持以下声明格式:
- Helm Charts
- Jsonnet Documents
- Kubernetes Manifests
- Kustomize Templates
我们将在本文中使用标准 Kubernetes Manifests。你将看到 Argo CD 文档将这些源作为“字典”。
现在我们已经了解了 Argo CD 是什么、它提供的价值以及它的构建方式,让我们开始安装它,以便更好地了解它如何用于管理 Kubernetes 工作负载。
本演练的先决条件如下:
- 对 Kubernetes 的集群提升访问权限
- Git 存储库
- kubectl 命令行工具
我们将从安装“argocd”命令行工具开始。执行以下 CLI 命令来完成此操作
curl -L 'https://github.com/argoproj/argo-cd/releases/download/v2.5.8/argocd-linux-amd64' > /usr/local/sbin/argocd chmod 0755 /usr/local/sbin/argocd
我们现在需要创建一个命名空间供 Argo CD 在其中运行。执行以下 CLI 命令来完成此操作。
kubectl create namespace argocd
接下来,我们将下载安装manifests并将其应用到我们的 Kubernetes 集群。
curl -L 'https://raw.githubusercontent.com/argoproj/argo-cd/v2.6.0/manifests/ha/install.yaml' > argocd-ha-install.yaml kubectl apply -n argocd -f argocd-ha-install.yaml
请注意,这是高可用安装类型。如果你的系统资源不足,你可以使用非 HA 版本。只需使用以下一组 CLI 命令即可。
curl -L 'https://raw.githubusercontent.com/argoproj/argo-cd/v2.6.0/manifests/install.yaml' > argocd-install.yaml kubectl apply -n argocd -f argocd-install.yaml
安装过程完成后,你需要获取管理员密码。执行以下 CLI 命令来完成此操作。
kubectl get secrets argocd-initial-admin-secret -n argocd -o json | jq -rM '.data.password' | base64 -d
这是一个高度敏感的信息。将此信息存储在安全的地方。尤其是在生产系统中工作时。
有了这些信息,我们现在可以使用 Web 浏览器连接到 UI。但首先,让我们将内部 Argo CD 服务端口转发到外部地址。执行以下 CLI 命令来完成此操作。
kubectl port-forward svc/argocd-server -n argocd 8443:443 --address='0.0.0.0'
这里需要注意的一个重要警告是,我在我的家庭实验室网络中运行的裸机 Kubernetes 集群中工作,并且不担心有威胁的访问者访问这个开放端口。如果你的集群暴露在互联网上,我强烈建议你采取必要的预防措施。此配置超出了本文章的范围,因此,你将承担保护集群访问的责任。
我运行此命令的服务器的 IP 地址恰好是 192.168.0.161。这让我访问以下 URL 来访问 Argo CD Web 界面:
使用“admin”作为用户名和我们之前检索到的密码登录后,你应该看到类似以下内容:
现在让我们使用 Argo CD 命令行工具登录。执行以下命令来完成此操作:
argocd login 192.168.0.161:8443
同样,192.168.0.161 是我的网络中的 IP 地址。这会和你的不一样。
你可以使用以下 CLI 命令更改管理员密码。如果在生产环境中工作,这样做可能是个好主意。
argocd account update-password
在这里,我们在与Argo CD 和 Kubernetes 集群交互时将主要使用 CLI。让我们继续创建我们的第一个 Argo CD 应用程序。我们将通过执行以下 CLI 命令来完成此操作。
argocd app create foo-app --repo https://github.com/trek10inc/exploring-gitops-with-argo --path part1/app1 --dest-server https://kubernetes.default.svc --dest-namespace default
请注意,此命令使用公共存储库创建应用程序。使用私有存储库创建应用程序超出了本文章的范围。你可以通过以下链接阅读有关如何完成此操作的更多信息:
https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/
此外,还要注意 CLI 命令中提供的“路径”属性。这就是告诉 Argo CD 在哪里寻找 Kubernetes 清单的信息。此属性允许你在单个存储库中存储多个应用程序。
命令执行完成后,我们将使用以下 CLI 命令列出新创建的 Argo CD 应用程序:
argocd app get foo-app
你应该看到类似以下内容:
argocd/foo-app Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://192.168.0.161:8443/applications/foo-app Repo: https://github.com/trek10inc/exploring-gitops-with-argo Target: Path: part1/app1 SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: OutOfSync from (37b85c8) Health Status: Missing GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default foo-svc OutOfSync Missing apps Deployment default foo-app OutOfSync Missing
记下“Service”和“Deployment”资源的“OutOfSync”状态。应用程序状态最初处于“OutOfSync”状态,因为应用程序尚未部署,这意味着尚未创建 Kubernetes 资源。
要同步(部署)应用程序,请执行以下 CLI 命令:
argocd app sync foo-app
使用此命令,Argo CD 将从受监控的存储库检索最新提交,并使用其包含的清单执行“kubectl apply”。
“foo-app”应用程序现在应该正在运行中。你可以查看其资源组件、日志、历史记录和评估的健康状态。
argocd app get foo-app Name: argocd/foo-app Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://192.168.0.161:8443/applications/foo-app Repo: https://github.com/trek10inc/exploring-gitops-with-argo Target: Path: part1/app1 SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: Synced to (37b85c8) Health Status: Healthy GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default foo-svc Synced Healthy service/foo-svc created apps Deployment default foo-app Synced Healthy deployment.apps/foo-app created —------ argocd app logs foo-app waiting 0 Starting application server Web server is running on port 80 waiting 0 Starting application server Web server is running on port 80 waiting 0 Starting application server Web server is running on port 80 —-- argocd app history foo-app ID DATE REVISION 0 2023-02-08 15:15:33 -0700 MST (37b85c8)
请注意,Argo CD 不会自动部署我们应用程序的最新提交版本。我们必须手动将本地系统状态与存储在存储库中的远程声明同步。由于利用 Argo CD 的全部目的是自动化部署过程,因此我们希望启用 Argo CD 所谓的“自动同步策略”。
当 Argo CD 检测到 Git 中所需的清单与集群中的实时状态之间的差异时,它能够自动同步应用程序。
使用以下 CLI 命令启用我们的应用程序的自动同步:
argocd app set foo-app --sync-policy automated
你可以通过以下 URL 了解有关同步策略可以利用的附加功能的更多信息。
https://argocd.readthedocs.io/en/stable/user-guide/auto\_sync/
https://argocd.readthedocs.io/en/stable/user-guide/sync-options/
现在让我们访问我们通过部署“foo-app”应用程序创建的 NodePort 服务上运行的 Web 服务器。我们首先需要找到集群节点的 IP 地址以及“foo-svc”服务正在侦听的端口。
你可以通过以下 CLI 命令获取集群节点的 IP 地址:
kubectl get nodes -o json | jq -rM '.items[].status.addresses[] | select(.type == "InternalIP") | .address' | tee /tmp/nodes.txt
你可以通过以下 CLI 命令获取“foo-svc”服务正在侦听的端口:
kubectl get svc foo-svc -o json | jq -rM '.spec.ports[].nodePort' | tee /tmp/port.txt
有了这些信息,我们将向每个集群节点上的服务的顶端路由发出请求,以验证我们的应用程序是否正常运行。执行以下 CLI 命令来完成此操作。
PORT=$(cat /tmp/port.txt) cat /tmp/nodes.txt | while read IP; do curl http://${IP}:${PORT}; done
你应该看到以下输出:
{ "version": "1.0.0" } { "version": "1.0.0" } { "version": "1.0.0" } { "version": "1.0.0" }
现在,我们将更改存储库中的清单之一,通过对“part1/app1/deployment.yaml”进行轻微编辑来强制更改系统状态。这是通过编辑“CONTENT”环境变量使其读取“1.0.1”然后提交更改来完成的。
name: foo-app env: - name: CONTENT value: '{ "version": "1.0.1" }'
短暂等待后,我们将看到我们的应用程序已自动更新。请注意,默认同步间隔设置为 3 分钟。
使用以下 CLI 命令查看“foo-app”应用程序的运行状况和同步状态。
argocd app get foo-app | grep Status
你应该看到类似以下内容:
Sync Status: Synced to (5c8fe96) Health Status: Healthy
使用以下 CLI 命令查看“foo-app”应用程序的历史记录。
argocd app history foo-app
这应该会产生如下所示的结果。提交 ID 将不同。
ID DATE REVISION 0 2023-02-08 15:15:33 -0700 MST (37b85c8) 1 2023-02-08 15:19:25 -0700 MST (5c8fe96)
我们还可以在 Web UI 中查看“foo-app”应用程序的漂亮的图形展示。请注意健康同步状态、修订号和副本集。
知道应用程序已成功同步后,让我们再次向每个集群节点上的“foo-svc”服务发出请求。我们将重用之前的命令。
PORT=$(cat /tmp/port.txt) cat /tmp/nodes.txt | while read IP; do curl http://${IP}:${PORT}; done
这次我们应该看到以下内容。
{ "version": "1.0.1" } { "version": "1.0.1" } { "version": "1.0.1" } { "version": "1.0.1" }
至此,我们使用称之为 Argo CD 的持续交付工具成功且安全地自动化了应用程序的部署!恭喜!
你可以通过执行以下 CLI 命令来删除 Argo CD 应用程序及其生成的所有资源。
argocd app delete foo-app
Argo CD 是一个强大的持续交付解决方案,其功能远远超出了本文章中强调的功能。如果你觉得这篇文章很有趣并且打算在生产环境中使用 Argo CD,我强烈建议你访问以下链接以了解有关该工具丰富功能集的更多信息。
https://argocd.readthedocs.io/en/stable/
当你这样做时,查看他们的安全文档会对你更有帮助!
https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/security.md
如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。
原文链接: