在多磁盘裸金属主机上选择固定系统磁盘

当同一个 SeedImage ISO 必须在多个裸金属主机之间复用,并且每台主机都有多个磁盘时,请使用本指南。该操作步骤可防止 Elemental 在每次启动时自动选择不同的磁盘,并允许 operator 根据每台主机稳定的 WWN 选择系统磁盘。

为什么需要手动磁盘门控

不要在多磁盘主机上将 MachineRegistration.spec.config.elemental.install.device 留空。空的 device 和空的 device-selector 并不会让 Elemental 等待 operator 选择磁盘。多个已发现的磁盘可能都会匹配,其中一个会在不执行唯一性检查的情况下被选中。

也不要使用 /dev/sda 作为持久磁盘标识。存储控制器的发现顺序可能会在 Live ISO 和已安装系统之间发生变化,因此同一个逻辑磁盘在一次启动时可能显示为 /dev/sda,而在另一次启动时则显示为 /dev/sdb

本指南使用一种“失败即关闭”的手动门控:

  1. 每个可复用的 ISO 都包含相同的、最初并不存在的安装路径:/dev/elemental-install-target
  2. 在该路径不存在时,安装服务无法继续,而且不会回退到自动磁盘选择。
  3. 在每台主机上,operator 通过 /dev/disk/by-id/wwn-* 识别目标整盘,并将该门控创建为指向该磁盘的符号链接。
  4. 只有在磁盘、网络、挂载和过期标签检查全部通过后,operator 才启动安装服务。
WARNING

本指南中的清理操作会永久销毁数据。仅可在 Live ISO 控制台中运行,仅可在已批准重新安装的磁盘上运行,并且只有在确认这些磁盘都未挂载之后才能运行。

前提条件

  • 裸金属 provider 和 elemental-operator 已安装在 global 集群上。
  • 你可以在 cpaas-system 中创建或编辑 MachineRegistrationSeedImage 资源。
  • 你可以通过 BMC、iDRAC、iLO 或同等接口访问每台主机的控制台。
  • 每个预期的系统磁盘都有稳定的 /dev/disk/by-id/wwn-* 条目。
  • 你知道哪些磁盘可以擦除。如果主机包含必须保留的数据磁盘,请将其从所有清理命令中排除。
  • 如果 Live ISO 网络没有 DHCP 服务,你需要准备好主机 IP 地址、前缀、网关、DNS 服务器和 Global registration URL。

有关完整的 provider 和集群创建工作流,请参见 在裸金属上创建集群

配置共享的 MachineRegistration

将安装设备设置为 /dev/elemental-install-target。不要为此工作流配置 device-selector

MachineRegistration install settings
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
  name: <cluster-name>-registration
  namespace: cpaas-system
spec:
  machineName: "<cluster-name>-${System Information/UUID}"
  config:
    elemental:
      install:
        device: /dev/elemental-install-target
        eject-cd: true
        reboot: true
        snapshotter:
          type: btrfs
          maxSnaps: 4
      registration:
        auth: tpm
        # Use hardware TPM when available. For hosts without TPM, enable
        # emulation and derive a unique identity for every host.
        emulate-tpm: true
        emulated-tpm-seed: -1

