我如何在 Kubernetes 上配置 ArgoCD 进行 GitOps:没人告诉你的事
Source: Dev.to
(请提供需要翻译的正文内容,我将为您翻译成简体中文。)
一个星期五的下午,约14个月前…
Desplegué la versión incorrecta de nuestro servicio de pagos en producción. No fue un error de código — fue un error de proceso. Corrí:
kubectl apply -f .
desde mi laptop con cambios locales sin commitear, y durante 23 minutos el sistema respondió con errores 500. Cuatro personas en el equipo, silencio total en Slack, y yo mirando los logs sin saber exactamente qué había pasado.
教训
Esa semana empecé a investigar GitOps de verdad. Revisé las dos opciones principales:
| 工具 | 理念 | 优势 |
|---|---|---|
| Flux v2 | “Kubernetes 原生”:全部是 CRD 和小型控制器。如果你喜欢组合组件,这很理想。 | 非常轻量,易于与流水线集成。 |
| Argo CD | 开箱即用的 UI 相当好,Application 模型更直观,社区文档更多。 | UI 友好,适合需要在不使用终端的情况下获取可视化的 小团队。 |
对于像我这样的一个小团队,UI 是决定因素。并不是因为它不可或缺,而是当不常使用终端的成员需要了解部署状态时,他们可以打开浏览器,而不是让我去运行 kubectl。这价值很大。
(这篇文章还有一个版本,我最终选择了 Flux。这很大程度上取决于你的团队是否已经熟悉每种工具的运维模型。)
Argo CD 快速安装(典型示例)
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
是的,能工作。 但是在我的环境(AWS 上的 EKS,已安装 ALB Controller)中,我遇到了一些如果事先知道就好了的问题。
我遇到的问题
-
网络限制 – 在出站受限的集群中,
argocd-serverPod 无法在集群内部执行git clone。日志信息不明确;解决办法是在 security groups 中创建明确的出站规则。 -
清单版本 –
stable分支并不总是指向你期望的版本。我以为是最新的,实际上安装了 Argo CD 2.9.3。请始终检查正在运行的镜像:kubectl get pods -n argocd -o jsonpath='{range .items[*]}{.spec.containers[0].image}{"\n"}{end}'
使用 Helm 安装(推荐用于生产环境)
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--version 6.7.3 \
--set server.service.type=ClusterIP \
--set configs.params."server\.insecure"=true
我使用 server.insecure=true 标志是因为 TLS 终止在 ALB 上,而不是直接在 Argo CD 上。如果你的部署不同,可能不需要它。
初始访问
# 获取 admin 的初始密码
kubectl get secret argocd-initial-admin-secret \
-n argocd \
-o jsonpath="{.data.password}" | base64 -d
# Port‑forward 以本地访问
kubectl port-forward svc/argocd-server -n argocd 8080:443
有趣的事实: 初始密码存放在 Secret
argocd-initial-admin-secret中,Argo CD 在你首次更改后会自动删除它。设计得很好,但当我几周后去查找时已经找不到了,让我措手不及。
Source: …
在 Argo CD 中使用 GitOps 的入门指南
思路:你有一个存放 Kubernetes 清单(或 Helm Chart、或 Kustomize)的仓库,Argo CD 监视该仓库并将集群状态与之同步。
1. 注册仓库
# 使用 SSH(我的首选)
argocd repo add git@github.com:tu-org/tu-repo-k8s.git \
--ssh-private-key-path ~/.ssh/id_rsa
# 或使用 HTTPS 加 GitHub Token
argocd repo add https://github.com/tu-org/tu-repo-k8s.git \
--username tu-usuario \
--password ghp_tu_token_aqui
2. 创建第一个 Application
可以通过 UI 创建,也可以使用 YAML 清单——我更喜欢 YAML,因为它保存在 Git 中(真正的 GitOps)。
# argocd/apps/mi-servicio.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mi-servicio
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/tu-org/tu-repo-k8s.git
targetRevision: main
path: manifests/mi-servicio
destination:
server: https://kubernetes.default.svc
namespace: mi-servicio
syncPolicy:
automated:
prune: true # 删除已不在 Git 中的资源
selfHeal: true # 自动恢复集群中手动修改的内容
syncOptions:
- CreateNamespace=true
selfHeal: true让 GitOps 成为 真正的 GitOps。如果有人(比如我,晚上 11 点“只想快速试一下”)直接在集群里执行kubectl edit,Argo CD 会检测到并自动回滚。刚开始可能会觉得烦,但之后会非常感激。prune: true也值得注意。开启此选项后,如果你从仓库中删除了某个清单,Argo CD 会同步删除集群中对应的资源。若不启用,孤立的资源会悄悄堆积。我就是因为没有这个选项,导致旧版本的Service仍然漂在集群里,毫无用处。
学到的教训(有点尴尬)
我配置了 Argo CD,启用了 自动同步 并设置 prune: true。它在几周内运行得非常顺利。随后,在一次重构中,我 移动了多个目录下的清单文件(重新组织了仓库的文件夹结构)。
Argo CD 检测到旧路径下的资源在 Git 中已不存在。由于 prune: true,它们被删除了。
建议: 在移动或重命名目录之前,考虑创建一个 暂停期(
sync: off)或使用新路径更新Application并手动执行sync。否则,如果迁移过程没有很好地协调,你可能会丢失关键资源。
快速概览
- 选择最适合你团队的工具(Flux vs. Argo CD)。
- 使用 Helm 安装,以获得更好的控制和升级便利。
- 配置出站(egress),并在网络受限的环境中工作时检查清单版本。
- 注册你的仓库(SSH 或 HTTPS)。
- 在 YAML 中定义
Application,并将其存储在 Git 中。 - 启用
selfHeal和prune,使集群始终反映期望状态。 - 在重新组织仓库结构时要小心;使用暂停或手动同步,以避免意外删除。
通过这些步骤,你的集群将保持与真相源对齐,避免因意外手动部署而导致的可怕“500 错误”。 🚀
使用 ArgoCD 进行目录迁移的经验教训
初始问题
新路径下的资源尚未同步。在 四分钟 内,多个 Deployments 处于 零副本 状态。
- 问题 不 在于 ArgoCD —— 行为完全符合文档说明。
- 问题在于没有考虑目录结构迁移的 操作顺序。
应该怎么做
- 在 PR 之前 禁用自动同步。
- 合并 目录重组的更改。
- 手动同步 并检查一切是否正常。
- 重新启用自动同步。
Tip: 如果你要对清单仓库进行结构性更改,请把该 PR 当作 数据库迁移 来处理:要小心,制定回滚计划,最好不要在 星期二晚上 进行。
同步窗口
Desde entonces uso syncWindows para limitar cuándo ArgoCD puede sincronizar automáticamente en producción.
# Configurado en el Project de ArgoCD, no en la Application
spec:
syncWindows:
- kind: allow
schedule: '0 9-17 * * 1-5' # Solo horario laboral, lunes a viernes
duration: 8h
applications:
- 'produccion-*'
namespaces:
- produccion
这并不适用于所有人。如果你经常在非工作时间进行部署,这会成为障碍。但对我们的团队来说,消除凌晨 3 am 的意外 syncs 同步值得额外的配置。
外部集群注册
我们有三个集群:开发、预发布和生产。
ArgoCD 只在一个集群——生产环境中运行,访问权限非常受限——并管理这三个集群。
# Asegúrate de tener el contexto correcto en tu kubeconfig
kubectl config get-contexts
# Registra el clúster de staging
argocd cluster add arn:aws:eks:us-east-1:123456789:cluster/staging \
--name staging
文档没有足够强调的一点是:ArgoCD 在远程集群中创建的 ServiceAccount 默认拥有 cluster‑admin 权限。起初这样没问题,但在生产环境中你会想要进行调整。我直到有人在安全团队明确询问我才去做——最好在被问之前就了解清楚。
环境间的 secret 管理
有件事我还没有完全解决:环境之间的 secret 管理。
- 我们使用 AWS Secrets Manager 与 External Secrets Operator。
- 与 ArgoCD 的集成有时会在 external secret 加载缓慢时产生混乱的 sync states。
这并不完全是一个 bug —— 更像是 时序(timing)问题以及 ArgoCD 如何评估资源的 health。我并不 100 % 确定我们目前的方案在超过现在的 12 个服务 后是否还能良好扩展。如果有人有优雅的解决方案,我真的很想了解。
经验教训(超过一年在生产环境)
-
先不要开启自动同步。
- 两周手动同步的操作会让你学到比任何教程都多:你会了解
prune的作用,如何阅读 ArgoCD 在应用前显示的 diff,以及为什么selfHeal最终会救你一命。 - 只有在你信任自己的清单文件以及 PR 审核流程时,才开启自动同步。
- 两周手动同步的操作会让你学到比任何教程都多:你会了解
-
如果有三四个以上结构相似的 Applications,请使用 ApplicationSets。
- 这样可以避免重复,且全局配置的更改更易于管理。
-
从一开始就投入时间进行访问控制 — 而不是事后再做。
- ArgoCD 使用基于项目的 RBAC,配合 Casbin 策略:灵活,但当已有十多人在使用系统时,要在调整权限的同时不破坏任何东西,重新利用会变得相当困难。
ArgoCD 与 Flux
| 特性 | ArgoCD | Flux |
|---|---|---|
| 适用于日常操作的友好 UI | ✅ | ❌ |
| 通过终端操作,小型控制器 | ❌ | ✅ |
| 纯声明式方法 | ✅ | ✅ |
| 学习曲线 | 中等 | 中等‑高 |
没有通用的答案,但针对你的特定情境有正确的答案。
对我的团队的结论
对于我们的团队,ArgoCD 是正确的决定。
- 在支付服务事故的下一个星期五,我们进行了一次部署,耗时恰好等同于 PR 合并的时间。
- 没有人运行本地命令。
- 没有人需要相信某人已经检出正确的分支。
- 部署历史记录保存在 Git 中,包含作者姓名和提交信息。
这点,比任何具体特性更能说明 GitOps 值得最初的投入。