feat(deployer): add Argo CD / GitOps workflow with MR-based deployment
This commit is contained in:
+61
-10
@@ -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 <node> 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/<项目名>` 时才需要。
|
||||
|
||||
+64
-25
@@ -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-dir> = 本 SKILL.md 所在目录,先解析出来记下
|
||||
# 布局 A:显式指定仓库根
|
||||
export DEPLOYER_ROOT=/path/to/your/compose-repo
|
||||
export DEPLOYER_ROOT=/path/to/your-compose-repo
|
||||
python3 <skill-dir>/scripts/deploy/list.py
|
||||
|
||||
# 布局 B:在项目内直接跑即可(cwd 在项目里)
|
||||
python3 <skill-dir>/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 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
|
||||
或直接读服务目录及祖先的 `_config.yaml`。
|
||||
|
||||
### 3. 命令选择(语义严格区分)
|
||||
#### 3. 命令选择(语义严格区分)
|
||||
|
||||
| 意图 | 命令 |
|
||||
|------|------|
|
||||
@@ -121,12 +144,12 @@ python3 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
| 仅重启,不同步文件 | `remote.py <svc> restart` |
|
||||
| 排查 | `remote.py <svc> ps` / `remote.py <svc> logs` |
|
||||
|
||||
### 4. 项目侧 Makefile(可选薄封装)
|
||||
#### 4. 项目侧 Makefile(可选薄封装)
|
||||
|
||||
若项目有 Makefile 封装,命令形如 `make deploy TGT=<服务路径>`。
|
||||
没有 Makefile 时直接调 python 脚本即可,不要新建封装层。
|
||||
|
||||
### 5. 新增服务 / 环境 checklist
|
||||
#### 5. 新增服务 / 环境 checklist
|
||||
|
||||
独立仓库布局:
|
||||
|
||||
@@ -146,13 +169,13 @@ python3 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
4. 同名冲突或需要固定远程目录名 → `_config.yaml` 写 `name:`
|
||||
5. 首次部署前确认目标主机的远程目录不存在旧内容(rsync `--delete` 会清掉)
|
||||
|
||||
### 6. 下线服务
|
||||
#### 6. 下线服务
|
||||
|
||||
独立仓库布局:配置移入 `unused/`(自动脱离发现体系),远程按需手动清理:
|
||||
`ssh <node> "cd <base_path>/<name> && 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 <skill-dir>/scripts/deploy/deb.py <target> apt https://example.com/foo_1
|
||||
- 升级同版本号前想先看包信息:`ssh <node> "dpkg -I <暂存路径>"`;
|
||||
装完验证:`ssh <node> "dpkg -l | grep <pkg>"`。
|
||||
|
||||
### 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 <skill-dir>/scripts/deploy/deb.py <target> apt https://example.com/foo_1
|
||||
默认排除的 `data/`、`_data/`,或 compose 挂载的远程绝对路径
|
||||
(如 `/data01/docker/<svc>/`),否则会被清掉。
|
||||
- **镜像固定 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 <skill-dir>/scripts/deploy/deb.py <target> apt https://example.com/foo_1
|
||||
|
||||
## 验证
|
||||
|
||||
- `list.py` 输出全部服务与节点分布,数量与预期一致
|
||||
- Compose:`list.py` 输出全部服务与节点分布,数量与预期一致
|
||||
- 每次 sync/deploy 后 `remote.py <svc> ps` 容器 Up、`logs` 无报错
|
||||
- 升级后额外确认镜像 tag 与 compose.yaml 一致
|
||||
- 改 Traefik/Caddy 路由后 curl 对应域名验证生效
|
||||
- Argo CD:MR 可打开且含本次清单;用户合并后 Application Synced;有 Ingress 则 curl healthz
|
||||
|
||||
## scripts/
|
||||
|
||||
@@ -226,3 +264,4 @@ python3 <skill-dir>/scripts/deploy/deb.py <target> apt https://example.com/foo_1
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `references/config-reference.md` | `_config.yaml` 字段完整说明与继承合并规则 |
|
||||
| `references/argocd.md` | Argo CD 轨道:`argocd.yaml`、新增/升级、开 MR、ns 级 Secret |
|
||||
|
||||
@@ -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 <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 对项目 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 <path>/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 <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 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`
|
||||
@@ -1,6 +1,9 @@
|
||||
# `_config.yaml` 配置参考
|
||||
|
||||
`_config.yaml` 供 skill 部署脚本解析,决定同步目标与排除规则。可放在**服务目录、部署根或其任意祖先目录**;子目录中的字段覆盖父目录(继承合并)。
|
||||
`_config.yaml` 供 **Compose 轨道**脚本解析,决定同步目标与排除规则。可放在**服务目录、部署根或其任意祖先目录**;子目录中的字段覆盖父目录(继承合并)。
|
||||
|
||||
Argo CD 轨道用独立文件 `.skiff/deployer/argocd.yaml`,字段见 [argocd.md](argocd.md)。
|
||||
不要把 `argocd:` 嵌进本文件(脚本解析器不支持嵌套映射)。
|
||||
|
||||
## 放置位置(两种布局)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user