From ee31278947907dfdef0651b07b7c96cb5f613ca7 Mon Sep 17 00:00:00 2001 From: laily Date: Mon, 24 Aug 2026 20:37:55 +0800 Subject: [PATCH] feat(deployer): add Argo CD / GitOps workflow with MR-based deployment --- skills/deployer/README.md | 71 +++++++-- skills/deployer/SKILL.md | 89 ++++++++--- skills/deployer/references/argocd.md | 150 ++++++++++++++++++ .../deployer/references/config-reference.md | 5 +- 4 files changed, 279 insertions(+), 36 deletions(-) create mode 100644 skills/deployer/references/argocd.md diff --git a/skills/deployer/README.md b/skills/deployer/README.md index e686b02..98f942d 100644 --- a/skills/deployer/README.md +++ b/skills/deployer/README.md @@ -1,13 +1,14 @@ # deployer -把「一堆 VPS / NAS 上的 Docker 服务」变成一个 Git 仓库就能管的事:仓库里只放服务配置(数据), -部署、同步、升级的方法和脚本全部由这个 skill 自带,换台电脑、换个项目都能直接用。 +把「服务怎么跑」写进 Git,部署方法由这个 skill 自带:换台电脑、换个项目都能直接用。 -支持两种用法: +支持三种用法: -- **独立配置中心**:一个专门的 Git 仓库管所有机器的所有服务(如 app00) -- **项目内环境**:在普通项目里放 `.skiff/deployer/{prod,test,dev}/`, - 把这个项目的生产/测试/开发环境也用同一套流程部署 +- **独立配置中心**:一个专门的 Git 仓库管所有机器的所有 Compose 服务(如 app00) +- **项目内 Compose 环境**:在普通项目里放 `.skiff/deployer/{prod,test,dev}/`, + 把这个项目的生产/测试/开发环境用 rsync + docker compose 部署 +- **Argo CD / GitOps**:项目里放 `.skiff/deployer/argocd.yaml`;Agent 改 GitOps 并开 MR, + 你合并后由 Argo CD 同步。仓库既可以只写 Git 地址(部署时浅 clone),也可以指定本机已有目录。 ## 什么时候使用 @@ -17,13 +18,13 @@ - 新加一个服务、把服务从一台机器挪到另一台、或下线旧服务 - 想给当前项目加 prod/test/dev 三套远程环境并随时部署其中一套 - 需要一张「哪台机器跑哪些服务」的清单 +- 镜像要进 Kubernetes,走 Argo CD:改 GitOps、开 MR、合并后部署 ## 使用前准备 -- 本机装有 Python 3、`rsync`、`ssh` -- 目标机器装好 Docker + Docker Compose v2 -- `~/.ssh/config` 里为每台机器配好 Host 别名,且能免密(或 agent)登录 -- 知道每个服务的运行时数据放在哪(这些目录不能被同步覆盖) +- Compose:本机 Python 3、`rsync`、`ssh`;目标机器 Docker Compose v2;`~/.ssh/config` 免密(或 agent) +- 知道每个 Compose 服务的运行时数据放在哪(这些目录不能被同步覆盖) +- Argo CD:能 clone/push GitOps 仓库(SSH 或已登录的 HTTPS),并能开 MR(GitLab `glab` / GitHub `gh` / Gitea `tea`)。本机不必长期放一份 GitOps checkout。 ## 使用示例 @@ -44,6 +45,11 @@ web1 能出网,直接让它从 https://... 把包拉下来装 给这个项目建好 .skiff/deployer,prod 和 test 分别放到两台机器上 把 test 环境重新部署一下 prod 的 compose 加个 redis,改完发上去 + +# Argo CD +把这个项目接到 argocd,仓库写成 git@git.example.com:org/infra-gitops.git +GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR +升镜像 tag,改 GitOps 开 MR ``` ## Agent 会做什么 @@ -55,6 +61,8 @@ prod 的 compose 加个 redis,改完发上去 4. deb 包安装走独立脚本:scp 上传到暂存目录后远程 apt 安装,失败自动修依赖 5. 同步后查看容器状态和日志确认生效 6. 只针对你指定的那一个服务操作,不会批量动整台机器 +7. Argo CD:读 `.skiff/deployer/argocd.yaml`,浅 clone 或使用 `repo_dir`,改清单,推分支开 MR,停下来等你合并; + 不直接 kubectl 发布,不把 Harbor/TLS 密钥提交进 Git 项目内布局下,远程目录名自动带上项目前缀(如 `my-project-prod`), 避免同一台机器上多个项目的同名环境互相覆盖;需要固定名字时在 `_config.yaml` 写 `name:`。 @@ -68,3 +76,46 @@ prod 的 compose 加个 redis,改完发上去 - `ps` 显示容器 Up、`logs` 无报错;升级后镜像 tag 与配置一致 - deb 安装后 `ssh dpkg -l` 能看到目标包,服务能正常启动 - 域名/端口类服务能 curl 通 +- Argo CD:给出 MR 链接;合入后 Application Synced,域名/healthz 可访问 + +## Argo CD 的两种接法 + +在业务项目里放 `.skiff/deployer/argocd.yaml`。Agent 只改 GitOps 并开 MR,**你合并之后** Argo CD 才部署。镜像、namespace、域名、Secret 名以 GitOps 清单为准,不必在这个文件里再抄一遍。 + +### 1. 只写仓库地址(默认) + +本机不用长期放 GitOps 仓库。部署时 Agent 浅 clone 到临时目录,改完开 MR,用完删掉。 + +```yaml +# .skiff/deployer/argocd.yaml +repo: git@git.example.com:org/infra-gitops.git +``` + +`https://git.example.com/org/infra-gitops.git` 也可以。对本机 git 来说这个地址要能 clone 和 push。 + +对 Agent 说: + +```text +把这个项目接到 argocd,仓库是 git@git.example.com:org/infra-gitops.git +升到 v0.0.2,改 GitOps 开 MR +``` + +### 2. 指定本地目录(不 clone) + +GitOps 仓库已经 checkout 在旁边时,写 `repo_dir`,Agent 直接进这个目录改、推分支、开 MR。 + +```yaml +# .skiff/deployer/argocd.yaml +repo: git@git.example.com:org/infra-gitops.git +repo_dir: ../infra-gitops +``` + +也可以只写 `repo_dir`(远程从该目录的 `origin` 读)。相对路径相对**业务项目根**。 + +对 Agent 说: + +```text +GitOps 已经 clone 在 ../infra-gitops,用那个目录开 MR +``` + +两种接法都可以再加 `path:`,仅当 Application 目录不是默认的 `argocd/applications/<项目名>` 时才需要。 diff --git a/skills/deployer/SKILL.md b/skills/deployer/SKILL.md index f71ab99..b6e149c 100644 --- a/skills/deployer/SKILL.md +++ b/skills/deployer/SKILL.md @@ -1,38 +1,53 @@ --- name: deployer description: >- - 管理多 VPS / NAS 的 Docker Compose 配置中心:仓库只存服务数据(compose.yaml、静态配置), - 部署方法与脚本由本 skill 提供。当用户要求部署、同步、升级、重启远程 Docker 服务, - 新增/迁移/下线服务,梳理节点与服务清单,向节点分发安装 deb 包(scp 上传 + dpkg/apt 安装, - 或从 URL 远程拉取安装),或提到 make sync/deploy/upgrade/TGT、_config.yaml、rsync 同步、 - tar over SSH、Synology NAS 部署失败时使用。 + 管理两类部署:多机 Docker Compose(仓库存 compose.yaml 与静态配置,本 skill 脚本 + 同步到 SSH 节点后 docker compose 应用),以及 Argo CD GitOps(改 GitOps 仓库清单、 + 开 PR/MR,用户合并后由 Argo CD 同步)。当用户要求部署、同步、升级、重启远程 + Compose 服务,向节点装 deb,新增/迁移/下线服务,梳理节点清单,make deploy TGT、 + _config.yaml、rsync、tar over SSH、NAS 部署失败;或要求 ArgoCD / GitOps / K8s + 部署、更新 Application、升镜像 tag、开 MR 让用户合并部署时使用。 --- -# deployer:多机 Compose 配置中心 +# deployer:Compose 节点与 Argo CD GitOps -仓库 = 数据(各机器的 `compose.yaml` 与静态配置);方法 = 本 skill 的脚本与规范。 -本地改配置 → skill 脚本同步到对应 SSH 节点 → 远程 `docker compose` 应用。 +两条轨道,配置都在仓库里,方法由本 skill 提供。 + +- **Compose**:本地改 `compose.yaml` → 脚本同步到 SSH 节点 → 远程 `docker compose`。 +- **Argo CD**:改 GitOps 仓库清单 → 开 PR/MR → 用户合并 → Argo CD 同步。不要用 + Compose 的 `sync.py`/`remote.py` 去推集群。 --- ## 何时使用 - 部署 / 同步 / 升级 / 重启某个远程 Docker Compose 服务 -- 向节点安装 deb 包:scp 上传本地 .deb 后 dpkg/apt 安装,或远程从 URL 直接拉取安装 +- 向节点安装 deb 包:scp 上传本地 .deb 后 dpkg/apt 安装,或从 URL 远程拉取安装 - 新增、迁移、下线一个服务;梳理「哪台机器跑什么」 - sync 失败排查、证书丢失、改了配置不生效等运维问题 - 提到 `make deploy TGT=...`、`TGT=`、`_config.yaml`、rsync/tar 同步 +- Argo CD / GitOps / 集群部署:新增 Application、改清单、升镜像 tag、开 MR 等用户合并 ## 不适用 - 单机 docker 日常使用(无多机同步诉求) -- K8s / Nomad 等编排系统 -- CI/CD 流水线构建发布(本流程是 push 式运维,不是流水线) +- Nomad,或绕过 GitOps 用 `kubectl apply` 当常规发布 +- 构建并推送镜像(走 builder);本 skill 只改 GitOps 里对该镜像的引用 --- ## 核心模型(先读懂再动手) +### 轨道选择 + +| 信号 | 轨道 | +|------|------| +| ArgoCD / GitOps / 集群 / 开 MR 部署 / 项目有 `.skiff/deployer/argocd.yaml` | Argo CD,见 [argocd.md](references/argocd.md) | +| sync、`TGT=`、某台机器、`compose.yaml` | Compose(下文布局与步骤) | +| 两者都有且意图不清 | 先问 | + +### Compose + - **仓库只放数据**:`compose.yaml`、Caddyfile、Traefik 动态配置等静态配置进 Git; 运行时数据(证书、数据库、上传文件)永不进 Git,也永不参与同步范围。 - **每个可部署服务目录必须有 `compose.yaml`**,且能解析出目标节点 `node` @@ -40,7 +55,12 @@ description: >- - **`node` 即 SSH Host 别名**(`~/.ssh/config`),支持 `user@host` 形式。 - `unused/` 下不参与自动发现与部署。 -### 两种布局 +### Argo CD + +源项目 `.skiff/deployer/argocd.yaml`:`repo` 写 Git 地址(部署时浅 clone),或加 `repo_dir` 用已有 checkout。 +改 GitOps 清单,不要改 Compose 脚本。密钥不入库。两种接法见 skill README,步骤见 [argocd.md](references/argocd.md)。 + +### 两种 Compose 布局 **A. 独立配置中心仓库**(如 app00):仓库根即部署根, `DEPLOYER_ROOT=/path/to/repo` 指定后按仓库内相对路径操作: @@ -64,6 +84,7 @@ my-project/ ├── src/ ... # 项目本体 └── .skiff/deployer/ ├── _config.yaml # 三个环境共享默认(node/base_path 等) + ├── argocd.yaml # 可选,Argo CD 指针(不是 compose 环境) ├── prod/ │ ├── compose.yaml # 生产 compose 与配置 │ └── _config.yaml # 环境级覆盖 @@ -77,7 +98,9 @@ my-project/ ## 步骤 -### 0. 定位部署根 +### Compose 轨道 + +#### 0. 定位部署根 skill 目录下的 `scripts/deploy/` 是通用部署工具链(lib/sync/remote/list), 不依赖具体项目路径。部署根按以下顺序解析: @@ -89,19 +112,19 @@ skill 目录下的 `scripts/deploy/` 是通用部署工具链(lib/sync/remote/ ```bash # = 本 SKILL.md 所在目录,先解析出来记下 # 布局 A:显式指定仓库根 -export DEPLOYER_ROOT=/path/to/your/compose-repo +export DEPLOYER_ROOT=/path/to/your-compose-repo python3 /scripts/deploy/list.py # 布局 B:在项目内直接跑即可(cwd 在项目里) python3 /scripts/deploy/list.py ``` -### 1. 摸底:列出服务与节点 +#### 1. 摸底:列出服务与节点 上一步的 `list.py` 输出全部服务与节点分布;新增环境/服务后重跑确认被发现。 -项目布局下 `prod/test/dev` 各显示为 `{项目名}-{env}`。 +项目布局下 `prod/test/dev` 各显示为 `{项目名}-{env}`。`argocd.yaml` 不会被 list.py 当成 compose 服务。 -### 2. 解析单个服务 +#### 2. 解析单个服务 ```bash # 查看 node、远程路径、排除规则(sync.py 干跑会打印这些信息) @@ -110,7 +133,7 @@ python3 /scripts/deploy/sync.py 或直接读服务目录及祖先的 `_config.yaml`。 -### 3. 命令选择(语义严格区分) +#### 3. 命令选择(语义严格区分) | 意图 | 命令 | |------|------| @@ -121,12 +144,12 @@ python3 /scripts/deploy/sync.py | 仅重启,不同步文件 | `remote.py restart` | | 排查 | `remote.py ps` / `remote.py logs` | -### 4. 项目侧 Makefile(可选薄封装) +#### 4. 项目侧 Makefile(可选薄封装) 若项目有 Makefile 封装,命令形如 `make deploy TGT=<服务路径>`。 没有 Makefile 时直接调 python 脚本即可,不要新建封装层。 -### 5. 新增服务 / 环境 checklist +#### 5. 新增服务 / 环境 checklist 独立仓库布局: @@ -146,13 +169,13 @@ python3 /scripts/deploy/sync.py 4. 同名冲突或需要固定远程目录名 → `_config.yaml` 写 `name:` 5. 首次部署前确认目标主机的远程目录不存在旧内容(rsync `--delete` 会清掉) -### 6. 下线服务 +#### 6. 下线服务 独立仓库布局:配置移入 `unused/`(自动脱离发现体系),远程按需手动清理: `ssh "cd / && docker compose down"`,数据卷按需保留或删除。 项目环境布局:删除对应 `.skiff/deployer/{env}/` 目录即可脱离发现体系,远程清理同上。 -### 7. 向节点安装 deb 包 +#### 7. 向节点安装 deb 包 `deb.py` 把 deb 包发到节点并安装。目标两种写法:仓库内目录 (复用 `_config.yaml` 继承链解析 node/port/identity_file,如 `hosts/web1`), @@ -177,6 +200,19 @@ python3 /scripts/deploy/deb.py apt https://example.com/foo_1 - 升级同版本号前想先看包信息:`ssh "dpkg -I <暂存路径>"`; 装完验证:`ssh "dpkg -l | grep "`。 +### Argo CD 轨道 + +完整步骤与 `argocd.yaml` 字段见 [argocd.md](references/argocd.md)。 + +1. 读项目 `.skiff/deployer/argocd.yaml`(无则只问 Git 地址,写成 `repo:`)。 + 有 `repo_dir` 则用该目录;否则把 `repo` 浅 clone 到临时目录,用完删除。 +2. 在工作副本里按**已有应用惯例**新增 Application,或只改镜像 tag / 清单。 +3. 从最新默认分支拉出分支,commit、push,用 `glab`/`gh`/`tea` 开 MR;CLI 对项目 404 则把 + `git push` 给出的网页建单链接交给用户。 +4. **停在 MR**,不合并、不 `kubectl apply` 工作负载。 +5. 无 app-of-apps 时提醒用户首次 `kubectl apply` 那份 `application.yaml`。 +6. Harbor 拉镜像 Secret、TLS Secret 不入库;只在工作负载所在 ns 准备,可从其他 ns 拷贝。 + --- ## 注意事项 @@ -187,8 +223,9 @@ python3 /scripts/deploy/deb.py apt https://example.com/foo_1 默认排除的 `data/`、`_data/`,或 compose 挂载的远程绝对路径 (如 `/data01/docker//`),否则会被清掉。 - **镜像固定 tag**,不用 `:latest` 漂移;成对升级的服务(如 proxy 客户端/服务端)要同步升。 -- **密钥**:优先放远程 `.env` 或环境变量,不要提交新密钥进 Git。 -- **Git 安全**:不 `--force` 推送、不硬 reset,除非用户明确要求。 +- **密钥**:Compose 优先放远程 `.env`;Argo CD 的 dockerconfigjson / TLS 私钥只存在集群 Secret。 + 不要提交新密钥进 Git。 +- **Git 安全**:不 `--force` 推送、不硬 reset,除非用户明确要求。Argo CD 轨道不直接推默认分支。 - **NAS / Synology 特例**:部分 NAS 的 SSH 用户禁用 rsync 协议(Permission denied)。 表现是 sync 报错但 ssh 正常。处理顺序: 1. 该节点 `_config.yaml` 写真实 `base_path`(如 `/volume1/docker`,避开符号链接路径) @@ -205,10 +242,11 @@ python3 /scripts/deploy/deb.py apt https://example.com/foo_1 ## 验证 -- `list.py` 输出全部服务与节点分布,数量与预期一致 +- Compose:`list.py` 输出全部服务与节点分布,数量与预期一致 - 每次 sync/deploy 后 `remote.py ps` 容器 Up、`logs` 无报错 - 升级后额外确认镜像 tag 与 compose.yaml 一致 - 改 Traefik/Caddy 路由后 curl 对应域名验证生效 +- Argo CD:MR 可打开且含本次清单;用户合并后 Application Synced;有 Ingress 则 curl healthz ## scripts/ @@ -226,3 +264,4 @@ python3 /scripts/deploy/deb.py apt https://example.com/foo_1 | 文件 | 用途 | |------|------| | `references/config-reference.md` | `_config.yaml` 字段完整说明与继承合并规则 | +| `references/argocd.md` | Argo CD 轨道:`argocd.yaml`、新增/升级、开 MR、ns 级 Secret | diff --git a/skills/deployer/references/argocd.md b/skills/deployer/references/argocd.md new file mode 100644 index 0000000..4490243 --- /dev/null +++ b/skills/deployer/references/argocd.md @@ -0,0 +1,150 @@ +# 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 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/`(浅 clone 已在默认分支;`repo_dir` 从 `origin/` 拉)。 +2. 建 `path/application.yaml` + 清单(或 values),字段对齐兄弟应用。 +3. 镜像用固定 tag,不用 `:latest`。 +4. Secret、dockerconfigjson、口令 **不入库**;Deployment 只引用 Secret 名。 + +## 升级 / 改清单 + +已有 Application 时: + +1. 在 `path` 下搜到的镜像行,把 `image: :` 改成新 tag。 +2. 只改本次要求的清单;不要顺手改无关 values。 +3. tag 必须已经推进镜像仓库(本轨道不负责 `docker push`,那是 builder)。 + +## 提交 MR + +1. 分支从最新 `origin/` 拉出,名称如 `feat/` 或 `chore/-`。 +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 对项目 404(token 看不到仓库)而 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 /application.yaml +``` + +TLS / 拉镜像 Secret 必须已在**工作负载所在 ns** 存在。没有则从已有 ns 拷贝(见下),不要新建一份写进 Git。 + +## Secret(ns 级,不入库) + +`imagePullSecrets` 与 Ingress `tls.secretName` 都只在 Pod/Ingress 所在 namespace 生效。 +不是集群每个 ns 都要建,只给**实际跑这个负载的 ns** 准备。 + +列出已有拉镜像 Secret(名字以 Deployment 的 `imagePullSecrets` 为准): + +```bash +kubectl get secret -A +``` + +拷到目标 ns(类型须为 `kubernetes.io/dockerconfigjson`): + +```bash +kubectl get 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 -n SOURCE \ + -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d > /tmp/dockerconfig.json +kubectl -n DEST create secret generic \ + --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` diff --git a/skills/deployer/references/config-reference.md b/skills/deployer/references/config-reference.md index a58f51f..72b9326 100644 --- a/skills/deployer/references/config-reference.md +++ b/skills/deployer/references/config-reference.md @@ -1,6 +1,9 @@ # `_config.yaml` 配置参考 -`_config.yaml` 供 skill 部署脚本解析,决定同步目标与排除规则。可放在**服务目录、部署根或其任意祖先目录**;子目录中的字段覆盖父目录(继承合并)。 +`_config.yaml` 供 **Compose 轨道**脚本解析,决定同步目标与排除规则。可放在**服务目录、部署根或其任意祖先目录**;子目录中的字段覆盖父目录(继承合并)。 + +Argo CD 轨道用独立文件 `.skiff/deployer/argocd.yaml`,字段见 [argocd.md](argocd.md)。 +不要把 `argocd:` 嵌进本文件(脚本解析器不支持嵌套映射)。 ## 放置位置(两种布局)