什么是 Argo CD
Argo CD 是 CNCF 毕业项目,专为 Kubernetes 设计的 GitOps 持续部署(CD) 控制器。它以 Git 仓库中的 manifest(YAML、Kustomize、Helm 等)为唯一期望状态,持续对比集群里的实际资源,并在偏差时执行同步。
与 Tekton、GitHub Actions 等 CI 工具的分工常见如下:
| 阶段 | 典型工具 | 做什么 |
|---|---|---|
| 构建 | Tekton、CI | 编译代码、打镜像、推 registry |
| 部署 | Argo CD | 根据 Git 里的镜像 tag / manifest 更新集群 |
在 homelab 里,配置仓库是 w10n-config:改 homelab/k8s/ 下的 YAML 并 push,由 Argo CD 把变更落到集群;镜像版本往往由 Tekton Pipeline 改 Git 里的 deployment 镜像字段,再交给 Argo 滚动发布。
GitOps 在说什么
传统做法常是 kubectl apply 或 Helm 从本机直接改集群,容易出现「集群里到底是什么版本」与 Git 不一致的问题。
GitOps 的核心约定:
- Git 是事实来源:期望状态只写在版本库里。
- 自动化同步:控制器拉取 Git,diff 后 apply 到集群。
- 可观测、可回滚:每次部署对应一个 commit revision,UI 和 CR 状态里能追溯。
Argo CD 负责第 2、3 步;人(或 CI)只负责把正确内容 merge 进 Git。
核心概念
Application
Application 是 Argo CD 的 CRD,描述「从哪个 Git 路径同步到哪个集群/命名空间」。homelab 中 QuantDinger 的示例(节选):
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: quantdinger
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:wiloon/w10n-config.git
targetRevision: main
path: homelab/k8s/quantdinger
destination:
server: https://kubernetes.default.svc
namespace: quantdinger
syncPolicy:
automated:
prune: true
selfHeal: true
source:Git 仓库、分支、子目录(或 Helm chart 参数)。destination:目标 API Server 与 namespace(单集群时多为 in-cluster 地址)。syncPolicy.automated:开启后,Git 变更或集群被手工改掉时,控制器会自动 Sync。
Sync 与 Health
- Sync:把 Git 中的 manifest 应用到集群(create/update/delete,取决于 diff 与
prune)。 - Health:Deployment、StatefulSet 等资源是否达到就绪等「业务健康」判定。
- Sync 状态:
Synced/OutOfSync表示 Git 与 live 是否一致;注意「显示 Synced」时 revision 仍可能未更新到最新 commit,排障时需对照status.sync.revision。
Project
AppProject 用于 RBAC、允许的仓库/集群/资源白名单。homelab 目前多用 default 项目。
其他常用能力
- Kustomize / Helm / 目录:
source.path指向 Kustomize 目录时,Argo 在仓库内执行kustomize build再 apply。 - ignoreDifferences:某些字段(如 Namespace 自动标签)不在 Git 里,可声明忽略,避免无意义 OutOfSync。
- sync-wave 注解:
argocd.argoproj.io/sync-wave控制资源应用顺序(例如先 Secret/ConfigMap,再 Deployment)。
homelab 中的部署方式
| 项 | 说明 |
|---|---|
| UI | https://argocd.wiloon.com |
| 命名空间 | argocd |
| 配置目录 | w10n-config 仓库 homelab/k8s/argocd/ |
| Application 清单 | 同目录下 application-*.yaml(如 quantdinger、pathfinder、rssx) |
典型工作流:
- 编辑
homelab/k8s/<服务>/下的 manifest(或等 Tekton 更新镜像 tag)。 git push到main。- Argo CD 检测到新 revision,在
automated策略下自动 Sync。 - 在 UI 或
kubectl get application -n argocd查看 Sync/Health。
若需构建镜像再发布,见仓库内 homelab/k8s/tekton/ 与各服务的 README(如 QuantDinger 的 Tekton + Argo CD 升级说明)。
同步策略说明
homelab 里多个 Application 启用了类似配置:
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
| 选项 | 含义 |
|---|---|
automated |
Git 变更后自动同步,无需每次手点 Sync |
prune: true |
Git 中已删除的资源,会从集群中删除 |
selfHeal: true |
有人用 kubectl 改了集群,会被拉回 Git 状态 |
CreateNamespace=true |
目标 namespace 不存在时自动创建 |
因此日常应避免对已由 Argo 管理的资源长期 kubectl apply -k 旁路修改,否则会出现 OutOfSync,或与 selfHeal 互相覆盖。应急手段与正路 Sync 的对比,见 Argo CD CLI 与 kubectl annotate 对比。
常用操作
Web UI
登录后可见应用列表、资源树、diff、同步历史、回滚到历史 revision 等,适合首次熟悉 GitOps 状态。
CLI(可选)
# Arch Linux 示例
yay -S argocd-bin
argocd login argocd.wiloon.com --grpc-web
argocd app list
argocd app get quantdinger
argocd app sync quantdinger
argocd app diff quantdinger
未安装 CLI 时,可用 kubectl annotate 触发 hard refresh,详见上文链接的对比文。
kubectl 查看 Application
kubectl -n argocd get application
kubectl -n argocd get application quantdinger -o yaml
关注 status.sync.status、status.sync.revision、status.health.status。
与 CI 的配合示意
sequenceDiagram participant Dev as 开发者 / CI participant Git as w10n-config participant Tekton as Tekton participant Argo as Argo CD participant K8s as 集群 Dev->>Git: 改 manifest 或触发 Pipeline Tekton->>Git: 更新镜像 tag(可选) Argo->>Git: 轮询 / webhook 拉取 Argo->>K8s: Sync diff apply K8s-->>Argo: Health 回报
小结
- Argo CD 把 Git 里的 K8s manifest 持续对齐到集群,是 homelab GitOps 的 CD 层。
- 日常以 改 Git → push → 自动 Sync 为主;
prune+selfHeal要求集群服从仓库。 - UI、CLI、
kubectl查看 Application 各有用途;深度排障与 refresh/sync 区别见 Argo CD CLI 与 kubectl annotate 对比。
官方文档:Argo CD Documentation。
Helm 直接安装 vs ArgoCD 管理
在 K8s 集群里部署一个服务(如 Loki)有两种常见方式:
方式一:Helm chart 直接安装
从本机命令行直接调用 helm install:
helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki -n loki -f loki-values.yaml
- 状态存在于 Helm release(K8s Secret 内)和运行的 Pod。
- 只要
values.yaml没有纣入版本控制,就属于“本地手动操作”,难以追溯、不易回滚。 - 升级:
helm upgrade loki grafana/loki -f loki-values.yaml。 - 适合快速验证和一次性部署。
方式二:ArgoCD Application(GitOps 管理)
将 Helm values 文件纳入 Git 仓库,由 ArgoCD 将其持续同步到集群。
两种写法都可行:
a. Application 直接引用 Helm chart:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: loki
namespace: argocd
spec:
source:
repoURL: https://grafana.github.io/helm-charts
chart: loki
targetRevision: "6.x.x"
helm:
valueFiles:
- values.yaml
destination:
namespace: loki
b. Application 引用 Git 目录(目录内有 Helm Chart.yaml + values.yaml):
spec:
source:
repoURL: git@github.com:wiloon/w10n-config.git
path: infra/homelab/k8s/observability/loki
targetRevision: main
helm:
valueFiles:
- loki-values.yaml
对比
| 项 | helm install 直接装 |
ArgoCD Application 管理 |
|---|---|---|
| 配置存在于 | 本地 values.yaml(可能没进 Git) |
Git 仓库(带 commit 历史) |
| 回滚 | helm rollback(仅限 Helm release 层) |
argocd app rollback(回到任意 Git commit) |
| 异常情况自愈(selfHeal) | 无 | 有(手动 kubectl 改了会被拉回) |
| 可观测性 | 只看 Helm release | ArgoCD UI 展示资源树、diff、健康状态 |
| 操作复杂度 | 低(一条命令) | 需要维护 Application CR |
| 适合场景 | 快速验证、一次性部署 | 长期运维的生产服务 |
homelab 建议
- 如果集群内其他服务(kube-prometheus-stack、rssx 等)已经由 ArgoCD 管理,Loki 保持一致也用 ArgoCD,第一次调试时稍快一些但后期维护更整齐。
- 如果只是这次临时解决问题、不想引入 GitOps 复杂度,
helm install直接装也完全可行。
ArgoCD + Helm chart vs ArgoCD → git path(manifest / kustomize)
同样由 ArgoCD 管理,source 的写法决定了背后截然不同的工作模式。
ArgoCD + Helm chart
source 指向一个 Helm chart(来自 Helm repo 或 OCI registry),并通过 helm.values / helm.valueFiles 覆盖参数:
spec:
source:
repoURL: https://grafana.github.io/helm-charts
chart: loki
targetRevision: "6.x.x"
helm:
values: |
loki:
commonConfig:
replication_factor: 1
- ArgoCD 在每次同步时执行
helm template,将渲染结果 apply 到集群;不会在集群内留下 Helm release,也不依赖helm命令行工具。 - 升级 chart 版本只需改
targetRevision。 - 适合部署第三方 chart(Prometheus、Loki、Cert-manager 等),无需维护 YAML 细节。
ArgoCD → git path(manifest / kustomize)
source 指向 Git 仓库中的一个目录,Argo 检测目录内容来决定渲染引擎:
- 目录内有
kustomization.yaml→ Kustomize 模式,ArgoCD 执行kustomize build。 - 目录内只有普通
.yaml→ Directory 模式,直接 apply 所有 manifest。
spec:
source:
repoURL: git@github.com:wiloon/w10n-config.git
path: homelab/k8s/quantdinger
targetRevision: main
所有 YAML 完全由自己维护,集群里运行的资源就是 Git 里写的资源,没有任何模板层的隐式行为。
对比
| 维度 | Helm chart | git path(manifest / kustomize) |
|---|---|---|
| 配置粒度 | chart 暴露什么参数就能改什么,其余固定在模板里 | 全部 YAML 自己控制,想改什么都能改 |
| 透明度 | 渲染结果在 ArgoCD UI 的 “Live Manifest” 里可见,但源码在上游 chart 里 | Git 里即是最终 YAML,所见即所得 |
| 升级方式 | 改 targetRevision(chart 版本) |
改 Git 里的 manifest(镜像 tag、字段等) |
| 适合的对象 | 第三方应用(自己不维护 chart 细节) | 自研服务或需要深度定制的应用 |
| Kustomize 叠加能力 | 可配合 patches 但较少见 |
天然适合用 base + overlay 管理多环境差异 |
| 排障难度 | 需了解上游 chart 结构,helm template 辅助排查 |
直接读 YAML,出错点一目了然 |
| 版本追踪 | Git 里追踪 targetRevision(chart 版本号) |
Git commit 即版本,git log 看所有变更历史 |
选型建议
- 第三方基础设施组件(Prometheus、Loki、Cert-manager、Ingress-nginx 等):用 Helm chart,跟随上游发版节奏,values 文件纳入 Git。
- 自研服务(QuantDinger、Pathfinder、rssx 等):用 git path,直接维护 Deployment/Service/ConfigMap,改什么一目了然。
- 多环境差异(dev/staging/prod 不同副本数、不同镜像 tag):git path + Kustomize 的 base/overlay 结构最直观,避免 Helm values 多层继承带来的认知负担。
接管已有 helm install 资源(迁移到 ArgoCD)
集群里已有 helm install 安装的服务,想改用 ArgoCD 管理,有一个常见陷阱:
⚠️ 不要
helm uninstall再重装。对于有持久化数据的服务(如 Longhorn、Prometheus),helm uninstall会触发资源级联删除,包括 PVC——数据会丢失。
正确方式是直接让 ArgoCD sync 覆盖 helm 的 ownership,无需先卸载。
为什么这样可行
helm install 的本质是在 K8s 资源上打了一组 annotation 和 label(helm.sh/chart、app.kubernetes.io/managed-by: Helm 等)并在 helm-system 或对应 namespace 存了一个 release Secret。这些只是元数据,ArgoCD 用 Server-Side Apply (SSA) sync 时会以自己为 field-manager 直接覆盖这些字段,而不会删除底层资源。
关键配置
syncPolicy:
syncOptions:
- ServerSideApply=true # SSA 模式,字段级覆盖,不删除资源
spec:
sources:
- repoURL: https://charts.longhorn.io
chart: longhorn
targetRevision: "1.10.0"
helm:
releaseName: longhorn # 必须与原 helm install 的 release name 一致
releaseName 与原 release 一致,ArgoCD 渲染出的资源 name 才能对上集群里的现有资源,SSA 才会是 update 而不是 create。
迁移步骤概要
- 提取现有 values:
helm get values <release> -n <namespace>,存入 Git。 - 写 ArgoCD Application YAML,
releaseName与原 release 一致,ServerSideApply=true,先设prune: false。 kubectl apply创建 Application,ArgoCD 开始首次 sync。- 观察 sync 结果:看 ArgoCD UI diff,确认是 update 而非 recreate。
- 验证服务正常后,将
prune: false改为prune: true并 push。
回滚
如果 sync 出现问题,不想继续让 ArgoCD 管理,可以只删 Application CR,保留底层资源:
kubectl delete application -n argocd <name> --cascade=orphan
--cascade=orphan 使 K8s 只删除 Application 对象本身,不级联删除它管理的 Longhorn/Prometheus 等资源,回到手动管理状态。