跳转至

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-pool active 且有充足可用空间(本次执行前实测 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)的差异有三处,均为本次需求决定:

  1. storage.data_pool: hdd-pool —— 数据盘落 HDD;
  2. vm_defaults.data_disk_format: qcow2 —— 默认是 raw,raw 会按名义容量预占 200 GiB,改 qcow2 后稀疏、按需增长;
  3. 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. 回滚

回滚分三层,互不依赖。

  1. 销毁虚机与磁盘(清掉本次运行时交付物,不可恢复):
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,虚机内数据一并丢失,执行前须确认无需保留。

  1. 撤销本次新增文件(无既有文件被修改,删除即可):
rm -f config/hosts-20261001-harbor.yaml config/credentials-harbor.yaml
  1. 文档回退: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 本体不在本工程范围内,需另行完成(属独立变更):

  1. 装容器运行时(Docker Engine 或 Podman);
  2. 下载 Harbor 在线安装器并部署(默认 4C/8G 起步;学习环境可关 Trivy);
  3. 配置 HTTPS(自签证书)或 http 访问,并在各 k8s 节点配置 insecure-registry / 受信 CA;
  4. 宿主机与各节点的 Docker/containerd 客户端信任该仓库。

来源:/home/rain/Documents/kvm/kvm_rocky9_deploy/harbor-20261001/SOP.md | 最后更新:2026-10-01 02:58(由 build/sync.py 同步,请勿在站点侧修改)