我如何在 Kubernetes 上配置 ArgoCD 进行 GitOps:没人告诉你的事

发布: (2026年3月8日 GMT+8 13:23)
13 分钟阅读
原文: Dev.to

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)中,我遇到了一些如果事先知道就好了的问题。

我遇到的问题

  1. 网络限制 – 在出站受限的集群中,argocd-server Pod 无法在集群内部执行 git clone。日志信息不明确;解决办法是在 security groups 中创建明确的出站规则。

  2. 清单版本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。否则,如果迁移过程没有很好地协调,你可能会丢失关键资源。

快速概览

  1. 选择最适合你团队的工具(Flux vs. Argo CD)。
  2. 使用 Helm 安装,以获得更好的控制和升级便利。
  3. 配置出站(egress),并在网络受限的环境中工作时检查清单版本。
  4. 注册你的仓库(SSH 或 HTTPS)。
  5. 在 YAML 中定义 Application,并将其存储在 Git 中。
  6. 启用 selfHealprune,使集群始终反映期望状态。
  7. 在重新组织仓库结构时要小心;使用暂停或手动同步,以避免意外删除。

通过这些步骤,你的集群将保持与真相源对齐,避免因意外手动部署而导致的可怕“500 错误”。 🚀

使用 ArgoCD 进行目录迁移的经验教训

初始问题

新路径下的资源尚未同步。在 四分钟 内,多个 Deployments 处于 零副本 状态。

  • 问题 在于 ArgoCD —— 行为完全符合文档说明。
  • 问题在于没有考虑目录结构迁移的 操作顺序

应该怎么做

  1. 在 PR 之前 禁用自动同步
  2. 合并 目录重组的更改。
  3. 手动同步 并检查一切是否正常。
  4. 重新启用自动同步

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 ManagerExternal Secrets Operator
  • 与 ArgoCD 的集成有时会在 external secret 加载缓慢时产生混乱的 sync states

这并不完全是一个 bug —— 更像是 时序(timing)问题以及 ArgoCD 如何评估资源的 health。我并不 100 % 确定我们目前的方案在超过现在的 12 个服务 后是否还能良好扩展。如果有人有优雅的解决方案,我真的很想了解。

经验教训(超过一年在生产环境)

  1. 先不要开启自动同步。

    • 两周手动同步的操作会让你学到比任何教程都多:你会了解 prune 的作用,如何阅读 ArgoCD 在应用前显示的 diff,以及为什么 selfHeal 最终会救你一命。
    • 只有在你信任自己的清单文件以及 PR 审核流程时,才开启自动同步。
  2. 如果有三四个以上结构相似的 Applications,请使用 ApplicationSets。

    • 这样可以避免重复,且全局配置的更改更易于管理。
  3. 从一开始就投入时间进行访问控制 — 而不是事后再做。

    • ArgoCD 使用基于项目的 RBAC,配合 Casbin 策略:灵活,但当已有十多人在使用系统时,要在调整权限的同时不破坏任何东西,重新利用会变得相当困难。

ArgoCD 与 Flux

特性ArgoCDFlux
适用于日常操作的友好 UI
通过终端操作,小型控制器
纯声明式方法
学习曲线中等中等‑高

没有通用的答案,但针对你的特定情境有正确的答案。

对我的团队的结论

对于我们的团队,ArgoCD 是正确的决定。

  • 在支付服务事故的下一个星期五,我们进行了一次部署,耗时恰好等同于 PR 合并的时间。
  • 没有人运行本地命令。
  • 没有人需要相信某人已经检出正确的分支。
  • 部署历史记录保存在 Git 中,包含作者姓名和提交信息。

这点,比任何具体特性更能说明 GitOps 值得最初的投入。

0 浏览
Back to Blog

相关文章

阅读更多 »