5.2 KiB
5.2 KiB
新主机入网清单(HA 阶段 4)
新机加入前,老机继续全量服务;新机全部验证通过后才切流量。 清单里的路径与实测值以 2026-10-26 主机为准,变了同步改。
1. 系统与用户
- Ubuntu 24.04、Python 3.12、git、Docker(与老机同大版本)、 Node 18(装 codex 用)。
- 建
codexsvc(uid 1003、gid 1004)并加入docker组。 - NTP:
timedatectl确认NTPSynchronized=yes(心跳、超时、 sweep 全依赖时钟,不同步会出现“活任务被误扫”)。
2. 代码与目录
/opt/codex-app-server:部署 tar 解包,chown -R codexsvc。/var/lib/codex-app-server/:建tenants/、repos/、codex-home/(模板)、backups/(700)。/etc/codex-app-server/env(0600 root):与老机一致,尤其CLOUD_DB_PASSWORD(新卷 Postgres 的初始化口令必须等于它, 见postgres-rebuild.md场景 B)、relay key、GitHub OAuth secret、webhook secret。密钥绝不进仓库、不进部署 tar。
3. 数据库
- 有现成 Postgres 时:env 里改
CLOUD_DB_HOST/PORT指向它。 - 没有时:按
postgres-rebuild.md场景 B 重建(新卷 + 最新备份 恢复 + 四表校验),再起 server。
4. 服务 units(都在 deploy/ 里有参考文件,unit 文件不在
deploy tar 里,须单独 scp 到 /etc/systemd/system/ 再
daemon-reload + enable + start)
codex-cloud-server(8765)与codex-cloud-server-2(8766) 双机;codex-autoscaler(min 1 / max 2、per-worker capacity 2、--docker-runtime runsc);codex-host-worker(local,--claim-executor-only,经aa-exec -p codex-host跑);codex-pg-backup.timer(每天 03:00 CST);monitor.timer(每 5 分钟)。- 注意:
codex-cloud-worker已停用(autoscaler 接管),绝不能 与 autoscaler 同时跑。
5. 沙箱与隔离
- AppArmor:加载
docker-codex与codex-host两个 profile (deploy/apparmor/下);codex-host的坑已修过(capability 放行只是 userns 内假 root;network netlink raw必须允许且 deny raw 须写明 inet/inet6;/tmp不隔离,见 HA-DESIGN)。 - Docker:
daemon.json注册 runsc(/usr/local/bin/runsc+ 必须成对的/usr/local/bin/gvisor-bin/,只拷 runsc 会报 sidecar 不可用);默认仍 runc,生产任务经 worker flag 走 runsc。 - 镜像:见第 7 节。
6. 出口代理(每机一份,改动时同批下发,不要手工各改各的)
- 拷
/etc/tinyproxy/tinyproxy.conf与/etc/tinyproxy/tinyproxy-filter(644,tinyproxy 用户可读; Filter 是 POSIX BASIC regex,extended 写法会把允许域名也 挡成 403;没有合法的Upstream none写法,直接连接就是默认)。 - 白名单只放行 xcmapi.org、github.com、pypi.org、npmjs.org
及子域;iptables 只放行
172.16.0.0/12与127.0.0.1(iptables-save导出、到新机iptables-restore)。 - Docker 任务容器出口走宿主 8888 代理(worker 的
--egress-proxy-port 8888)。
7. 镜像传输(现阶段:docker save/load,不建无鉴权 registry)
- 没有带鉴权 + TLS 的 registry 时,不要在本机跑无鉴权 registry(谁都能推恶意镜像,等于把 worker 的执行环境交给 任何人)。新机用 save/load 传镜像,流程已实弹验过:
# 老机导出(919MB,注意磁盘余量)
docker save codex-app-server:latest -o /tmp/codex-image.tar
# 传到新机(scp 或 chunk_send,传完 sha256 比对)
# 新机导入(幂等,已有同名镜像时只是重加已有层,不删东西)
docker load -i /tmp/codex-image.tar
docker images codex-app-server
- host 2 落地后,再评估带鉴权 + TLS 的 registry(或云厂商的
容器镜像服务),届时把“新机拉镜像”一步换成
docker pull。
8. 入口(nginx)
- 拷 vhost(含三个 codex location)与
codex-upstream.conf(upstream 块只能在 http 段,不能放进 server 块)。 - 宝塔重生成 vhost 会吃掉 location,备份在
/etc/codex-app-server/与 vhost 目录的.pre-*文件里, 被吃时从备份贴回,再nginx -t+ reload。 - 双机 nginx(浮动 IP keepalived,同机房;或 DNS 轮询 + 健康 检查,跨机房)需要第二台主机才能演练,现阶段单机 nginx 仍是单点,见 HA-DESIGN 阶段 4。
9. 入网验证(全部通过才切流量)
monitor.sh全过(含 backup 项)。- 双 server health(8765、8766)均为 ok 且 db_ok。
- autoscaler 正常(
--host-name已传宿主名,见 worker 进程 命令行),worker 注册表里有新机 worker。 - 一个 Docker 任务端到端完成(worktree_host 应为新机主机名)。
/pr同步路(本机 worktree)与队列路(改写 worktree_host 后排队、pr-runner 跑通)各一次。- 备份 timer 下次触发时间正常(
systemctl list-timers)。
10. 回滚
- 新机任何一步失败:停新机服务,老机不受影响(老机从未停过, 流量也从未切过)。
- 切流量后发现问题:nginx upstream 先摘掉新机端口(或把三个 location 的 proxy_pass 指回老机单端口),reload 即可回单机。