当 Live ISO 启动时,该路径有意不存在。文件系统标签、GPT PARTLABEL/dev/disk/by-label/* 路径都不是替代方案:这些标识的是分区,而 Elemental 需要的是整盘安装目标。

创建一个引用此 MachineRegistration 的 SeedImage,或者在更改安装设备后重新构建现有的 SeedImage。

WARNING

MachineRegistration 设置会嵌入到生成的 ISO 中。仅修补 MachineRegistration 不会更改已经构建并下载的 ISO。请重新构建 SeedImage,等待其就绪,下载新的 ISO,并在从其启动主机之前验证其校验和。

准备每台主机

一次只对一台主机执行以下步骤。在需要进行磁盘清理时,不要并行准备多台主机。

1. 启动预期的 Live ISO 并阻止自动安装

从共享 ISO 启动主机。一旦 Live ISO 控制台可用,立即停止并屏蔽自动安装程序:

systemctl stop elemental-register-install.service
systemctl mask elemental-register-install.service
systemctl reset-failed elemental-register-install.service

确认 ISO 中包含手动门控:

grep -n -C 3 '/dev/elemental-install-target' \
  /run/initramfs/live/livecd-cloud-config.yaml

如果该路径不存在,说明主机没有启动预期的 ISO。不要继续。

2. 确认主机正在 Live ISO 中运行

findmnt -n -o SOURCE,FSTYPE,TARGET /
findmnt /run/initramfs/live
lsblk -e7 -o NAME,PATH,TYPE,SIZE,MODEL,SERIAL,WWN,FSTYPE,LABEL,MOUNTPOINTS

确认以下所有内容:

  • / 是 Live root,例如 LiveOS_rootfs
  • 虚拟 CD 设备,通常是 /dev/sr0,带有 COS_LIVE 标签。
  • 你计划清理或用作安装目标的任何磁盘都没有挂载。

检查物理磁盘、device-mapper、swap、LVM 和 multipath 的使用情况:

findmnt -rn -o SOURCE,TARGET | grep -E '^/dev/(sd|mapper/)' || \
  echo NO_PHYSICAL_DISK_MOUNTS
swapon --show
pvs 2>/dev/null || true
vgs 2>/dev/null || true
multipath -ll 2>/dev/null || true

如果目标磁盘已挂载,或者你无法证明根文件系统属于 Live ISO,则停止。

3. 在 DHCP 不可用时配置 Live ISO 网络

首先识别实际的 NetworkManager 连接和接口。不要假设连接名称总是 Wired connection 1

nmcli device status
nmcli connection show
ip -br link

使用分配给此主机的值配置所选连接:

nmcli connection modify "Wired connection 1" \
  ipv4.method manual \
  ipv4.addresses 192.168.254.76/24 \
  ipv4.gateway 192.168.254.1 \
  ipv4.dns 192.168.16.19 \
  ipv4.ignore-auto-dns yes

nmcli connection up "Wired connection 1"

验证地址、默认路由、DNS 解析以及完整的 registration URL:

ip -br addr
ip route
cat /etc/resolv.conf
ping -c 2 -W 2 192.168.254.1
getent hosts <global-domain>
curl -ksS --connect-timeout 10 \
  -o /dev/null -w 'REG_HTTP=%{http_code}\n' \
  'https://<global-domain>/<registration-path-and-token>'

请使用站点特定的网络值,而不是复制示例地址。请将完整的 registration URL 和 token 保持在源代码管理和共享日志之外。

此网络配置仅用于将 Live ISO 连接到注册和初始安装流程。它不会替代在 Cluster API 重新预配期间应用于已安装系统的持久网络配置。

4. 识别所有磁盘和目标系统磁盘

再次列出稳定的磁盘属性:

lsblk -d -e7 -o NAME,PATH,TYPE,SIZE,MODEL,SERIAL,WWN,HCTL

for current_disk in /dev/sda /dev/sdb /dev/sdc /dev/sdd; do
  echo "=== ${current_disk} ==="
  udevadm info -q symlink -n "${current_disk}" | tr ' ' '\n' |
    grep -E 'disk/by-id/(wwn|scsi)-' || true
done

根据当前主机调整磁盘列表。记录并交叉核对:

  • 当前 kernel 设备名。
  • 大小、型号、序列号和控制器地址(HCTL)。
  • /dev/disk/by-id/wwn-* 路径。
  • 哪个整盘被批准作为系统磁盘。

使用 WWN 以及大小、型号和控制器信息来做出决定。不要仅根据 kernel 名称或容量选择磁盘。

5. 在重新安装主机时移除过期的 Elemental 标签

对于必须保留数据的磁盘,跳过破坏性清理。对主机执行完整重新安装时,请在清理已批准磁盘之前移除旧映射:

swapoff -a
vgchange -an 2>/dev/null || true
systemctl stop multipathd.service multipathd.socket 2>/dev/null || true
systemctl mask multipathd.service multipathd.socket 2>/dev/null || true
multipath -F 2>/dev/null || true
udevadm settle

如果主机有无关的 LVM、multipath 或共享存储设备,不要使用全局停用命令。只停用属于已批准磁盘的映射。

对于每个已批准磁盘,清除其 GPT、已识别签名以及磁盘起始和末尾的元数据。下面的示例针对 /dev/sda;仅对你已独立识别并批准的每个磁盘重复执行。

disk_to_wipe=/dev/sda

lsblk -d -o NAME,PATH,SIZE,MODEL,SERIAL,WWN,HCTL "${disk_to_wipe}"
sgdisk --zap-all "${disk_to_wipe}"
wipefs -a -f "${disk_to_wipe}"
dd if=/dev/zero of="${disk_to_wipe}" \
  bs=1M count=64 conv=fsync status=progress

disk_sectors=$(blockdev --getsz "${disk_to_wipe}")
if [ "${disk_sectors}" -le 262144 ]; then
  echo 'REFUSE: disk is too small; stop and recheck the target'
else
  dd if=/dev/zero of="${disk_to_wipe}" bs=512 \
    seek=$((disk_sectors-131072)) count=131072 \
    conv=fsync status=progress
fi

在所有已批准磁盘清理完成后刷新 kernel 和 udev:

partprobe /dev/sda /dev/sdb /dev/sdc /dev/sdd 2>/dev/null || true
udevadm trigger --subsystem-match=block
udevadm settle

调整 partprobe 列表,仅包含在此主机上清理过的磁盘。

验证已清理磁盘没有签名、分区、文件系统类型、标签或分区标签:

wipefs /dev/sda /dev/sdb /dev/sdc /dev/sdd
lsblk -e7 -o \
NAME,PATH,TYPE,SIZE,MODEL,SERIAL,WWN,FSTYPE,LABEL,PARTLABEL,MOUNTPOINTS

if blkid /dev/sda /dev/sdb /dev/sdc /dev/sdd 2>/dev/null |
  grep -E 'LABEL="(OLD_)?COS_(GRUB|OEM|RECOVERY|STATE|PERSISTENT)"'; then
  echo COS_LABELS_REMAIN
else
  echo NO_COS_LABELS
fi

调整每个设备列表以匹配已清理的磁盘。仅在以下条件满足时继续:

  • wipefs 不会为任何已清理磁盘打印签名。
  • lsblk 不会显示旧的子分区、FSTYPELABELPARTLABEL
  • 检查会打印 NO_COS_LABELS
  • 唯一剩余的 COS_LIVE 标签属于虚拟 CD 设备,而不是系统磁盘。

6. 创建每台主机的安装目标

在清理完成后,再次列出稳定的 WWN 路径:

ls -l /dev/disk/by-id/wwn-*
lsblk -d -e7 -o NAME,PATH,SIZE,MODEL,SERIAL,WWN,HCTL

只有在选择并验证了目标整盘之后,才创建门控。将示例 WWN 替换为为此主机记录的值:

test ! -e /dev/elemental-install-target
test ! -L /dev/elemental-install-target

ln -s \
  /dev/disk/by-id/wwn-0x0123456789abcdef \
  /dev/elemental-install-target

readlink -f /dev/elemental-install-target
test -b /dev/elemental-install-target && echo TARGET_IS_BLOCK
lsblk -d -o NAME,PATH,SIZE,MODEL,SERIAL,WWN,HCTL \
  "$(readlink -f /dev/elemental-install-target)"

如果别名已经存在,或者是一个悬空链接,不要覆盖它。使用 readlink 检查它,确定它为何存在,并且只有在确认其已过期后才将其移除。

该链接仅存在于当前 Live ISO 会话中。预期它会在重启后消失;已安装系统的正常启动不需要它。

7. 运行最终门控并开始安装

最后一次验证 Live root、挂载、目标链接、网络和 DNS:

findmnt -n -o SOURCE,FSTYPE,TARGET /
findmnt -rn -o SOURCE,TARGET | grep -E '^/dev/(sd|mapper/)' || \
  echo NO_PHYSICAL_DISK_MOUNTS
readlink -f /dev/elemental-install-target
test -b /dev/elemental-install-target
ip -br addr
ip route show default
getent hosts <global-domain>

只有在所有检查都通过后才启动安装程序:

systemctl unmask elemental-register-install.service
systemctl reset-failed elemental-register-install.service
systemctl start elemental-register-install.service
journalctl -fu elemental-register-install.service

在日志中确认注册成功、/dev/elemental-install-target 解析到预期的 WWN 磁盘、分区和安装完成,以及已配置的弹出/重启操作已执行。

验证已安装的主机

安装触发重启后:

  1. 弹出 BMC 虚拟介质,并恢复正常的“优先从磁盘启动”的启动顺序。

  2. 确认主机不会返回到 Live ISO。

  3. 在 Global 集群上验证新的 MachineInventory

    kubectl -n cpaas-system get machineinventories.elemental.cattle.io -o wide
    kubectl -n cpaas-system describe machineinventory <inventory-name>
  4. 确认该 inventory 的 Ready=True,报告了预期的网络,并且只有一个当前的 Elemental 磁盘布局。

  5. 只有在其就绪后,才将该 inventory 添加到 MachineInventoryPool

  6. 在 Cluster API 分配主机后,按照 在裸金属上创建集群 中的说明,验证 BaremetalMachine、工作负载 Node、控制平面组件和 CNI。

故障排除

症状原因与处理
在你选择磁盘之前,安装服务就失败了。这是在 /dev/elemental-install-target 不存在时预期的“失败即关闭”行为。停止并屏蔽该服务,完成检查,创建链接,然后重置并启动该服务。
test -b /dev/elemental-install-target 失败。WWN 路径错误、缺失,或者没有解析到整块块设备。重新检查 lsblk/dev/disk/by-id;不要启动安装。
仍有多个磁盘带有 COS_STATECOS_PERSISTENT先前的 Elemental 布局仍然存在。停止安装,并清理每个已批准的重新安装磁盘,直到 wipefsblkidlsblk 全部通过。
同一个物理磁盘在重启后具有不同的 /dev/sdX 名称。这在某些存储控制器上是预期行为。请比较 WWN、序列号、大小和控制器地址,而不是 kernel 名称。
MachineRegistration 已被修补,但 ISO 仍然使用旧目标。重新构建 SeedImage 并下载新生成的 ISO。对现有 ISO,不会回溯应用 MachineRegistration 更改。
Live ISO 中的注册可用,但重新预配后已安装主机没有网络。分别诊断已安装系统的 cloud-init 和 NetworkManager 激活。Live ISO 的 nmcli 配置文件是临时的,不能证明持久化重新预配网络已成功。

限制

  • 此工作流有意要求每台主机执行一次控制台操作。它可以防止自动选择;但它不能提供完全无人值守的异构磁盘选择。
  • MachineRegistration 元数据标签不会插值到 install.device 中。
  • 仅当恰好只有一块磁盘可能匹配时,基于磁盘大小的 device-selector 才是安全的,而当前选择并不强制唯一性。对于具有多个相同大小磁盘的主机,优先使用 WWN 门控。
  • 目标必须是整盘。不要将门控指向分区。