7.0 KiB
Argo CD GitOps 轨道
改 GitOps 仓库里的 Application / 清单 → 开 PR/MR → 用户合并 → Argo CD 同步到集群。
Agent 不直接 kubectl apply 工作负载,也不合并 MR。
Compose 的 _config.yaml / sync.py / remote.py 不用于本轨道。
项目配置
argocd.yaml 只做指针:GitOps 仓库的 Git 地址,以及可选的本地目录。Application 名、镜像、namespace、域名、Secret 名的权威在 GitOps 清单里,不要再抄一份。
不要嵌进 _config.yaml(脚本解析器不支持嵌套映射)。
两种接法(人类说明见 skill README.md):
# 1)只写地址:部署时浅 clone 到临时目录,开完 MR 删掉
repo: git@git.example.com:org/infra-gitops.git
# 2)已有 checkout:不 clone,直接在目录里改
# repo: git@git.example.com:org/infra-gitops.git # 可选;缺省用该目录 origin
repo_dir: ../infra-gitops # 相对路径相对项目根
# path: argocd/applications/other-name # 仅当目录不是 argocd/applications/<源项目名>
| 字段 | 必填 | 说明 |
|---|---|---|
repo |
与 repo_dir 至少一个 |
Git 远程地址(git@host:group/name.git 或 https://...) |
repo_dir |
与 repo 至少一个 |
本地 checkout;相对项目根或绝对路径 |
path |
否 | 默认 argocd/applications/<源项目 git 仓库名> |
repo 写成本地路径(../、/、~/)时,当作 repo_dir(旧写法兼容)。
有 repo_dir 且目录是 git 仓库 → 不 clone,在里面改。repo 同时存在且与 origin 指向不同仓库时停下问用户。
只有 repo 地址 → git clone --depth 1 到 mktemp -d;开完 MR(或确认失败)后删掉临时目录。不要 clone 进源项目。
无此文件:只问 Git 地址,写成 repo: 再动手。
其余一律推导,不要写进这个文件:
| 需要的信息 | 从哪来 |
|---|---|
| 推送 remote | repo 地址,或 git -C <repo_dir> remote get-url origin |
| Application 名 | path 末级,或 application.yaml 的 metadata.name |
| 镜像(无 tag) | 清单里的 image:;首次无清单则项目 Makefile / .env 的 registry + name |
| 升 tag 改哪个文件 | 在 path 下搜该镜像 |
| namespace / host / imagePullSecret / TLS Secret | application.yaml 与 Ingress/Deployment |
默认 path 不存在:再按 metadata.name == 源项目名 搜;还没有则走「新增」,不要把 namespace/host 写回 argocd.yaml。
摸底
- 读
argocd.yaml,按上一节得到工作副本(浅 clone 或repo_dir)。repo_dir先git fetch;工作区有无关改动则git worktree add隔离。 - 打开
path/:有application.yaml视为已接入;只有惯例目录、没有本应用则走「新增」。 - 清单写法跟目标 GitOps 仓库已有应用走,不要另起一套:
- 自建镜像:
application.yaml+manifests/(Deployment/Service/Ingress) - 上游 Helm:
sources[]里 chart + 本仓库values.yaml
- 自建镜像:
- 从兄弟应用抄:
spec.project、destination.server、syncPolicy、IngressClass、TLS 引用方式。 - 仓库 README 写明「无 app-of-apps / 需逐个创建 Application」时,合入 main 不会自动注册新 Application。
新增 Application
向用户确认清单里写不出的项:namespace、对外 host(或仅 ClusterIP)、是否要 imagePullSecrets、TLS Secret 名、镜像 tag。
然后在工作副本里:
- 从最新默认分支拉出
feat/<application>(浅 clone 已在默认分支;repo_dir从origin/<default>拉)。 - 建
path/application.yaml+ 清单(或 values),字段对齐兄弟应用。 - 镜像用固定 tag,不用
:latest。 - Secret、dockerconfigjson、口令 不入库;Deployment 只引用 Secret 名。
升级 / 改清单
已有 Application 时:
- 在
path下搜到的镜像行,把image: <name>:<old>改成新 tag。 - 只改本次要求的清单;不要顺手改无关 values。
- tag 必须已经推进镜像仓库(本轨道不负责
docker push,那是 builder)。
提交 MR
- 分支从最新
origin/<default>拉出,名称如feat/<application>或chore/<application>-<tag>。 - 只提交 GitOps 仓库内本次文件。
git push -u到origin;不--force、不硬 reset。- 按 remote 选 CLI:GitLab
glab mr create、GitHubgh pr create、Gitea/Forgejotea pulls create。 创建前读该子命令--help;指定 title、body、base、head。 - CLI 对项目 404(token 看不到仓库)而 SSH push 已成功:把
git push打印的「create merge request」网页链接交给用户,不要读 token 配置、不要改用 curl 带 token。 - 停在 MR。不合并、不替用户点 Sync。浅 clone 的临时目录在得到 MR 链接(或确认失败)后删除。
MR 正文写清:改了什么、镜像引用、合入后用户还要做的事(首次 apply Application、拷 Secret、验 healthz/域名)。
合入后交给用户
无 app-of-apps 时,第一次注册 Application(之后改 manifests 合入即可):
kubectl apply -f <path>/application.yaml
TLS / 拉镜像 Secret 必须已在工作负载所在 ns 存在。没有则从已有 ns 拷贝(见下),不要新建一份写进 Git。
Secret(ns 级,不入库)
imagePullSecrets 与 Ingress tls.secretName 都只在 Pod/Ingress 所在 namespace 生效。
不是集群每个 ns 都要建,只给实际跑这个负载的 ns 准备。
列出已有拉镜像 Secret(名字以 Deployment 的 imagePullSecrets 为准):
kubectl get secret <secret> -A
拷到目标 ns(类型须为 kubernetes.io/dockerconfigjson):
kubectl get secret <secret> -n SOURCE -o json \
| jq 'del(
.metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp,
.metadata.selfLink, .metadata.ownerReferences, .metadata.managedFields,
.metadata.annotations, .status
) | .metadata.namespace = "DEST"' \
| kubectl apply -f -
没有 jq:
kubectl get secret <secret> -n SOURCE \
-o jsonpath='{.data.\.dockerconfigjson}' | base64 -d > /tmp/dockerconfig.json
kubectl -n DEST create secret generic <secret> \
--type=kubernetes.io/dockerconfigjson \
--from-file=.dockerconfigjson=/tmp/dockerconfig.json
rm /tmp/dockerconfig.json
本环境没有 kubeconfig 时,把命令交给用户执行,不要假装已经建好。
验证
- MR URL 可打开,head 含本次清单,base 为约定默认分支
- 用户合并后:Argo CD 中该 Application Synced(automated 关闭时用户需手动 Sync)
- 升级:集群里容器镜像 tag 与清单一致
- 有 Ingress:curl 域名 healthz / 业务路径;HTTPS 失败先查 TLS Secret 是否在该 ns
不要做
- 把 Compose 的 rsync/
remote.py套到集群 - 常规发布用
kubectl apply工作负载绕过 GitOps - 提交 Harbor 密码、
dockerconfigjson、TLS 私钥 - 在未获「合并」授权时
glab mr merge/gh pr merge