RUNBOOK — kvm_rocky9_deploy 部署工具运行与使用手册¶
写给:接手日常运维与值班的人(没接触过本工程也能照着做)。 事实来源:
main.py、deployer.py、utils/kvm_utils.py、config_schema.py(行号见各处引用,以实现体为准)。 修订:2026-09-25 首版。
目录¶
1. 服务概览¶
干什么用的:在 KVM 宿主 dell-R620 上按 YAML 配置文件批量创建 Rocky 9 虚机(含磁盘、无人值守安装、SSH 公钥注入、开机自启),并提供只读体检、漂移巡检与整体回滚。
由哪些组件构成:
| 组件 | 位置 | 职责 |
|---|---|---|
| 入口 CLI | main.py |
参数解析、模式分发、退出码 |
| 生命周期编排 | deployer.py |
门禁、漂移、供给、校验、回滚业务 |
| 配置校验 | config_schema.py |
配置合法性(BLOCK/WARN 两级) |
| 命令与探测 | utils/kvm_utils.py |
subprocess 执行 + 三态探测 |
| 共享库 | /home/rain/py_public_modules/(经 .pth 挂载) |
阶段编排基类、日志 |
| 配置 | config/*.yaml |
每批次一份主机清单 |
依赖谁:宿主上的 virt-install/virsh/qemu-img/openssl、libvirtd 服务、存储池(hdd-pool/ssd-pool/iso)、桥 br0、安装 ISO /data/kvm/iso/Rocky-9-latest-x86_64-dvd.iso。
异常时的业务影响:本工具只在「创建/回滚主机」时有影响;平时不常驻、不监听端口,坏了不影响已建好的虚机。异常影响的是下一次建机能否进行。
重要性等级:中(建机工具,非生产链路组件;但回滚误操作会不可恢复地销毁虚机与磁盘,故回滚动作按高危对待)。
执行模型:单机本机执行(virsh qemu:///system,不走 SSH 到宿主);进程锁 logs/kvm_rocky9_deploy.lock 保证同时只有一个实例。
2. 接入与凭据¶
接入:登录 KVM 宿主 dell-R620(工程目录 /home/rain/Documents/kvm/kvm_rocky9_deploy),所有命令在工程根目录执行,需要 root(门禁第一项就查 root 身份)。
账号清单:
| 账号 | 用途 |
|---|---|
| 宿主 root(sudo) | 执行 main.py 全部模式、virsh |
| 新建虚机的 root | 运维登录虚机;口令与公钥见下 |
凭据存放与取用(凭据不写入本文档,只给取用命令):
| 凭据 | 位置 | 取用命令 |
|---|---|---|
| 各批次虚机 root 口令 | config/credentials*.yaml(0600,已 gitignore) |
sudo cat config/credentials-<批次>.yaml |
| SSH 公钥(注入虚机的) | config/ssh.pubkey_file 指向 /home/rain/.ssh/id_ed25519.pub |
cat /home/rain/.ssh/id_ed25519.pub |
客户端接入示例(虚机就绪后,用宿主私钥登录):
ssh -i /home/rain/.ssh/id_ed25519 root@192.168.31.28 # <ip> 换成目标节点配置里的 ip
# 预期:直接登录成功(配置默认禁用口令认证,仅公钥可用)
# 若被拒:确认该批次配置 disable_password_auth 与 pubkey_file,见第 8 章场景 4
3. 日常速查表¶
以下均在工程根目录执行;<cfg> 换成 config/ 下的配置文件(清单见第 5 章)。
| # | 目的 | 命令 | 预期 |
|---|---|---|---|
| 1 | 只读体检(能不能建) | sudo .venv/bin/python main.py --precheck --config <cfg> |
退出码 0=可建;2=有阻断(逐项 [阻断] 已列出) |
| 2 | 预演(将改什么,零改动) | sudo .venv/bin/python main.py --dry-run --config <cfg> |
每条变更一行 [dry-run] 将执行变更: …;计划落 build/plans/ |
| 3 | 真实创建 | sudo .venv/bin/python main.py --config <cfg> |
末行 状态: success(或 skipped);退出码 0 |
| 4 | 漂移巡检(现状 vs 期望) | sudo .venv/bin/python main.py --drift --config <cfg> |
0=无漂移;4=有漂移;5=探测不完整 |
| 5 | 查全部虚机 | virsh --connect qemu:///system list --all |
列出全部域与状态 |
| 6 | 查执行日志 | tail -n 50 logs/kvm-rocky9-deploy.log |
最近执行的阶段与结果 |
| 7 | 查最近体检/巡检报告 | ls -t build/reports/ \| head; cat build/reports/<最新文件> |
报告含结论与逐项明细 |
| 8 | 高危:销毁本配置全部虚机 | sudo .venv/bin/python main.py --rollback --force --config <cfg> |
不可恢复;预演用 --dry-run --rollback |
回滚(第 8 行)是唯一不可逆操作:销毁所选配置里列出的虚机与磁盘,不影响其它批次。
CentOS 7 批次用完全相同的子命令,只需把入口换成
main_centos7.py、配置换成config/hosts-20260928-centos7.yaml、日志看logs/kvm-centos7-deploy.log;差异与专属故障场景见第 12 章。
4. 日常操作¶
4.1 标准建机流程(新建一批主机)¶
# ① 准备配置(复制模板改,见第 5 章)
cp config/deploy.yaml.example config/<新配置>.yaml && vi config/<新配置>.yaml
# ② 只读体检:环境 + 配置
sudo .venv/bin/python main.py --precheck --config config/<新配置>.yaml
# 预期输出尾行:门禁检查:共 N 项(通过 a、告警 b、阻断 c)
# 全通过 → "预检查通过:全部检查项达标",退出码 0
# 有阻断 → "门禁未通过:N 项阻断,终止执行",退出码 2,按逐项 [阻断] 修复
# ③ 预演:不改任何系统状态
sudo .venv/bin/python main.py --dry-run --config config/<新配置>.yaml
# 预期:"状态巡检:发现 N 项待变更" + 每项 [dry-run] 将执行变更: …
# 计划写入 build/plans/plan-<配置名>-<时间戳>.yaml
# ④ 真实执行
sudo .venv/bin/python main.py --config config/<新配置>.yaml
# 预期(单台约 10–15 分钟,安装等待上限 runtime.install_timeout_sec=2400s):
# "状态巡检:发现 N 项待变更" → "开始处理 N 台节点" → "[完成] <name>"
# → "节点校验结果:" 每台 状态=running SSH=… 自启=… → "全部节点校验通过"
# 末行:"状态: success | 耗时: …s"
# ⑤ 验证
sudo .venv/bin/python main.py --drift --config config/<新配置>.yaml # 预期退出码 0:"未发现漂移"
ssh -i /home/rain/.ssh/id_ed25519 root@<节点ip> 'hostname' # 预期:返回主机名
4.2 幂等复跑¶
同一命令重复执行是安全的:已达标的项逐条跳过(日志形如 卷已存在,跳过:…、域已存在,跳过创建:…、自启已开启,跳过:…),全部达标时整体 状态: skipped、退出码 0。复跑不会更换已生成的 root 口令(口令复用既有凭据文件,deployer.py:1040-1060)。
4.3 停止 / 启动单台虚机(不走本工具)¶
virsh --connect qemu:///system shutdown <name> # 优雅关机
virsh --connect qemu:///system start <name> # 启动
virsh --connect qemu:///system console <name> # 进控制台(排障用,退出:Ctrl+])
4.4 回滚(销毁整批)¶
# 先预演,看将销毁什么(零改动)
sudo .venv/bin/python main.py --dry-run --rollback --config <cfg>
# 预期:逐台 "[dry-run] 将销毁域与磁盘:<name>",末行 "[dry-run] 未执行任何销毁动作"
# 高危:真实销毁。两种确认方式二选一——
sudo .venv/bin/python main.py --rollback --force --config <cfg> # 非交互:显式 --force
sudo .venv/bin/python main.py --rollback --config <cfg> # 交互:输入 YES
# 预期:"【高危】回滚:将销毁…" 横幅 → "已销毁域与磁盘" → "回滚完成"
# 未加 --force 且非交互 → "[已取消] 未执行回滚",退出码 1
销毁顺序与保护(deployer.py:853-921):逐台探测域 → 不存在则跳过;探测 UNKNOWN 则跳过不删(防误删)→ running 先 virsh destroy → virsh undefine --remove-all-storage --nvram。
5. 配置管理¶
5.1 配置文件清单¶
| 文件 | 管什么 | 状态 |
|---|---|---|
config/deploy.yaml.example |
模板(全部可选项带注释),新批次从它复制 | — |
config/deploy.yaml |
默认配置(--config 缺省值) |
既有 |
config/hosts-20260918.yaml |
k8s + slurm 批次 | 既有 |
config/lustre-20260921.yaml |
lustre 批次 | 既有 |
config/hosts-20260924-lsf.yaml |
LSF 批次 | 既有 |
config/hosts-20260925-rocky9.yaml |
rocky9-01 | 既有 |
config/hosts-20260928-centos7.yaml |
centos7-01(CentOS 7 临时测试机,入口 main_centos7.py,见第 12 章) |
既有 |
config/hosts-20261001-harbor.yaml |
harbor-01(学习测试用镜像仓库,4C/8G + 200G 数据盘挂 /data) |
既有 |
config/flexlm-rocky.yaml |
flexlm license server(规划中) | 当前 name/ip 与 rocky9-01 冲突,未修不可执行 |
config/credentials*.yaml |
各批次 root 口令(工具自动生成,0600,gitignore) | 只读引用 |
5.2 修改流程(任何配置改动)¶
vi config/<cfg>.yaml # ① 改配置
sudo .venv/bin/python main.py --precheck --config config/<cfg>.yaml # ② 配置+环境校验
sudo .venv/bin/python main.py --dry-run --config config/<cfg>.yaml # ③ 预演核对变更明细
sudo .venv/bin/python main.py --config config/<cfg>.yaml # ④ 执行
sudo .venv/bin/python main.py --drift --config config/<cfg>.yaml # ⑤ 验证退出码 0
改完必须回到 ②;只读改动(如加注释)至少跑一次 ② 确认零告警。
5.3 配置段与易错点¶
配置段:target(hostname/iso)、storage(system_pool/data_pool)、vm_defaults、network、ssh、host_tuning(可省,省则不碰宿主内核)、nodes、runtime。键名以 config_schema.py:78-95 的已知键表为准。
易错点(按踩坑频率排序):
- 跨批次冲突工具查不出来。配置校验只保证同一批次内 name/ip/mac 唯一(
config_schema.py:435-457),不做网络占用探测(无 ping/arping)。复制旧配置忘改name/ip→ 同名域创建报错、IP 与既有虚机冲突。改完手工核一遍:bash grep -H -E 'name:|ip:|mac:' config/*.yaml | grep -v credentials # 跨批次人工比对 ping -c 2 -W 1 <拟用ip> # 预期:不通=空闲 virsh --connect qemu:///system list --all | grep <拟用name> # 预期:无输出 - 幽灵配置项:写了实现体不认的键 →
[告警] …该配置项未被引用,配置后不产生任何效果。按告警删键或先实现。 - 既无公钥又禁口令 → 阻断「主机将无任何可用的登录方式」。二者至少留一个。
- 凭据文件按批次独立:
runtime.credentials_file指哪个文件,新机口令就写进哪个文件;换新批次建议同步换新文件名(如config/credentials-flexlm.yaml),工具首次执行自动创建(0600)。 - 改
utils/kvm_utils.py(共享能力层)后:必须对全部配置各跑一次--drift回归。
6. 备份与恢复¶
本工具涉及三类"备份":
| 类型 | 何时产生 | 位置 |
|---|---|---|
| 宿主文件备份 | 配置了 host_tuning 且将改写 sysctl/KSM 单元时,阶段 3 自动 auto_backup |
与原文件同目录,<原名>.bak.<时间戳> |
| 批次变更备份 | 各批次变更时人工备份的配置/文档 | config/hosts-*/backup/、*-2026mmdd/backup/,台账见各自 backup/README.md |
| 凭据文件 | 工具生成口令时同时落盘 | config/credentials*.yaml(0600) |
手工备份配置(改配置前):
ts=$(date +%Y%m%d-%H%M%S); cp -a config/<cfg>.yaml config/<cfg>.yaml.bak.$ts # 改前备份
恢复步骤:
# 宿主参数被改坏(配了 host_tuning 时)
sudo cp -a /etc/sysctl.d/<文件>.bak.<时间戳> /etc/sysctl.d/<文件> && sudo sysctl --system # 还原并生效
# 配置改坏
cp -a config/<cfg>.yaml.bak.<时间戳> config/<cfg>.yaml
# 虚机被回滚销毁 —— 无法"恢复数据",只能重新创建:重跑该批次 --config 命令(磁盘与安装全新重建)
恢复后验证:sudo .venv/bin/python main.py --drift --config <cfg> 退出码 0。
清理:备份文件对照各 backup/README.md 台账,由用户确认后自行删除;Agent 不主动删。
7. 监控与告警¶
本工具无常驻监控;退出码就是告警信号,建议纳入定期巡检脚本。
| 入口 | 查法 |
|---|---|
| 执行日志 | logs/kvm-rocky9-deploy.log(按天切割、保留 30 份、文件级 DEBUG) |
| 日志行格式 | [时间] [模块] [LEVEL] [HOST: …] [CMD: …] [RET: …] message |
| 体检/巡检报告 | build/reports/precheck-<配置>-<时间戳>.txt、drift-<配置>-<时间戳>.txt |
| 变更计划 | build/plans/plan-<配置>-<时间戳>.yaml |
关键日志与阈值:
tail -n 50 logs/kvm-rocky9-deploy.log # 最近状态
grep -E '\[ERROR\]|阻断|失败|中止' logs/kvm-rocky9-deploy.log | tail -n 30 # 只看问题行
重点盯的信号:
| 信号 | 含义 | 动作 |
|---|---|---|
门禁未通过:N 项阻断 |
环境或配置不达标 | 按逐项 [阻断] 建议修复 |
状态探测不可用(N 项),已中止变更 |
libvirtd/存储池/网络通道故障 | 见第 8 章场景 2 |
存在未达标节点,请检查日志 |
后置校验失败(域/SSH/自启) | 见第 8 章场景 3 |
检测到并发实例(PID=x) |
进程锁冲突 | 确认无他人在跑;孤儿锁会自动清理 |
| 退出码 4/5 | 漂移/探测不完整 | 逐项看 drift 报告 |
日志排查常用级别:--log-level DEBUG 会把每条执行的命令与返回值打进日志([CMD: …] [RET: …])。
8. 故障处置¶
场景 1:--precheck 退出码 2(门禁阻断)¶
症状:命令尾行 门禁未通过:N 项阻断,终止执行,退出码 2。
诊断
sudo .venv/bin/python main.py --precheck --config <cfg> # 预期:逐项 [阻断] 名称:实测 X,期望 Y;建议 …
cat build/reports/precheck-<cfg>-<最新时间戳>.txt # 同样内容落盘,含结论
常见阻断与处置:
| 阻断项 | 处置 |
|---|---|
| 运行身份非 root | 命令前加 sudo |
/dev/kvm 缺失 |
查宿主虚拟化:ls -l /dev/kvm;BIOS 未开虚拟化则重启进 BIOS |
| 缺 virt-install/virsh/qemu-img/openssl | dnf install -y libvirt-client virt-install qemu-img openssl |
| ISO 不存在 | ls -l <target.iso>;确认 ISO 已拷到宿主 |
| 存储池未运行 | virsh pool-start <pool>(建议文案已给出) |
| kickstart 模板缺失 | 确认 templates/ks.cfg.tmpl 存在 |
| 配置 BLOCK 项 | 按字段路径改配置(如 nodes[0].ip 不是合法 IPv4) |
验证:重跑 --precheck 退出码 0。
场景 2:执行中途 状态探测不可用(N 项),已中止变更¶
症状:阶段 2(幂等状态巡检)即中止,日志 状态探测不可用(N 项),已中止变更;请先修复探测通道(如 libvirtd、存储池、网络)后重跑。这是保护:UNKNOWN 不当作"需要变更",防止误建误删。
诊断
systemctl is-active libvirtd # 预期:active
virsh --connect qemu:///system pool-list --all # 预期:目标池 State=running
virsh --connect qemu:///system list --all # 预期:正常列域
sudo .venv/bin/python main.py --drift --config <cfg> ; echo $? # 预期:退出码 5=探测失败项,报告逐条 [探测失败]
处置:按诊断结果修通道——libvirtd 挂了 systemctl restart libvirtd;池停了 virsh pool-start <pool>;网络不通查 br0 与目标 IP。
验证:--drift 不再出现 [探测失败](退出码 0 或 4),再重跑执行。
场景 3:安装或 SSH 就绪超时¶
症状:日志 <name> 在 2400s 内未完成安装,请查看 /var/log/libvirt/qemu/<name>.log,或 <name> 在 2400s 内未就绪,请用 'virsh console <name>' 查看控制台;节点标 [失败],整体 状态: failed,退出码 1。
诊断
ls -l /var/log/libvirt/qemu/<name>.log && tail -n 30 /var/log/libvirt/qemu/<name>.log # qemu 层报错
virsh --connect qemu:///system domstate <name> # 预期:running(安装中)或 shut off
virsh --connect qemu:///system console <name> # 进控制台看安装进度/报错,退出 Ctrl+]
ping -c 2 -W 1 <节点ip> # 网络层是否已通
处置:
- 控制台显示安装报错(kickstart 失败、磁盘错误)→ 修配置或模板后,先清理残局再重跑:
bash # 高危:销毁半成品域与磁盘(确认不再需要后执行) sudo .venv/bin/python main.py --rollback --force --config <cfg> sudo .venv/bin/python main.py --config <cfg> # 重新创建 - 提示
<name> 仍在以安装期定义运行(该定义会重新进入安装器)→ 按提示virsh destroy <name>后重跑。 - 装完了但 SSH 不通 → 查虚机内网络:控制台里
ip a确认拿到配置的静态 IP。
验证:末行 状态: success,--drift 退出码 0,ssh -i <私钥> root@<ip> 'hostname' 返回主机名。
场景 4:SSH 登录被拒¶
症状:ssh root@<ip> 报 Permission denied (publickey)。
诊断
ls -l /home/rain/.ssh/id_ed25519.pub # 公钥存在
grep -A3 '^ssh:' config/<cfg>.yaml # pubkey_file 指向、disable_password_auth
sudo cat config/credentials-<批次>.yaml # 口令兜底(0600,需 root)
处置:确认配置的 pubkey_file 与你本地私钥配对;不符则改配置后对该机重跑创建(公钥注入在供给阶段)。仅公钥登录是既定安全策略,不要改回口令登录。
验证:ssh -i /home/rain/.ssh/id_ed25519 root@<ip> 'hostname' 成功。
场景 5:回滚取消或失败¶
症状:[已取消] 未执行回滚(退出码 1)——非交互环境忘了 --force,加上即可;或 【高危】域名探测失败,跳过以免误操作——故意不删,防误销毁。
诊断/处置:virsh --connect qemu:///system list --all 人工确认域状态;探测通道恢复后重跑。任何"跳过"都意味着对应虚机仍存在,不要手工强删,回到诊断流程。
验证:重跑 --dry-run --rollback,清单符合预期后再真实执行。
场景 6:命令刚启动就 Traceback(PermissionError,漏加 sudo)¶
症状:任意模式(--precheck / --drift / --rollback …)一执行就抛 Traceback,栈尾停在 python3.12/logging/handlers.py 的 open(),报 PermissionError: [Errno 13] Permission denied。
根因:命令漏加 sudo。logs/ 目录与日志文件由历次 sudo 运行创建,属主为 root,普通用户打不开日志文件——程序在 log_manager.setup_all() 阶段(业务逻辑之前)即退出。
诊断
ls -ld logs; ls -l logs/kvm-centos7-deploy.log # 预期属主 root:root
处置:命令前补 sudo 重跑。
关键判据:输出中没有任何 【高危】 / [dry-run] 行 → 尚未进入业务逻辑,属无害失败,不存在「半执行」中间态(回滚没跑、虚机仍在),补 sudo 即可,无需任何清理。
验证:重跑后应看到正常日志头(初始化模块: kvm_rocky9_deploy)或 【高危】 横幅。
9. 安全与权限¶
- 执行权限:全部模式需 root(门禁第一项);工程不改
/etc/sudoers,不静默提权。 - 虚机登录:默认仅公钥登录、禁用口令认证(
ssh.disable_password_auth: true);公钥取自宿主 rain 用户。 - 凭据:
config/credentials*.yaml含明文 root 口令(0600,gitignore 规则config/credentials*.yaml),禁止提交或外传;文档、日志、对话中只写"从哪里取",不写口令本身。 - 高危动作:
--rollback销毁虚机与磁盘不可恢复,需--force或交互输入YES;--force只做确认,不跳过任何校验(main.py:16-18)。 - 不碰的边界:不重启宿主、不改
br0/物理网卡/netplan;宿主上有调度作业(Slurm/LSF)时不在该节点做变更动作;未配host_tuning时不触碰宿主内核参数与 KSM。 - 日志脱敏:凭据/口令类信息落盘或贴出前打码;执行日志本身不含口令(口令只进 credentials 文件)。
10. 容量与性能¶
当前水位基线(2026-09-25):
| 项 | 基线 |
|---|---|
| 宿主内存 | 117 GiB total;20 台虚机在跑(气球 + 稀疏分配兜底)【已确认】 |
| 在跑域 | openwrt 1、k8s 4、slurm 5、lustre 2、lsf 5、rocky9-01 1(另 k8s-master-02/03 shut off) |
| 存储池 | hdd-pool(系统盘)、ssd-pool(数据盘)、iso,均 active;系统盘稀疏 qcow2 |
| 单台典型规格 | 2–8 vCPU / 2–4 GiB / 20–50 GiB 系统盘 |
IP / MAC 段分配(第五字节 / 末段):
| 批次 | MAC 第五字节 | IP 段 |
|---|---|---|
| k8s | 0a |
.10–15 |
| slurm | 0b |
.16–20 |
| lustre | 0c |
.21–22 |
| lsf | 0d |
.23–27 |
| rocky9 | 0e |
.28(0e:01 已用) |
| flexlm(规划) | 0e 起顺延(0e:02 可用) |
.29 起顺延(.29 ping 空闲【已确认】;未核 DHCP 池) |
扩容触发条件与操作:
- 段内 IP 耗尽 → 在上表开新段,改配置
nodes即可(工具无全局 IP 注册表,段规划靠本表人工维护)。 - 宿主内存/磁盘吃紧 → 虚机规格只在创建时定义,扩容=回滚重建或另立批次;先
virsh dominfo <name>与df -h看水位。
已知瓶颈:安装串行等待(install_max_concurrent 控制并发,默认 1,单台约 10–15 分钟);系统盘落 hdd-pool(HDD)IO 偏慢,IO 敏感批次考虑放 ssd-pool(配置 storage.system_pool 或数据盘 pool)。
11. 附录¶
A. 退出码表¶
| 码 | 含义 |
|---|---|
| 0 | 成功 / 无漂移 / 预检查无阻断(含仅告警;skipped 也算 0) |
| 1 | 部署或回滚失败(含回滚确认被取消) |
| 2 | 参数用法错误(argparse)或 --precheck 有阻断项(同码两义,看输出区分) |
| 3 | 配置文件缺失 |
| 4 | --drift 检测到漂移 |
| 5 | --drift 存在探测失败项,结论不完整 |
B. 执行阶段(真实执行时的日志顺序)¶
进程锁 → 阶段0 初始化(配置解析完成…)→ 阶段1 门禁(门禁检查:共 N 项…)→ 阶段2 幂等状态巡检(状态巡检:发现 N 项待变更,计划落 build/plans/)→ 阶段3 前置备份(仅 host_tuning)→ 阶段4 核心变更([开始] 供给 <name> → 安装 → [完成] <name>)→ 阶段5 后置校验(节点校验结果:…)→ 收尾摘要(状态: … | 成功: … | 失败: …)。
短路规则:门禁失败不进阶段2-5;探测 UNKNOWN 在阶段2中止;变更失败不进阶段5。
C. 三态探测语义¶
ProbeState(DONE/PENDING/UNKNOWN)(utils/kvm_utils.py:29-41):DONE=已达标(幂等跳过);PENDING=确需变更(执行);UNKNOWN=探测不到(一律中止变更或阻断,绝不折平为"需要变更")。SSH 探测是纯 TCP connect(非 SSH 协议):连通=DONE,拒绝=PENDING,超时/不可达=UNKNOWN。
D. 相关文档¶
| 文档 | 管什么 |
|---|---|
docs/HANDOFF.md |
交接快照:当前状态与下一步 |
rocky9-20260925/SOP.md |
rocky9-01 创建变更档案 |
lsf-20260924/SOP.md |
LSF 批次变更档案(CLI 最全,历史文档 CLI 漂移以其为准) |
docs/SOP.md、docs/SOP-hosts-20260918.md |
k8s/slurm 旧 SOP(CLI 已过时,--rollback 现需 --force) |
config/deploy.yaml.example |
配置模板 |
各批次 backup/README.md |
备份台账 |
E. 修订记录¶
| 日期 | 修改人 | 内容 |
|---|---|---|
| 2026-09-25 | (本次) | 首版:按 writing-ops-change-sop 技能 RUNBOOK 11 章产出,事实取自实现体行号 |
| 2026-09-28 | (本次) | 新增第 12 章 CentOS 7 批次;速查表与 5.1 配置清单各补一行 |
12. CentOS 7 批次(main_centos7.py)¶
用途:按需创建 CentOS 7 临时测试机。与 Rocky 9 批次共用同一套生命周期与子命令,只是入口、模板与 SSH 加固写法不同;完整变更档案见 centos7-20260928/SOP.md。
| 项 | Rocky 9 批次 | CentOS 7 批次 |
|---|---|---|
| 入口 | main.py |
main_centos7.py |
| 实现体 | deployer.py(类 KvmRocky9Deployer) |
deployer_centos7.py(继承前者,只覆盖模板目录与 SSH 加固片段) |
| 模板 | templates/ks.cfg.tmpl |
templates/centos7/ks.cfg.tmpl |
| 日志 | logs/kvm-rocky9-deploy.log |
logs/kvm-centos7-deploy.log |
| 配置 | 各批次既有配置 | config/hosts-20260928-centos7.yaml |
| 进程锁 | logs/kvm_rocky9_deploy.lock |
同左(两批次共用,不能并发执行) |
命令:把第 3 章速查表里的 main.py 换成 main_centos7.py、<cfg> 换成 config/hosts-20260928-centos7.yaml 即可,参数、退出码、三态语义完全一致。
与 Rocky 9 的三处关键差异(换镜像或改配置前务必先读)
vm_defaults.osinfo必须填centos7(libosinfo 条目名);误填rocky9会让virt-install按 RHEL9 假设建机。- SSH 加固写在
/etc/ssh/sshd_config末尾,不用sshd_config.d/:CentOS 7 系的 sshd 默认不加载该目录,写片段会被整体忽略(口令登录静默保持可用)。片段会先sed删除同名旧项再追加——sshd 对同名项「首次匹配生效」,CentOS 7 默认文件里的PasswordAuthentication yes是未注释行,直接追加会被它压住。 - 老版本 OpenSSH 取值:CentOS 7.1 自带 6.6.1,
PermitRootLogin禁口令取值必须是without-password;写prohibit-password(7.0 起)会让 sshd 直接启动失败(code=exited, status=255循环重启)。
故障处置(CentOS 7 批次专属)
-
症状:安装完成但 SSH 永不可达(探测一直 unknown) 诊断:宿主侧看网卡收发,
tx_packets 0即 guest 网卡未启用(anaconda 未落实 network 行):bash sudo virsh --connect qemu:///system domiflist centos7-01 # 取 vnetN sudo virsh --connect qemu:///system domifstat centos7-01 vnet61 # 预期 rx 有值、tx 非 0 ip neigh | grep 192.168.31.30 # 预期 REACHABLE,而非 INCOMPLETE处置:确认用的是最新templates/centos7/ks.cfg.tmpl(其%post含按实际网卡名补写 ifcfg 的兜底);仍失败则按下方串口手法进 guest 查/etc/sysconfig/network-scripts/ifcfg-*。 -
症状:ping 通、SSH 端口
connection refused(探测长期 pending) 含义:guest 网络正常但 sshd 未监听。诊断(串口):bash PTY=$(sudo virsh ttyconsole centos7-01) timeout 30 sudo cat "$PTY" & # 读取回显到终端 printf 'root\n' | sudo tee "$PTY" # 登录(口令见 config/credentials-centos7.yaml) printf 'sshd -t; systemctl status sshd --no-pager | head -12\n' | sudo tee "$PTY"预期:sshd -t无输出、退出码 0;Active: active (running)。 失败判断:unsupported option …→ 配置取值与该 OpenSSH 版本不符,修正deployer_centos7.py的_password_auth_post_block后先回滚再重跑。 -
症状:SSH 能登但怀疑口令认证没关 诊断:
ssh -i <key> root@192.168.31.30 "sshd -T | grep ^passwordauthentication",预期passwordauthentication no(以sshd -T的实际生效值为准,不要只看配置文件末尾)。
串口登录手法(
virsh console需要 TTY,故用 pty 直读直写)同样适用于 Rocky 9 批次:把域名与凭据文件换掉即可。
来源:
/home/rain/Documents/kvm/kvm_rocky9_deploy/runbook-20260925/RUNBOOK.md| 最后更新:2026-10-01 02:58(由build/sync.py同步,请勿在站点侧修改)