LabHub
学习 学习路径 课程

GitOps 与 Argo CD

亲手写 Application 与 AppProject

在 LabHub 中继续学习

目标

亲自编写 ArgoCD 的 ApplicationAppProject,用声明表达“从哪里读取什么,以什么顺序和策略应用到何处”。

为什么重要

把部署建模为对象而非脚本,会带来三项能力:可向集群查询“当前正在接收什么部署”;自动获得 RBAC 和审计日志;还能将声明本身提交回 git。本实验填写的每个字段都对应真实事故:prune 能把一次仓库路径拼写错误变成大规模删除;没有 retry.backoff 时,失败同步会以固定间隔持续冲击 API 服务器;没有 ignoreDifferences 时,HPA 与 ArgoCD 会反复争夺 replicas。但本环境并未运行 ArgoCD 控制器。你可以注册 CRD 并创建自定义资源,但它们不会自行变为 Synced/Healthy。因此评分检查的是声明是否准确;真实控制器会如何执行这些声明,已在前面的阅读材料和最后一个模块中说明。

步骤

  1. /opt/crds/ 下的离线 CRD 包中查找包含 ArgoCD CRD 的文件(grep -l applications.argoproj.io /opt/crds/*.yaml),用 kubectl apply -f 应用。必须创建 applications.argoproj.ioappprojects.argoproj.io 两个 CRD,且 Established 条件为 True;还须存在命名空间 argocd。将已注册类型列表保存到 /root/gitops/app/out/crds.txt(必须包含字符串 applications)。
  2. argocd 命名空间创建 kind: Applicationmetadata.name: web 的对象。spec.source.repoURLfile:///root/gitops/repospec.source.pathapps/webspec.source.targetRevisionmainspec.destination.serverhttps://kubernetes.default.svcspec.destination.namespacegitops-labspec.projectplatform
  3. web 添加 spec.syncPolicy.automated,设置 prune: trueselfHeal: true。在 /root/gitops/app/out/prune-note.txt 中用两三行中文说明启用 prune 的风险:一个指向错误路径的提交可能导致大规模删除
  4. webspec.syncPolicy.syncOptions 中加入 CreateNamespace=trueServerSideApply=true;在 spec.syncPolicy.retry 中设置 limit: 3backoff.duration: 10sbackoff.factor: 2backoff.maxDuration: 5m
  5. 若仓库 /root/gitops/repo 尚不存在,先创建它:将 /opt/lab/fixtures/gitops/seed/ 中的 deployment.yamlservice.yaml 复制到 /root/gitops/repo/apps/web/,执行 git init 后提交。随后为 /root/gitops/repo/apps/web/ 中的 service.yaml 添加 argocd.argoproj.io/sync-wave: "-1" 注解,为 deployment.yaml 添加 argocd.argoproj.io/sync-wave: "0"值必须是用双引号包裹的字符串。在 /root/gitops/app/out/wave-note.txt 中说明,同一 wave 内按资源种类(kind)的默认顺序应用。
  6. /root/gitops/repo/apps/web/presync-job.yaml 创建 kind: Job 的钩子资源。添加注解 argocd.argoproj.io/hook: PreSyncargocd.argoproj.io/hook-delete-policy: BeforeHookCreation;容器名为 migratespec.backoffLimit1,Pod 的 restartPolicyNever。该目录中带钩子注解的文件必须只有这一个
  7. argocd 命名空间创建 kind: AppProjectmetadata.name: platformspec.sourceRepos 只能包含 file:///root/gitops/repo(禁止 *);spec.destinations[0] 包含 server https://kubernetes.default.svc 和 namespace gitops-lab(禁止 *);spec.clusterResourceWhitelist 包含 group "" / kind Namespacespec.namespaceResourceBlacklist 包含 group "" / kind ResourceQuota 与 group "" / kind LimitRange。Application webspec.project 必须为 platform
  8. web 添加 spec.ignoreDifferences:group apps、kind DeploymentjsonPointers 中包含 /spec/replicas(由 HPA 所有)。将 spec.revisionHistoryLimit 设为 5。最后创建 /root/gitops/app/out/gitops-report.jsonapplications 是包含 argocd 命名空间全部 Application、形式为 {"name": "..."} 的数组;project"platform"self_healtrue

参考

注册 ArgoCD API 类型

/opt/crds/ 下的离线 CRD 包中查找包含 ArgoCD CRD 的文件(grep -l applications.argoproj.io /opt/crds/*.yaml),用 kubectl apply -f 应用。必须创建 applications.argoproj.ioappprojects.argoproj.io 两个 CRD,且 Established 条件为 True;还须存在命名空间 argocd。将已注册类型列表保存到 /root/gitops/app/out/crds.txt(必须包含字符串 applications)。

由于没有互联网,请使用离线 CRD 包。不要死记文件名,而应按内容搜索——可用 grep 查找哪个文件包含 applications.argoproj.io

定义 Application 的源与目标

argocd 命名空间创建 kind: Applicationmetadata.name: web 的对象。spec.source.repoURLfile:///root/gitops/repospec.source.pathapps/webspec.source.targetRevisionmainspec.destination.serverhttps://kubernetes.default.svcspec.destination.namespacegitops-labspec.projectplatform

Application 对象自身所在位置与部署目标命名空间不同。source 必须同时说明从哪里、读取哪里以及使用哪个修订版本。

启用自动同步、清理与自愈

web 添加 spec.syncPolicy.automated,设置 prune: trueselfHeal: true。在 /root/gitops/app/out/prune-note.txt 中用两三行中文说明启用 prune 的风险:一个指向错误路径的提交可能导致大规模删除

automated 下两个开关承担不同职责:一个处理从仓库删除的资源,另一个纠正集群中的漂移。还必须写明其中危险的一项是什么。

添加同步选项与重试退避

webspec.syncPolicy.syncOptions 中加入 CreateNamespace=trueServerSideApply=true;在 spec.syncPolicy.retry 中设置 limit: 3backoff.duration: 10sbackoff.factor: 2backoff.maxDuration: 5m

syncOptions 是 키=값 字符串数组。重试不能只有次数,还需要三个让间隔逐渐拉长的值。

用 sync wave 创建部署顺序

若仓库 /root/gitops/repo 尚不存在,先创建它:将 /opt/lab/fixtures/gitops/seed/ 中的 deployment.yamlservice.yaml 复制到 /root/gitops/repo/apps/web/,执行 git init 后提交。随后为 /root/gitops/repo/apps/web/ 中的 service.yaml 添加 argocd.argoproj.io/sync-wave: "-1" 注解,为 deployment.yaml 添加 argocd.argoproj.io/sync-wave: "0"值必须是用双引号包裹的字符串。在 /root/gitops/app/out/wave-note.txt 中说明,同一 wave 内按资源种类(kind)的默认顺序应用。

wave 值是注解,必须写成用双引号包裹的字符串,而非数字。应先创建的资源使用更小的值,必要时可用负数。要体现顺序,至少需要两个文件。

编写 PreSync 钩子 Job

/root/gitops/repo/apps/web/presync-job.yaml 创建 kind: Job 的钩子资源。添加注解 argocd.argoproj.io/hook: PreSyncargocd.argoproj.io/hook-delete-policy: BeforeHookCreation;容器名为 migratespec.backoffLimit1,Pod 的 restartPolicyNever。该目录中带钩子注解的文件必须只有这一个

钩子本质上是普通 Job。需要两个注解:一个决定所处阶段,一个决定何时清理。遗漏清理策略会使钩子资源不断累积。

用 AppProject 划定边界

argocd 命名空间创建 kind: AppProjectmetadata.name: platformspec.sourceRepos 只能包含 file:///root/gitops/repo(禁止 *);spec.destinations[0] 包含 server https://kubernetes.default.svc 和 namespace gitops-lab(禁止 *);spec.clusterResourceWhitelist 包含 group "" / kind Namespacespec.namespaceResourceBlacklist 包含 group "" / kind ResourceQuota 与 group "" / kind LimitRange。Application webspec.project 必须为 platform

白名单表示“只允许列出的内容”,黑名单表示“只禁止列出的内容”。仓库和命名空间若使用 *,项目隔离就失去意义。也不要忘记把应用归入该项目。

指定忽略字段并创建配置报告

web 添加 spec.ignoreDifferences:group apps、kind DeploymentjsonPointers 中包含 /spec/replicas(由 HPA 所有)。将 spec.revisionHistoryLimit 设为 5。最后创建 /root/gitops/app/out/gitops-report.jsonapplications 是包含 argocd 命名空间全部 Application、形式为 {"name": "..."} 的数组;project"platform"self_healtrue

若连其他控制器所有的字段也强行回滚,就会形成无限同步。报告中的应用数量不要手工统计,而应查询集群生成,才能始终与实际一致。