SOP — 新增 harbor 节点(harbor-01,学习测试用镜像仓库)¶
- 主题目录:
harbor-20261001/ - 执行日期:2026-10-01
- 入口:
main.py(Rocky 9,未新增代码) - 配置:
config/hosts-20261001-harbor.yaml
1. 背景¶
需要一台私有镜像仓库节点,供自建 k8s 集群拉取镜像,用于学习测试:镜像数量少、并发低。要求数据盘落在宿主 HDD(hdd-pool),以复用容量而非占用 SSD 池。
本工程既有能力(main.py + deployer.py + Rocky 9 kickstart 模板)已支持"单系统盘 + 数据盘(可指定池、格式、挂载点)",因此本次不改任何实现体代码,只新增一份配置并执行建机。
2. 目标(可验证)¶
| 项 | 目标值 |
|---|---|
| 主机名 / IP / MAC | harbor-01 / 192.168.31.31 / 52:54:00:31:0f:01 |
| 规格 | 4 vCPU / 8192 MiB 内存 |
| 磁盘 | 系统盘 50 GiB qcow2(hdd-pool);数据盘 200 GiB qcow2(hdd-pool)挂载 /data |
| 状态 | 域 running、autostart=enable、persistent=yes |
| 登录 | 仅公钥(rain 的 id_ed25519),口令认证禁用 |
| 幂等 | 复跑输出 状态: skipped、零变更 |
| 与本项目其他批次 | 互不影响(体检/巡检/回滚只作用于本配置列出的主机) |
3. 前置条件¶
- 执行身份:root(必须
sudo)。漏sudo会在日志初始化阶段报PermissionError,见 RUNBOOK 第 8 章场景 6。 - 宿主:
dell-R620,hdd-poolactive 且有充足可用空间(本次执行前实测 1.20 TiB 可用)。 - 依赖命令:
virt-install、virsh、qemu-img、openssl(门禁会自动核验)。 - ISO:
/data/kvm/iso/Rocky-9-latest-x86_64-dvd.iso(宿主 CPU 仅支持 x86-64-v2,须用 Rocky 9)。 - 公钥:
/home/rain/.ssh/id_ed25519.pub。 - 地址空闲确认:
192.168.31.31执行前 ping 无应答;MAC 段0f未被占用(既有占用到0e)。 - 进程锁:与其他批次共用
logs/kvm_rocky9_deploy.lock,不可与其他批次并发执行。
4. 影响范围¶
- 新增 1 台虚机
harbor-01与其两块卷;不影响既有 20 台在跑域。 - 不需停服:纯新增,不重启宿主、不改
br0/物理网卡/netplan。 - 资源占用:4 vCPU、8 GiB 内存(宿主 117 GiB total,执行后可用约 22 GiB);卷为稀疏,实测实占 2.3 GiB + 3.0 MiB。
- 窗口期:无人值守安装实测 812.79s(约 13.5 分钟),期间宿主 IO 有负载,不建议同时跑其他重 IO 任务。
- 宿主上若有 Slurm/LSF 作业在跑,按红线不得动该节点;本次仅新增域,不触及既有域。
5. 分步操作¶
步骤 1:新增批次配置¶
按 config/deploy.yaml.example 的字段约定新写一份配置。与既有单台批次(rocky9/flexlm)的差异有三处,均为本次需求决定:
storage.data_pool: hdd-pool—— 数据盘落 HDD;vm_defaults.data_disk_format: qcow2—— 默认是raw,raw 会按名义容量预占 200 GiB,改 qcow2 后稀疏、按需增长;nodes[0].data_disks指定format/pool/mount,并显式写mount: /data,否则只建盘不挂载。
grep -nE "system_pool|data_pool|data_disk_format|name:|ip:|mac:|vcpu:|memory_mib:|system_disk_gib:|size_gib:|mount:" \
config/hosts-20261001-harbor.yaml
预期:system_pool: hdd-pool、data_pool: hdd-pool、data_disk_format: qcow2、harbor-01/192.168.31.31/52:54:00:31:0f:01/4/8192/50/200//data。
失败判断:字段缺失 → 门禁或配置解析阶段报 DeployError(退出码 2),按提示补字段。
注意事项与坑
role: registry仅作日志标识,不驱动任何行为。- 卷名规则为
<主机名>-<suffix>.<格式>,故数据盘卷名固定为harbor-01-data.qcow2;改suffix会改名并触发重建,勿轻改。 - 数据盘
mount由 kickstart 的%post用 xfs 格式化并写入/etc/fstab(defaults,noatime),实现体见 deployer.py 的_data_disk_post_block。
步骤 2:门禁体检(只读)¶
sudo .venv/bin/python main.py --precheck --config config/hosts-20261001-harbor.yaml
预期:预检查通过:全部检查项达标,退出码 0(本次实测 10 项全通过)。
失败判断:退出码 2 且有 [阻断] → 按逐项建议修复后重跑;有阻断时不得继续。
步骤 3:漂移体检(只读)¶
sudo .venv/bin/python main.py --drift --config config/hosts-20261001-harbor.yaml
预期(建机前):待变更 3 项——hdd-pool/harbor-01.qcow2、hdd-pool/harbor-01-data.qcow2、域 harbor-01;退出码非 0(有漂移属正常语义)。
步骤 4:预演(零系统改动)¶
sudo .venv/bin/python main.py --dry-run --config config/hosts-20261001-harbor.yaml
预期:状态巡检:发现 3 项待变更,逐条 [dry-run] 将执行变更: …,计划写入 build/plans/plan-hosts-20261001-harbor-<时间戳>.yaml。
实测零改动验证:预演前后各跑一次 --drift,两次结论一致(同为 3 项待变更),证明预演未落任何变更。
步骤 5:真实创建¶
sudo .venv/bin/python main.py --config config/hosts-20261001-harbor.yaml
预期:状态: success,总主机数: 1 | 成功: 1 | 失败: 0 | 跳过: 0;本次实测 耗时: 812.79s。日志 logs/kvm-rocky9-deploy.log。
失败判断:末行非 success → 「等待安装完成」超时多为 kickstart 被 anaconda 拒绝;「等待就绪」超时(pending=端口未监听 / unknown=不可达)按日志定位后转第 7 章回滚重来。
底层等价命令(实现体内部执行,供复核;实现体:deployer.py _ensure_volumes / _create_domain):
# ① 建卷(稀疏)
sudo virsh --connect qemu:///system vol-create-as hdd-pool harbor-01.qcow2 50G --format qcow2
sudo virsh --connect qemu:///system vol-create-as hdd-pool harbor-01-data.qcow2 200G --format qcow2
# ② 渲染 kickstart 到 build/harbor-01/ks.cfg(含静态网络、公钥、禁口令、数据盘挂载、关 swap)
# ③ 无人值守安装(kickstart 以 poweroff 收尾)
sudo virt-install --connect qemu:///system --name harbor-01 \
--memory 8192 --vcpus 4 --cpu host-passthrough --machine pc --osinfo name=rocky9 \
--disk path=/data/kvm/img/harbor-01.qcow2,format=qcow2,bus=virtio,cache=none,io=native,discard=unmap \
--disk path=/data/kvm/img/harbor-01-data.qcow2,format=qcow2,bus=virtio,cache=none,io=native \
--network bridge=br0,mac=52:54:00:31:0f:01,model=virtio \
--location /data/kvm/iso/Rocky-9-latest-x86_64-dvd.iso \
--extra-args "inst.ks=file:/ks.cfg inst.text console=tty0 console=ttyS0,115200n8" \
--initrd-inject build/harbor-01/ks.cfg --graphics none --console pty,target_type=serial \
--memballoon model=virtio --noautoconsole --autostart
# ④ 安装结束域转 shut off → 实现体固化域定义(去 direct-boot、注入气球策略)后启动
步骤 6:幂等复跑¶
sudo .venv/bin/python main.py --config config/hosts-20261001-harbor.yaml
预期:状态: skipped、状态巡检:全部项已达标,无需变更、计划 0 项。本次实测符合。
6. 验证(含实测值)¶
sudo virsh --connect qemu:///system dominfo harbor-01 | grep -Ei "name|state|CPU|memory|autostart|persistent"
sudo virsh --connect qemu:///system domblklist harbor-01
ssh -o BatchMode=yes root@192.168.31.31 \
'hostname; nproc; free -h | sed -n 2p; df -h / /data; findmnt -no SOURCE,FSTYPE,OPTIONS /data; \
systemctl is-active sshd chronyd; swapon --show | wc -l'
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@192.168.31.31 true
sudo .venv/bin/python main.py --drift --config config/hosts-20261001-harbor.yaml
| 检查项 | 预期 | 本次实测 |
|---|---|---|
| 域状态 | running / autostart / persistent | State: running、Autostart: enable、Persistent: yes |
| 规格 | 4 vCPU / 8192 MiB | CPU(s): 4、Max memory: 8388608 KiB |
| 磁盘 | vda 50G 系统盘 + vdb 200G 数据盘 | vda /data/kvm/img/harbor-01.qcow2、vdb /data/kvm/img/harbor-01-data.qcow2 |
| 卷实占(稀疏) | 远小于名义容量 | 系统盘 2.3G、数据盘 3.0M |
| 系统内规格 | 4 核 / 7.5 GiB 可见 | CPU核数: 4、Mem: 7.5Gi |
/data 挂载 |
/dev/vdb xfs,noatime |
/dev/vdb 200G 1.5G 199G 1% /data,xfs rw,noatime,... |
| 分区布局 | /boot + / 在系统盘 |
vda1 1G /boot、vda2 49G / |
| 服务 | sshd / chronyd active | 均 active |
| swap | 已关闭 | swapon 0 行 |
| 口令登录 | 已禁用 | Permission denied (publickey,...),无 password |
| 漂移 | 0 项、退出码 0 | 待变更 0 项,探测失败 0 项 |
| 幂等复跑 | 全跳过、零变更 | 状态: skipped |
| 其他批次回归 | 未受影响 | 未改动实现体;既有配置单独执行互不影响 |
7. 回滚¶
回滚分三层,互不依赖。
- 销毁虚机与磁盘(清掉本次运行时交付物,不可恢复):
sudo .venv/bin/python main.py --dry-run --rollback --config config/hosts-20261001-harbor.yaml # 预演:只列清单
sudo .venv/bin/python main.py --rollback --force --config config/hosts-20261001-harbor.yaml # 高危:真实销毁
预期:【高危】… 横幅 → 已销毁域与磁盘:harbor-01 → 回滚完成;virsh list --all | grep harbor 无输出,hdd-pool 卷列表无 harbor-01*.qcow2。
高危提示:该命令会同时删除 harbor-01.qcow2 与 harbor-01-data.qcow2,虚机内数据一并丢失,执行前须确认无需保留。
- 撤销本次新增文件(无既有文件被修改,删除即可):
rm -f config/hosts-20261001-harbor.yaml config/credentials-harbor.yaml
- 文档回退:
runbook-20260925/RUNBOOK.md与docs/HANDOFF.md的本次改动,用备份覆盖回去。
cp harbor-20261001/backup/runbook-20260925/RUNBOOK.md.bak.20261001-025742 runbook-20260925/RUNBOOK.md
cp harbor-20261001/backup/docs/HANDOFF.md.bak.20261001-025742 docs/HANDOFF.md
备份位置:harbor-20261001/backup/,逐条登记见 backup/README.md。本次配置与工作产物均为新增,仅上述两份文档被改动,故只备份这两份。
回滚后验证:sudo .venv/bin/python main.py --drift --config config/hosts-20260925-rocky9.yaml 应仍为 0 项(确认未伤及既有批次);virsh list --all 中不应残留 harbor-01。
8. 风险说明¶
| 风险 | 缓解 |
|---|---|
| HDD 是 registry 的性能瓶颈:镜像层解压、校验、推送为 IO 密集,推拉大镜像明显偏慢 | 定位为学习测试、镜像少;若后续提速,把数据盘改到 ssd-pool 重建即可(改 data_disks[0].pool) |
--rollback 不可恢复(连磁盘一起删) |
需 --force 或交互确认;执行前先 --dry-run --rollback 看清单 |
数据盘若误用默认 raw,会在 HDD 池预占 200 GiB |
本配置已显式写 format: qcow2;换批次时勿照抄 deploy.yaml.example 的默认值 |
| 8 GiB 内存对 Harbor 全组件(含 Trivy 扫描)偏紧 | 学习测试可关 Trivy 或限制其并发;若跑满再上调 memory_mib(宿主仍有约 22 GiB 余量) |
| 镜像仓库是集群拉取的单点 | 本机为学习测试,不承接生产;生产需 HA 与持久化后端另行设计 |
| 宿主内存持续性下降 | 已启用气球 deflate_on_oom;卷稀疏,实际占用随使用增长 |
| 本批次与既有批次共用进程锁 | 不可与其他批次并发执行(刻意保护) |
附录 A:交付物清单¶
| 文件 | 性质 | 说明 |
|---|---|---|
config/hosts-20261001-harbor.yaml |
新增 | 本次批次配置 |
config/credentials-harbor.yaml |
工具生成 | 随机 root 口令,0600,已 gitignore |
build/harbor-01/ks.cfg、build/harbor-01/domain.xml |
工具生成 | 渲染后的 kickstart 与固化域定义 |
build/plans/plan-hosts-20261001-harbor-*.yaml |
工具生成 | 变更计划 |
build/reports/precheck-hosts-20261001-harbor-*.txt、drift-hosts-20261001-harbor-*.txt |
工具生成 | 体检与漂移报告 |
harbor-20261001/SOP.md |
本文件 | 变更档案 |
harbor-20261001/backup/ |
备份 | 两份被改文档的改前版本 + 台账 |
附录 B:范围外事项¶
本次只交付基础系统。Harbor 本体不在本工程范围内,需另行完成(属独立变更):
- 装容器运行时(Docker Engine 或 Podman);
- 下载 Harbor 在线安装器并部署(默认
4C/8G起步;学习环境可关 Trivy); - 配置 HTTPS(自签证书)或 http 访问,并在各 k8s 节点配置
insecure-registry/ 受信 CA; - 宿主机与各节点的 Docker/containerd 客户端信任该仓库。
来源:
/home/rain/Documents/kvm/kvm_rocky9_deploy/harbor-20261001/SOP.md| 最后更新:2026-10-01 02:58(由build/sync.py同步,请勿在站点侧修改)