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

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

为什么需要手动磁盘门禁

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

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

本指南使用 fail-closed 的手动门禁:

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

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

前提条件

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

有关完整的 provider 和集群创建流程,请参见 Creating Clusters on Bare Metal。

配置共享 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。该 SeedImage 还必须包含 在首次安装前调整 COS_STATE 大小 中描述的 state 分区大小 —— 一旦主机升级到不同的镜像,Elemental 默认的 8 GiB 就太小了,而且在不重新安装主机的情况下无法更改大小。

WARNING

MachineRegistration 配置会嵌入到生成的 ISO 中。对 MachineRegistration 打补丁不会更改已经构建并下载的 ISO。请重新构建 SeedImage,等待其就绪,下载新的 ISO,并在从该 ISO 启动主机之前验证其 checksum。

准备每台主机

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

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

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

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

如果目标磁盘已挂载,或者你无法证明 root filesystem 属于 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 连接到 registration 和初始安装。它不会替代 Cluster API reprovisioning 时应用到已安装系统上的持久网络配置。

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 device 名称。
  • 大小、model、serial number 和 controller address(HCTL)。
  • /dev/disk/by-id/wwn-* 路径。
  • 哪一块整盘被批准作为系统磁盘。

使用 WWN 以及大小、model 和 controller 信息来做决定。不要仅凭 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 列表,仅包含本主机上已清理的磁盘。

验证已清理磁盘不包含签名、分区、filesystem type、标签或 partition label:

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 不显示旧的子分区、FSTYPE、LABEL 或 PARTLABEL。
  • 检查输出 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

在日志中确认 registration 成功,/dev/elemental-install-target 解析到了目标 WWN 磁盘,分区和安装完成,并且配置的 eject/reboot 操作已执行。

验证已安装主机

安装触发重启后:

  1. 弹出 BMC 虚拟介质,并恢复正常的 disk-first 启动顺序。

  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 disk layout。

  5. 只有在其 ready 之后,才将 inventory 加入 MachineInventoryPool。

  6. 在 Cluster API 分配主机之后,按照 Creating Clusters on Bare Metal 中的说明,验证 BaremetalMachine、工作负载 Node、control-plane 组件和 CNI。

故障排除

症状原因和处理
安装服务在你选择磁盘之前就失败了。当 /dev/elemental-install-target 不存在时,这就是预期的 fail-closed 行为。停止并 mask 该服务,完成检查,创建链接,然后 reset 并启动该服务。
test -b /dev/elemental-install-target 失败。WWN 路径错误、缺失,或者没有解析为整块块设备。重新检查 lsblk 和 /dev/disk/by-id;不要开始安装。
仍有多于一块磁盘具有 COS_STATE 或 COS_PERSISTENT。之前的 Elemental 布局仍然存在。停止安装,并清理每一块已批准重新安装的磁盘,直到 wipefs、blkid 和 lsblk 都通过。
同一块物理磁盘在重启后具有不同的 /dev/sdX 名称。这在某些存储控制器上是正常的。请比较 WWN、serial number、大小和 controller address,而不是 kernel 名称。
MachineRegistration 已打补丁,但 ISO 仍在使用旧目标。重新构建 SeedImage 并下载新生成的 ISO。MachineRegistration 的更改不会追溯应用到已有 ISO。
在 Live ISO 中 registration 正常,但已安装主机在 reprovision 后没有网络。需要分别诊断已安装系统中的 cloud-init 和 NetworkManager 激活。Live ISO 的 nmcli profile 是临时的,不能证明持久 reprovision 网络已成功。

限制

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