Files
.pouch/skills/deployer/references/argocd.md
T

151 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`):
```yaml
# 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`
## 摸底
1.`argocd.yaml`,按上一节得到工作副本(浅 clone 或 `repo_dir`)。`repo_dir``git fetch`;工作区有无关改动则 `git worktree add` 隔离。
2. 打开 `path/`:有 `application.yaml` 视为已接入;只有惯例目录、没有本应用则走「新增」。
3. **清单写法跟目标 GitOps 仓库已有应用走**,不要另起一套:
- 自建镜像:`application.yaml` + `manifests/`Deployment/Service/Ingress
- 上游 Helm`sources[]` 里 chart + 本仓库 `values.yaml`
4. 从兄弟应用抄:`spec.project``destination.server``syncPolicy`、IngressClass、TLS 引用方式。
5. 仓库 README 写明「无 app-of-apps / 需逐个创建 Application」时,合入 main **不会**自动注册新 Application。
## 新增 Application
向用户确认清单里写不出的项:namespace、对外 host(或仅 ClusterIP)、是否要 `imagePullSecrets`、TLS Secret 名、镜像 tag。
然后在工作副本里:
1. 从最新默认分支拉出 `feat/<application>`(浅 clone 已在默认分支;`repo_dir``origin/<default>` 拉)。
2.`path/application.yaml` + 清单(或 values),字段对齐兄弟应用。
3. 镜像用固定 tag,不用 `:latest`
4. Secret、dockerconfigjson、口令 **不入库**Deployment 只引用 Secret 名。
## 升级 / 改清单
已有 Application 时:
1.`path` 下搜到的镜像行,把 `image: <name>:<old>` 改成新 tag。
2. 只改本次要求的清单;不要顺手改无关 values。
3. tag 必须已经推进镜像仓库(本轨道不负责 `docker push`,那是 builder)。
## 提交 MR
1. 分支从最新 `origin/<default>` 拉出,名称如 `feat/<application>``chore/<application>-<tag>`
2. 只提交 GitOps 仓库内本次文件。
3. `git push -u``origin`;不 `--force`、不硬 reset。
4. 按 remote 选 CLI**GitLab `glab mr create`**、**GitHub `gh pr create`**、**Gitea/Forgejo `tea pulls create`**。
创建前读该子命令 `--help`;指定 title、body、base、head。
5. CLI 对项目 404token 看不到仓库)而 SSH push 已成功:把 `git push` 打印的「create merge request」网页链接交给用户,不要读 token 配置、不要改用 curl 带 token。
6. **停在 MR**。不合并、不替用户点 Sync。浅 clone 的临时目录在得到 MR 链接(或确认失败)后删除。
MR 正文写清:改了什么、镜像引用、合入后用户还要做的事(首次 apply Application、拷 Secret、验 healthz/域名)。
## 合入后交给用户
无 app-of-apps 时,**第一次**注册 Application(之后改 manifests 合入即可):
```bash
kubectl apply -f <path>/application.yaml
```
TLS / 拉镜像 Secret 必须已在**工作负载所在 ns** 存在。没有则从已有 ns 拷贝(见下),不要新建一份写进 Git。
## Secretns 级,不入库)
`imagePullSecrets` 与 Ingress `tls.secretName` 都只在 Pod/Ingress 所在 namespace 生效。
不是集群每个 ns 都要建,只给**实际跑这个负载的 ns** 准备。
列出已有拉镜像 Secret(名字以 Deployment 的 `imagePullSecrets` 为准):
```bash
kubectl get secret <secret> -A
```
拷到目标 ns(类型须为 `kubernetes.io/dockerconfigjson`):
```bash
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`
```bash
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 Syncedautomated 关闭时用户需手动 Sync
- 升级:集群里容器镜像 tag 与清单一致
- 有 Ingresscurl 域名 healthz / 业务路径;HTTPS 失败先查 TLS Secret 是否在该 ns
## 不要做
- 把 Compose 的 rsync/`remote.py` 套到集群
- 常规发布用 `kubectl apply` 工作负载绕过 GitOps
- 提交 Harbor 密码、`dockerconfigjson`、TLS 私钥
- 在未获「合并」授权时 `glab mr merge` / `gh pr merge`