foms/docs/deploy-operations.md

187 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# FOMS 部署与运维手册
> 版本2026-08-27foms_app 纯伞化之后)
> 适用MySQL 主从 + rsync 文件同步的双机主备VIP 浮动1A+2B+3A
>
> 仓库分工:**foms_app纯伞构建/配置/启动)** + foms核心业务+ dbbackup/filesync/hostwatch邻接模块
> 部署以 foms_app 为入口。
## 一、架构
```
管理中心 Cfoms_app 组装运行,管理库 foms
▲ HTTPBearer token
┌────────────┴────────────┐
主机 Amaster 主机 Bstandby
· MySQL 主库 · MySQL 从库binlog 复制)
· 业务 + keepalived · 业务 + keepalived
· foms-agent · foms-agent
└──── VIP浮动业务连 VIP────┘
```
三个角色:
- **管理中心 C**:跑 foms_app组装核心 + dbbackup/filesync/hostwatch 模块),存配置与切换记录。
- **主机 A / 备机 B**:跑业务 + MySQL + keepalived + foms-agent守护进程
- **VIP**:业务流量入口,平时在 A故障时漂到 Bkeepalived 兜底 + FOMS 主动操作)。
## 二、管理中心 C 部署
```bash
git clone git@git.opencomputing.cn:yumoqing/foms_app.git
cd foms_app
./build.sh # 建 venv、clone+安装全部模块、生成 DDL/CRUD
```
**建库**build 后各模块目录下生成了 DDL
```bash
mysql -uroot -p < pkgs/foms/models/mysql.ddl.sql # 核心表
mysql -uroot -p < pkgs/dbbackup/models/mysql.ddl.sql # dbbackup 表
mysql -uroot -p < pkgs/filesync/models/mysql.ddl.sql # filesync 表
mysql -uroot -p < pkgs/hostwatch/models/mysql.ddl.sql # hostwatch 表
```
**配置**
- 数据库连接:编辑 `conf/config.json``databases.foms`host/user/password/db
- 环境变量:`cp .env.example .env`,填 `FOMS_PORT` / `MYSQL_ROOT_PASSWORD` / `FOMS_AGENT_TOKEN`
**启动**
```bash
./start.sh # 监听 FOMS_PORT默认 9080
./stop.sh
```
启动时 `load_foms()` 会自动注册切换编排器并拉起健康判定器后台任务。
**URL 布局**conf/config.json website.paths
- foms 核心:根路径(`/api/...``/clusters_list``/nodes_list`
- dbbackup`/dbbackup/...` filesync`/filesync/...` hostwatch`/hostwatch/...`
## 三、管理中心登记拓扑(部署后必做)
在 FOMS 界面(或 API依次创建
1. **节点**nodesA、B 各一条,填 host、ip、ssh_port、ssh_user、rolemaster/standby
2. **集群**clustersmaster_node_id=A、standby_node_id=B、`vip`(如 `192.168.1.100/24`)、
`check_interval`(检测间隔秒)、`failover_threshold`(连续故障次数)、`failover_mode=semi`
3. **复制配置**dbbackup_replications主库/从库地址、复制账号。
4. **文件同步**filesync_directories要 rsync 的目录source→dest
## 四、被管主机 A / B 部署
### 4.1 安装依赖
```bash
apt install -y mysql-server rsync keepalived ipvsadm python3
pip3 install psutil # Agent 采集系统指标需要
```
### 4.2 配置 keepalivedVIP 浮动)
A`/etc/keepalived/keepalived.conf`MASTER
```
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100 # A 高优先级
advert_int 1
virtual_ipaddress { 192.168.1.100/24 }
}
```
B 相同,但 `state BACKUP``priority 90`
keepalived 是**兜底**:机器全宕机时 VIP 自动漂移;"机器活、服务挂"的场景由 FOMS 主动 fence/promote 处理。
### 4.3 配置并启动 Agent
环境变量A、B 各自的值不同):
```bash
export FOMS_MANAGEMENT_URL=http://<C的IP>:9080 # 管理中心地址
export FOMS_NODE_ID=<本节点在nodes表的id> # A/B 各自
export FOMS_AGENT_TOKEN=<鉴权token> # 与管理中心约定
export FOMS_HEARTBEAT_INTERVAL=10
# 切换动作专用
export FOMS_MYSQL_SERVICE=mysql # MySQL systemd 服务名
export FOMS_VIP=192.168.1.100/24 # VIPCIDR
export FOMS_VIP_IFACE=eth0 # VIP 所在网卡
export MYSQL_ROOT_PASSWORD=<root密码> # promote/verify 用
# 回滚降从库用(指向"对端",即本机的复制上游)
export FOMS_MASTER_HOST=<对端IP> # B 上填 A 的 IPA 上填 B 的 IP
export FOMS_MASTER_PORT=3306
export FOMS_REPL_USER=repl
export FOMS_REPL_PASSWORD=<复制密码>
```
启动:
```bash
python3 foms-agent.py # 建议用 systemd 托管(见下)
```
**systemd 单元**`/etc/systemd/system/foms-agent.service`
```
[Unit]
Description=FOMS Agent
After=network.target
[Service]
EnvironmentFile=/etc/foms/agent.env # 上面的环境变量写这里
ExecStart=/usr/bin/python3 /opt/foms/foms-agent.py
Restart=always
[Install]
WantedBy=multi-user.target
```
```bash
systemctl enable --now foms-agent
```
### 4.4 Agent 需要的权限
Agent 以能执行 `systemctl`/`ip`/`mysql` 的用户运行(通常 root。**生产环境应收窄**
用 sudoers 白名单只允许这几条命令,而非完整 root。
## 五、日常运维
### 5.1 故障识别(自动)
健康判定器后台循环(默认 5s 扫一次):
- 判定条件master 心跳超时(> `failover_threshold × check_interval` 秒)**或** 复制状态 error/failed。
- **防抖**:连续 `failover_threshold` 次命中才判故障(避免瞬时抖动误判)。
- 判故障 → 写 `switchover_logs(status=detected, trigger=auto_detect)` + 发 `hostwatch_events` 告警。
- **半自动**:只告警不切,等人确认。
### 5.2 故障切换(人工确认)
看到告警后,人工确认 → 触发切换:
- 界面:集群列表 → 切换按钮(`trigger_switchover`
- API`POST /api/trigger_switchover.dspy {cluster_id}`
编排器异步执行六步(`switchover_steps` 表可查每步状态):
```
1. precheck 目标节点在线+心跳新鲜+复制延迟≤5s防丢数据
2. fence 隔离原主:停 MySQL + 摘 VIP ← 防脑裂,失败必中止
3. promote 提升新主STOP SLAVE + RESET SLAVE ALL原子
4. flip_sync 反转文件同步方向
5. verify 新主可写测试 + VIP 归属检查(业务层请人工确认)
6. converge 集群主备互换 + 节点角色互换 + 状态收敛
```
### 5.3 故障维修与切回
1. 修好原主 A硬件/系统/MySQL
2. 把 A 重新挂为 B 的从库(`CHANGE MASTER TO` 指向 B`START SLAVE`),等复制追平。
3. 确认 A 健康后,触发切回:`trigger_switchback`(反向六步)。
### 5.4 失败与回滚语义
- 任何一步失败 → 已完成步骤**逆向回滚**`switchover_logs=failed`
- 回滚也失败 → `switchover_logs=rollback_failed` + 最高级告警,**人工介入**。
- 回滚动作unfence恢复原主、revert_promote降回从库、flip_sync 反转、converge 换回。
## 六、防脑裂三重保险
1. **fence 先于 promote**:先停旧主 MySQL + 摘 VIP再立新主。
2. **fence 失败硬中止**:绝不 promote否则双主
3. **keepalived VRRP 兜底**:主机器全宕机时 VIP 自动漂移。
## 七、已知限制(诚实声明)
- **切换时 Agent 延迟**Agent 轮询命令,切换六步串行走完约需数十秒(运维切换通常可接受)。
- **verify 只到数据层**:验证"MySQL 可写 + VIP 可达",业务层是否正常需人工确认。
- **数据丢失窗口**precheck 要求复制延迟 ≤5sfence 到 promote 之间若有未同步 binlog 会丢失(已尽量收窄)。
- **远程命令安全**命令下发目前无白名单鉴权P1 待办),生产应收窄。
## 八、模块清单
| 仓库 | 角色 | 职责 |
|---|---|---|
| foms_app | 纯伞(应用壳) | 组装入口、build、配置、启动、首页、RBAC 注册(无业务逻辑) |
| foms | 业务模块(核心) | 集群/节点/切换编排/心跳/远程命令/Agent |
| dbbackup | 业务模块 | 数据库备份 + 日志同步binlog 复制) |
| filesync | 业务模块 | 运行文件同步rsync |
| hostwatch | 业务模块 | 日志监控 + 日志分析 + 主机指标 |