documentation.suse.com / SUSE Edge 文档 / 产品文档 / 全自动定向网络置备

42 全自动定向网络置备

42.1 简介

定向网络置备是用于自动置备下游群集的功能。如果您有许多下游群集需要置备并希望自动完成该过程,此功能将非常有用。

管理群集(第 40 章 “设置管理群集)会自动部署以下组件:

  • SUSE Linux Micro RT(操作系统),可以根据使用场景自定义网络、存储、用户和内核参数等配置。

  • RKE2(Kubernetes 群集),默认的 CNI 插件为 Cilium。根据具体的应用场景,可以使用某些 CNI 插件,例如 Cilium+Multus

  • SUSE Storage

  • SUSE Security

  • MetalLB 可用作高可用性多节点群集的负载平衡器。

注意
注意

有关 SUSE Linux Micro 的详细信息,请参见第 9 章 “SUSE Linux Micro。有关 RKE2 的详细信息,请参见第 16 章 “RKE2。有关 SUSE Storage 的详细信息,请参见第 17 章 “SUSE Storage。有关 SUSE Security 的详细信息,请参见第 18 章 “SUSE Security

以下章节介绍了不同的定向网络置备工作流程,以及可添加到置备过程的一些附加功能:

注意
注意

以下几节介绍如何使用 SUSE Edge for Telco 为不同的定向网络置备工作流程场景做好准备工作。有关不同的部署配置选项示例(包括隔离环境、DHCP 和无 DHCP 网络、专用容器注册表等),请参见 SUSE Edge for Telco 储存库

42.2 为联网场景准备下游群集映像

Edge Image Builder(第 11 章 “Edge Image Builder)用于准备经过修改、将置备到下游群集主机上的 SLEMicro 基础映像。

可以通过 Edge Image Builder 完成大部分配置,但本指南仅介绍设置下游群集所需的最低限度配置。

42.2.1 联网场景的先决条件

  • 需要安装 PodmanRancher Desktop 等容器运行时,以便能够运行 Edge Image Builder。

  • 基础映像将按照第 28 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 映像所述通过 Base-SelfInstall 配置文件(对于实时内核,会使用 Base-RT-SelfInstall 配置文件)构建。为 x86-64 和 aarch64 这两种体系结构构建基础映像的过程是相同的。

  • 要部署 aarch64 下游群集,必须在部署管理群集之前,在 metal3.yaml 文件中设置 deployArchitecture: arm64 参数(如管理群集文档(???)中所述)。必须进行此设置,才能确保下游群集使用正确的体系结构。

注意
注意

构建主机的体系结构必须与待构建映像的体系结构一致。也就是说,要构建 aarch64 体系结构的映像,必须使用 aarch64 体系结构的构建主机;x86-64 体系结构同样如此 - 目前不支持跨体系结构构建。

42.2.2 联网场景的映像配置

运行 Edge Image Builder 时,将从主机挂载一个目录,因此需要创建一个目录结构来存储用于定义目标映像的配置文件。

  • downstream-cluster-config.yaml 是映像定义文件,有关详细信息,请参见第 3 章 “使用 Edge Image Builder 配置独立群集

  • 基础映像文件夹将包含按照第 28 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 映像所述使用 Base-SelfInstall 配置文件(对于实时内核,会使用 Base-RT-SelfInstall 配置文件)生成的输出原始映像。必须将该映像复制/移动到 base-images 文件夹下。

  • network 文件夹是可选的,有关详细信息,请参见第 42.2.2.6 节 “高级网络配置的附加脚本”

  • custom/scripts 目录包含要在首次引导时运行的脚本:

    1. 01-fix-growfs.sh 脚本,用于在部署时调整操作系统根分区的大小

    2. 02-performance.sh 脚本(可选),用于配置系统以调优性能。

    3. 03-sriov.sh 脚本(可选),用于为 SR-IOV 配置系统。

  • custom/files 目录包含映像创建过程中要复制到该映像的 performance-settings.shsriov-auto-filler.sh 文件。

├── downstream-cluster-config.yaml
├── base-images/
│   └ SL-Micro.x86_64-6.1-Base-GM.raw
├── network/
|   └ configure-network.sh
└── custom/
    └ scripts/
    |   └ 01-fix-growfs.sh
    |   └ 02-performance.sh
    |   └ 03-sriov.sh
    └ files/
        └ performance-settings.sh
        └ sriov-auto-filler.sh

42.2.2.1 下游群集映像定义文件

downstream-cluster-config.yaml 文件是下游群集映像的主配置文件。下面是通过 Metal3 进行部署的极简示例:

apiVersion: 1.2
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-GM.raw
  outputImageName: eibimage-output-telco.raw
operatingSystem:
  kernelArgs:
    - ignition.platform.id=openstack
    - net.ifnames=1
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $USERKEY1
  packages:
    packageList:
      - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE

其中,$SCC_REGISTRATION_CODE 是从 SUSE Customer Center 中复制的注册代码,并且软件包列表包含必需的 jq

$ROOT_PASSWORD 是 root 用户的已加密口令,可用于测试/调试目的。可以使用 openssl passwd-6 PASSWORD 命令生成此口令

对于生产环境,建议使用可添加到 users 块的 SSH 密钥(需将 $USERKEY1 替换为实际 SSH 密钥)。

注意
注意

arch: x86_64 为映像的体系结构。对于 arm64 体系结构,请使用 arch: aarch64

net.ifnames=1 会启用可预测网络接口命名

这与 metal3 chart 的默认配置相匹配,但设置必须与配置的 chart predictableNicNames 值相匹配。

另请注意,ignition.platform.id=openstack 是必需的,如果不指定此参数,在 Metal3 自动化流程中通过 ignition 配置 SLEMicro 时将会失败。

42.2.2.2 Growfs 脚本

目前,在置备后首次引导时,需要使用一个自定义脚本 (custom/scripts/01-fix-growfs.sh) 来增大文件系统,使之与磁盘大小匹配。01-fix-growfs.sh 脚本包含以下信息:

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /

42.2.2.3 性能脚本

以下可选脚本(custom/scripts/02-performance.sh)可用于配置系统以调优性能:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/performance-settings

# copy the artifacts
cp performance-settings.sh /opt/performance-settings/

custom/files/performance-settings.sh 是可用于配置系统以调优性能的脚本,可从以下链接下载。

42.2.2.4 SR-IOV 脚本

以下可选脚本 (custom/scripts/03-sriov.sh) 可用于为 SR-IOV 配置系统:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/sriov
# copy the artifacts
cp sriov-auto-filler.sh /opt/sriov/sriov-auto-filler.sh

custom/files/sriov-auto-filler.sh 是可用于为 SR-IOV 配置系统的脚本,可从以下链接下载。

注意
注意

使用相同的方法添加要在置备过程中执行的您自己的自定义脚本。有关详细信息,请参见第 3 章 “使用 Edge Image Builder 配置独立群集

42.2.2.5 电信工作负载的附加配置

要启用 dpdksr-iovFEC 等电信功能,可能需要提供附加软件包,如以下示例中所示。

apiVersion: 1.2
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.1-Base-GM.raw
  outputImageName: eibimage-output-telco.raw
operatingSystem:
  kernelArgs:
    - ignition.platform.id=openstack
    - net.ifnames=1
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $user1Key1
  packages:
    packageList:
      - jq
      - dpdk
      - dpdk-tools
      - libdpdk-23
      - pf-bb-config
    sccRegistrationCode: $SCC_REGISTRATION_CODE

其中,$SCC_REGISTRATION_CODE 是从 SUSE Customer Center 中复制的注册代码,并且软件包列表包含要用于 Telco 配置文件的最低限度的软件包。

注意
注意

arch: x86_64 为映像的体系结构。对于 arm64 体系结构,请使用 arch: aarch64

42.2.2.6 高级网络配置的附加脚本

如果您需要配置静态 IP 或第 42.6 节 “高级网络配置”中所述的更高级网络方案,则需要提供以下附加配置。

network 文件夹中创建以下 configure-network.sh 文件 - 这会在首次引导时使用配置驱动器数据,并使用 NM Configurator 工具来配置主机网络。

#!/bin/bash

set -eux

# Attempt to statically configure a NIC in the case where we find a network_data.json
# In a configuration drive

CONFIG_DRIVE=$(blkid --label config-2 || true)
if [ -z "${CONFIG_DRIVE}" ]; then
  echo "No config-2 device found, skipping network configuration"
  exit 0
fi

mount -o ro $CONFIG_DRIVE /mnt

NETWORK_DATA_FILE="/mnt/openstack/latest/network_data.json"

if [ ! -f "${NETWORK_DATA_FILE}" ]; then
  umount /mnt
  echo "No network_data.json found, skipping network configuration"
  exit 0
fi

DESIRED_HOSTNAME=$(cat /mnt/openstack/latest/meta_data.json | tr ',{}' '\n' | grep '\"metal3-name\"' | sed 's/.*\"metal3-name\": \"\(.*\)\"/\1/')
echo "${DESIRED_HOSTNAME}" > /etc/hostname

mkdir -p /tmp/nmc/{desired,generated}
cp ${NETWORK_DATA_FILE} /tmp/nmc/desired/_all.yaml
umount /mnt

./nmc generate --config-dir /tmp/nmc/desired --output-dir /tmp/nmc/generated
./nmc apply --config-dir /tmp/nmc/generated

42.2.3 映像创建

按照前面的章节准备好目录结构后,运行以下命令来构建映像:

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
 build --definition-file downstream-cluster-config.yaml

这会根据上述定义创建名为 eibimage-output-telco.raw 的输出 ISO 映像文件。

然后必须通过 Web 服务器提供输出映像,该服务器可以是根据管理群集文档(注意)启用的媒体服务器容器,也可以是其他某个本地可访问的服务器。在下面的示例中,此服务器是 imagecache.local:8080

42.3 为隔离场景准备下游群集映像

Edge Image Builder(第 11 章 “Edge Image Builder)用于准备经过修改、将置备到下游群集主机上的 SLEMicro 基础映像。

可以通过 Edge Image Builder 完成大部分配置,但本指南仅介绍为隔离场景设置下游群集所需的最低限度配置。

42.3.1 隔离场景的先决条件

  • 需要安装 PodmanRancher Desktop 等容器运行时,以便能够运行 Edge Image Builder。

  • 基础映像将按照第 28 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 映像所述通过 Base-SelfInstall 配置文件(对于实时内核,会使用 Base-RT-SelfInstall 配置文件)构建。为 x86-64 和 aarch64 这两种体系结构构建基础映像的过程是相同的。

  • 要部署 aarch64 下游群集,必须在部署管理群集之前,在 metal3.yaml 文件中设置 deployArchitecture: arm64 参数(如管理群集文档(???)中所述)。必须进行此设置,才能确保下游群集使用正确的体系结构。

  • 如果您要使用 SR-IOV 或任何其他需要容器映像的工作负载,则必须部署并事先配置一个本地专用注册表(设置/未设置 TLS 和/或身份验证)。此注册表用于存储 Helm chart OCI 映像及其他映像。

注意
注意

构建主机的体系结构必须与待构建映像的体系结构一致。也就是说,要构建 aarch64 体系结构的映像,必须使用 aarch64 体系结构的构建主机;x86-64 体系结构同样如此 - 目前不支持跨体系结构构建。

42.3.2 隔离场景的映像配置

运行 Edge Image Builder 时,将从主机挂载一个目录,因此需要创建一个目录结构来存储用于定义目标映像的配置文件。

  • downstream-cluster-airgap-config.yaml 是映像定义文件,有关详细信息,请参见第 3 章 “使用 Edge Image Builder 配置独立群集

  • 基础映像文件夹将包含按照第 28 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 映像所述使用 Base-SelfInstall 配置文件(对于实时内核,会使用 Base-RT-SelfInstall 配置文件)生成的输出原始映像。必须将该映像复制/移动到 base-images 文件夹下。

  • network 文件夹是可选的,有关详细信息,请参见第 42.2.2.6 节 “高级网络配置的附加脚本”

  • custom/scripts 目录包含要在首次引导时运行的脚本:

    1. 01-fix-growfs.sh 脚本,用于在部署时调整操作系统根分区的大小。

    2. 02-airgap.sh 脚本,用于在为隔离环境创建映像时,将映像复制到正确的位置。

    3. 03-performance.sh 脚本(可选),用于配置系统以调优性能。

    4. 04-sriov.sh 脚本(可选),用于为 SR-IOV 配置系统。

  • custom/files 目录包含在映像创建过程中要复制到映像的 rke2cni 映像。此外,还可以包含可选的 performance-settings.shsriov-auto-filler.sh 文件。

├── downstream-cluster-airgap-config.yaml
├── base-images/
│   └ SL-Micro.x86_64-6.1-Base-GM.raw
├── network/
|   └ configure-network.sh
└── custom/
    └ files/
    |   └ install.sh
    |   └ rke2-images-cilium.linux-amd64.tar.zst
    |   └ rke2-images-core.linux-amd64.tar.zst
    |   └ rke2-images-multus.linux-amd64.tar.zst
    |   └ rke2-images.linux-amd64.tar.zst
    |   └ rke2.linux-amd64.tar.zst
    |   └ sha256sum-amd64.txt
    |   └ performance-settings.sh
    |   └ sriov-auto-filler.sh
    └ scripts/
        └ 01-fix-growfs.sh
        └ 02-airgap.sh
        └ 03-performance.sh
        └ 04-sriov.sh

42.3.2.1 下游群集映像定义文件

downstream-cluster-airgap-config.yaml 文件是下游群集映像的主配置文件,上一节(第 42.2.2.5 节 “电信工作负载的附加配置”)已介绍其内容。

42.3.2.2 Growfs 脚本

目前,在置备后首次引导时,需要使用一个自定义脚本 (custom/scripts/01-fix-growfs.sh) 来增大文件系统,使之与磁盘大小匹配。01-fix-growfs.sh 脚本包含以下信息:

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /

42.3.2.3 隔离脚本

在映像创建过程中,需要使用以下脚本 (custom/scripts/02-airgap.sh) 将映像复制到正确的位置:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/rke2-artifacts
mkdir -p /var/lib/rancher/rke2/agent/images

# copy the artifacts
cp install.sh /opt/
cp rke2-images*.tar.zst rke2.linux-amd64.tar.gz sha256sum-amd64.txt /opt/rke2-artifacts/

42.3.2.4 性能脚本

以下可选脚本(custom/scripts/03-performance.sh)可用于配置系统以调优性能:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/performance-settings

# copy the artifacts
cp performance-settings.sh /opt/performance-settings/

custom/files/performance-settings.sh 是可用于配置系统以调优性能的脚本,可从以下链接下载。

42.3.2.5 SR-IOV 脚本

以下可选脚本 (custom/scripts/04-sriov.sh) 可用于为 SR-IOV 配置系统:

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/sriov
# copy the artifacts
cp sriov-auto-filler.sh /opt/sriov/sriov-auto-filler.sh

custom/files/sriov-auto-filler.sh 是可用于为 SR-IOV 配置系统的脚本,可从以下链接下载。

42.3.2.6 隔离场景的自定义文件

custom/files 目录包含映像创建过程中要复制到该映像的 rke2cni 映像。为了轻松生成映像,请使用以下脚本此处的映像列表在本地准备这些映像,以生成需要包含在 custom/files 中的制品。另外,可以从此处下载最新的 rke2-install 脚本。

$ ./edge-save-rke2-images.sh -o custom/files -l ~/edge-release-rke2-images.txt

下载映像后,目录结构应如下所示:

└── custom/
    └ files/
        └ install.sh
        └ rke2-images-cilium.linux-amd64.tar.zst
        └ rke2-images-core.linux-amd64.tar.zst
        └ rke2-images-multus.linux-amd64.tar.zst
        └ rke2-images.linux-amd64.tar.zst
        └ rke2.linux-amd64.tar.zst
        └ sha256sum-amd64.txt

42.3.2.7 预加载包含隔离场景和 SR-IOV 所需映像的专用注册表(可选)

如果您要在隔离场景中使用 SR-IOV 或要使用任何其他工作负载映像,必须按照以下步骤预加载包含这些映像的本地专用注册表:

  • 下载、提取 helm-chart OCI 映像并将其推送到专用注册表

  • 下载、提取所需的其余映像并将其推送到专用注册表

可使用以下脚本下载、提取映像并将其推送到专用注册表。本节将通过一个示例来说明如何预加载 SR-IOV 映像,但您也可以使用相同的方法来预加载任何其他自定义映像:

  1. 预加载 SR-IOV 所需的 helm-chart OCI 映像:

    1. 必须创建一个包含所需 helm-chart OCI 映像的列表:

      $ cat > edge-release-helm-oci-artifacts.txt <<EOF
      edge/sriov-network-operator-chart:303.0.2+up1.5.0
      edge/sriov-crd-chart:303.0.2+up1.5.0
      EOF
    2. 使用以下脚本和上面创建的列表生成本地 tarball 文件:

      $ ./edge-save-oci-artefacts.sh -al ./edge-release-helm-oci-artifacts.txt -s registry.suse.com
      Pulled: registry.suse.com/edge/charts/sriov-network-operator:303.0.2+up1.5.0
      Pulled: registry.suse.com/edge/charts/sriov-crd:303.0.2+up1.5.0
      a edge-release-oci-tgz-20240705
      a edge-release-oci-tgz-20240705/sriov-network-operator-chart-303.0.2+up1.5.0.tgz
      a edge-release-oci-tgz-20240705/sriov-crd-chart-303.0.2+up1.5.0.tgz
    3. 使用以下脚本将 tarball 文件上载到专用注册表(例如 myregistry:5000),以在您的注册表中预加载上一步下载的 Helm chart OCI 映像:

      $ tar zxvf edge-release-oci-tgz-20240705.tgz
      $ ./edge-load-oci-artefacts.sh -ad edge-release-oci-tgz-20240705 -r myregistry:5000
  2. 预加载 SR-IOV 所需的其余映像:

    1. 在这种情况下,必须包含电信工作负载的 sr-iov 容器映像(例如,作为参考,您可以从 helm-chart 值获取这些映像)

      $ cat > edge-release-images.txt <<EOF
      rancher/hardened-sriov-network-operator:v1.3.0-build20240816
      rancher/hardened-sriov-network-config-daemon:v1.3.0-build20240816
      rancher/hardened-sriov-cni:v2.8.1-build20240820
      rancher/hardened-ib-sriov-cni:v1.1.1-build20240816
      rancher/hardened-sriov-network-device-plugin:v3.7.0-build20240816
      rancher/hardened-sriov-network-resources-injector:v1.6.0-build20240816
      rancher/hardened-sriov-network-webhook:v1.3.0-build20240816
      EOF
    2. 必须使用以下脚本和上面创建的列表,在本地生成包含所需映像的 tarball 文件:

      $ ./edge-save-images.sh -l ./edge-release-images.txt -s registry.suse.com
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-operator:v1.3.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-config-daemon:v1.3.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-cni:v2.8.1-build20240820
      Image pull success: registry.suse.com/rancher/hardened-ib-sriov-cni:v1.1.1-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-device-plugin:v3.7.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-resources-injector:v1.6.0-build20240816
      Image pull success: registry.suse.com/rancher/hardened-sriov-network-webhook:v1.3.0-build20240816
      Creating edge-images.tar.gz with 7 images
    3. 使用以下脚本将 tarball 文件上载到专用注册表(例如 myregistry:5000),以在您的专用注册表中预加载上一步下载的映像:

      $ tar zxvf edge-release-images-tgz-20240705.tgz
      $ ./edge-load-images.sh -ad edge-release-images-tgz-20240705 -r myregistry:5000

42.3.3 为隔离场景创建映像

按照前面的章节准备好目录结构后,运行以下命令来构建映像:

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
 build --definition-file downstream-cluster-airgap-config.yaml

这会根据上述定义创建名为 eibimage-output-telco.raw 的输出 ISO 映像文件。

然后必须通过 Web 服务器提供输出映像,该服务器可以是根据管理群集文档(注意)启用的媒体服务器容器,也可以是其他某个本地可访问的服务器。在下面的示例中,此服务器是 imagecache.local:8080

42.4 使用定向网络置备来置备下游群集(单节点)

本节介绍用于通过定向网络置备自动置备单节点下游群集的工作流程。这是自动置备下游群集的最简单的方法。

要求

工作流程

下图显示了用于通过定向网络置备自动置备单节点下游群集的工作流程:

ATIP 单节点群集自动置备 1

可以执行两个不同的步骤来使用定向网络置备自动置备单节点下游群集:

  1. 登记裸机主机,使其在置备过程中可用。

  2. 置备裸机主机,以安装并配置操作系统和 Kubernetes 群集。

登记裸机主机

第一步是在管理群集中登记新的裸机主机,使其可供置备。为此,必须在管理群集中创建以下文件 (bmh-example.yaml),以指定要使用的 BMC 身份凭证以及要登记的 BaremetalHost 对象:

apiVersion: v1
kind: Secret
metadata:
  name: example-demo-credentials
type: Opaque
data:
  username: ${BMC_USERNAME}
  password: ${BMC_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: example-demo
  labels:
    cluster-role: control-plane
spec:
  online: true
  bootMACAddress: ${BMC_MAC}
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: ${BMC_ADDRESS}
    disableCertificateVerification: true
    credentialsName: example-demo-credentials

其中:

  • ${BMC_USERNAME} — 新裸机主机的 BMC 用户名。

  • ${BMC_PASSWORD} — 新裸机主机的 BMC 口令。

  • ${BMC_MAC} — 要使用的新裸机主机的 MAC 地址。

  • ${BMC_ADDRESS} — 裸机主机 BMCURL(例如 redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/)。要了解有关硬件提供商支持的不同选项的详细信息,请访问此链接

注意
注意

如果未在映像构建时或通过 BareMetalHost 定义指定主机的网络配置,系统将使用自动配置机制(DHCP、DHCPv6、SLAAC)。有关详细信息或复杂配置,请参见第 42.6 节 “高级网络配置”

创建该文件后,必须在管理群集中执行以下命令,才能在管理群集中开始登记新的裸机主机:

$ kubectl apply -f bmh-example.yaml

随后会登记新裸机主机对象,其状态将从正在注册依次变为正在检查和可用。可使用以下命令检查状态变化:

$ kubectl get bmh
注意
注意

在验证 BMC 身份凭证之前,BaremetalHost 对象将一直处于正在注册状态。验证身份凭证后,BaremetalHost 对象的状态将变为正在检查,此步骤可能需要一段时间(最长 20 分钟),具体取决于所用的硬件。在检查阶段,将检索硬件信息并更新 Kubernetes 对象。请使用以下命令检查信息:kubectl get bmh -o yaml

置备步骤

裸机主机已登记并可供使用后,下一步是置备裸机主机,以安装并配置操作系统和 Kubernetes 群集。为此,必须在管理群集中创建以下文件 (capi-provisioning-example.yaml) 并在其中包含以下信息(可以通过合并以下块来生成 capi-provisioning-example.yaml)。

注意
注意

只需将 ${...} 中的值替换为实际值。

下面的块是群集定义,可在其中使用 podsservices 块来配置网络。此外,它还包含对要使用的控制平面和基础架构(使用 Metal3 提供程序)对象的引用。

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
    services:
      cidrBlocks:
        - 10.96.0.0/12
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane
    name: single-node-cluster
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: single-node-cluster

对于双栈 Pod 和服务的部署,可以改为使用以下定义:

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
        - fd00:bad:cafe::/48
    services:
      cidrBlocks:
        - 10.96.0.0/12
        - fd00:bad:bad:cafe::/112
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane
    name: single-node-cluster
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: single-node-cluster
重要
重要

IPv6 和双栈部署处于技术预览状态,不提供官方支持。

Metal3Cluster 对象指定要配置的控制平面端点(请替换 ${DOWNSTREAM_CONTROL_PLANE_IP})以及 noCloudProvider,因为使用了一个裸机节点。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: ${DOWNSTREAM_CONTROL_PLANE_IP}
    port: 6443
  noCloudProvider: true

RKE2ControlPlane 对象指定要使用的控制平面配置,Metal3MachineTemplate 对象指定要使用的控制平面映像。此外,它还包含有关要使用的复本数(在本例中为 1)以及要使用的 CNI 插件(在本例中为 Cilium)的信息。agentConfig 块包含要使用的 Ignition 格式,以及用于配置 RKE2 节点的 additionalUserData,其中包含名为 rke2-preinstall.service 的 systemd 等信息,用于在置备过程中使用 Ironic 信息自动替换 BAREMETALHOST_UUIDnode-name。为了启用 multus 和 cilium,会在 rke2 服务器清单目录中创建名为 rke2-cilium-config.yaml 的文件,其中包含要使用的配置。最后一个信息块包含要使用的 Kubernetes 版本。${RKE2_VERSION} 是要使用的 RKE2 版本,请替换此值(例如替换为 v1.32.4+rke2r1)。

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: cilium
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
        storage:
          files:
            # https://docs.rke2.io/networking/multus_sriov#using-multus-with-cilium
            - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChartConfig
                  metadata:
                    name: rke2-cilium
                    namespace: kube-system
                  spec:
                    valuesContent: |-
                      cni:
                        exclusive: false
              mode: 0644
              user:
                name: root
              group:
                name: root
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

Metal3MachineTemplate 对象指定以下信息:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: single-node-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: single-node-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/eibimage-output-telco.raw.sha256
        checksumType: sha256
        format: raw
        url: http://imagecache.local:8080/eibimage-output-telco.raw

Metal3DataTemplate 对象指定下游群集的 metaData

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: single-node-cluster-controlplane-template
  namespace: default
spec:
  clusterName: single-node-cluster
  metaData:
    objectNames:
      - key: name
        object: machine
      - key: local-hostname
        object: machine
      - key: local_hostname
        object: machine

通过合并上述块创建该文件后,必须在管理群集中执行以下命令才能开始置备新的裸机主机:

$ kubectl apply -f capi-provisioning-example.yaml

42.5 使用定向网络置备来置备下游群集(多节点)

本节介绍用于通过定向网络置备和 MetalLB(用作负载平衡器策略)自动置备多节点下游群集的工作流程。这是自动置备下游群集的最简单的方法。下图显示了用于通过定向网络置备和 MetalLB 自动置备多节点下游群集的工作流程。

要求

工作流程

下图显示了用于通过定向网络置备自动置备多节点下游群集的工作流程:

ATIP 多节点群集自动置备 1
  1. 登记三个裸机主机,使其在置备过程中可用。

  2. 置备三个裸机主机,以使用 MetalLB 安装并配置操作系统和 Kubernetes 群集。

登记裸机主机

第一步是在管理群集中登记三个裸机主机,使其可供置备。为此,必须在管理群集中创建以下文件(bmh-example-node1.yamlbmh-example-node2.yamlbmh-example-node3.yaml),以指定要使用的 BMC 身份凭证,以及要在管理群集中登记的 BaremetalHost 对象。

注意
注意
  • 只需将 ${...} 中的值替换为实际值。

  • 本节只会指导您完成一个主机的置备过程。这些步骤同样适用于另外两个节点。

apiVersion: v1
kind: Secret
metadata:
  name: node1-example-credentials
type: Opaque
data:
  username: ${BMC_NODE1_USERNAME}
  password: ${BMC_NODE1_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: node1-example
  labels:
    cluster-role: control-plane
spec:
  online: true
  bootMACAddress: ${BMC_NODE1_MAC}
  bmc:
    address: ${BMC_NODE1_ADDRESS}
    disableCertificateVerification: true
    credentialsName: node1-example-credentials

其中:

  • ${BMC_NODE1_USERNAME} — 第一个裸机主机的 BMC 用户名。

  • ${BMC_NODE1_PASSWORD} — 第一个裸机主机的 BMC 口令。

  • ${BMC_NODE1_MAC} — 第一个裸机主机的要使用的 MAC 地址。

  • ${BMC_NODE1_ADDRESS} — 第一个裸机主机的 BMC 的 URL(例如 redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/)。要了解有关硬件提供商支持的不同选项的详细信息,请访问此链接

注意
注意
  • 如果未在映像构建时或通过 BareMetalHost 定义指定主机的网络配置,系统将使用自动配置机制(DHCP、DHCPv6、SLAAC)。有关详细信息或复杂配置,请参见第 42.6 节 “高级网络配置”

  • 尚不支持多节点双栈群集或仅支持 IPv6 的群集。

创建该文件后,必须在管理群集中执行以下命令,才能在管理群集中开始登记裸机主机:

$ kubectl apply -f bmh-example-node1.yaml
$ kubectl apply -f bmh-example-node2.yaml
$ kubectl apply -f bmh-example-node3.yaml

随后会登记新裸机主机对象,其状态将从正在注册依次变为正在检查和可用。可使用以下命令检查状态变化:

$ kubectl get bmh -o wide
注意
注意

在验证 BMC 身份凭证之前,BaremetalHost 对象将一直处于正在注册状态。验证身份凭证后,BaremetalHost 对象的状态将变为正在检查,此步骤可能需要一段时间(最长 20 分钟),具体取决于所用的硬件。在检查阶段,将检索硬件信息并更新 Kubernetes 对象。请使用以下命令检查信息:kubectl get bmh -o yaml

置备步骤

三个裸机主机已登记并可供使用后,下一步是置备裸机主机,以安装和配置操作系统与 Kubernetes 群集,并创建用于管理该操作系统和群集的负载平衡器。为此,必须在管理群集中创建以下文件 (capi-provisioning-example.yaml) 并在其中包含以下信息(可以通过合并以下块来生成 capi-provisioning-example.yaml)。

注意
注意
  • 只需将 ${...} 中的值替换为实际值。

  • VIP 地址是尚未分配给任何节点的预留 IP 地址,用于配置负载平衡器。

下面的内容为群集定义,可在其中使用 podsservices 块来配置群集网络。此外,它还包含对要使用的控制平面和基础架构(使用 Metal3 提供程序)对象的引用。

apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: multinode-cluster
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
    services:
      cidrBlocks:
        - 10.96.0.0/12
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1beta1
    kind: RKE2ControlPlane
    name: multinode-cluster
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3Cluster
    name: multinode-cluster

Metal3Cluster 对象指定使用已预留的 VIP 地址(请替换 ${DOWNSTREAM_VIP_ADDRESS})的待配置控制平面端点,以及 noCloudProvider(因为使用了三个裸机节点)。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3Cluster
metadata:
  name: multinode-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: ${EDGE_VIP_ADDRESS}
    port: 6443
  noCloudProvider: true

RKE2ControlPlane 对象指定要使用的控制平面配置,Metal3MachineTemplate 对象指定要使用的控制平面映像。

  • 要使用的复本数(在本例中为 3)。

  • 负载平衡器要使用的通告模式(address 使用 L2 实现),以及要使用的地址(请将 ${EDGE_VIP_ADDRESS} 替换为 VIP 地址)。

  • serverConfig,其中包含要使用的 CNI 插件(在本例中为 Cilium);用于配置 VIP 地址的 tlsSan

  • agentConfig 块包含要使用的 Ignition 格式以及用于配置 RKE2 节点的 additionalUserData,其中的信息如下:

    • 名为 rke2-preinstall.service 的 systemd 服务,用于在置备过程中使用 Ironic 信息自动替换 BAREMETALHOST_UUIDnode-name

    • storage 块,其中包含用于安装 MetalLBendpoint-copier-operator 的 Helm chart。

    • metalLB 自定义资源文件,其中包含要使用的 IPaddressPoolL2Advertisement(请将 ${EDGE_VIP_ADDRESS} 替换为 VIP 地址)。

    • 用于配置 kubernetes-vip 服务的 end-svc.yaml 文件,MetalLB 使用该服务来管理 VIP 地址。

  • 最后一个信息块包含要使用的 Kubernetes 版本。${RKE2_VERSION} 是要使用的 RKE2 版本,请替换此值(例如替换为 v1.32.4+rke2r1)。

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: multinode-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: multinode-cluster-controlplane
  replicas: 3
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  registrationAddress: ${EDGE_VIP_ADDRESS}
  serverConfig:
    cni: cilium
    tlsSan:
      - ${EDGE_VIP_ADDRESS}
      - https://${EDGE_VIP_ADDRESS}.sslip.io
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
        storage:
          files:
            # https://docs.rke2.io/networking/multus_sriov#using-multus-with-cilium
            - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChartConfig
                  metadata:
                    name: rke2-cilium
                    namespace: kube-system
                  spec:
                    valuesContent: |-
                      cni:
                        exclusive: false
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-copier-operator.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: endpoint-copier-operator
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
                    targetNamespace: endpoint-copier-operator
                    version: 303.0.0+up0.2.1
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/metallb.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: metallb
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/metallb
                    targetNamespace: metallb-system
                    version: 303.0.0+up0.14.9
                    createNamespace: true

            - path: /var/lib/rancher/rke2/server/manifests/metallb-cr.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: metallb.io/v1beta1
                  kind: IPAddressPool
                  metadata:
                    name: kubernetes-vip-ip-pool
                    namespace: metallb-system
                  spec:
                    addresses:
                      - ${EDGE_VIP_ADDRESS}/32
                    serviceAllocation:
                      priority: 100
                      namespaces:
                        - default
                      serviceSelectors:
                        - matchExpressions:
                          - {key: "serviceType", operator: In, values: [kubernetes-vip]}
                  ---
                  apiVersion: metallb.io/v1beta1
                  kind: L2Advertisement
                  metadata:
                    name: ip-pool-l2-adv
                    namespace: metallb-system
                  spec:
                    ipAddressPools:
                      - kubernetes-vip-ip-pool
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-svc.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: Service
                  metadata:
                    name: kubernetes-vip
                    namespace: default
                    labels:
                      serviceType: kubernetes-vip
                  spec:
                    ports:
                    - name: rke2-api
                      port: 9345
                      protocol: TCP
                      targetPort: 9345
                    - name: k8s-api
                      port: 6443
                      protocol: TCP
                      targetPort: 6443
                    type: LoadBalancer
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "Node-multinode-cluster"

Metal3MachineTemplate 对象指定以下信息:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: multinode-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: multinode-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/eibimage-output-telco.raw.sha256
        checksumType: sha256
        format: raw
        url: http://imagecache.local:8080/eibimage-output-telco.raw

Metal3DataTemplate 对象指定下游群集的 metaData

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: multinode-cluster-controlplane-template
  namespace: default
spec:
  clusterName: multinode-cluster
  metaData:
    objectNames:
      - key: name
        object: machine
      - key: local-hostname
        object: machine
      - key: local_hostname
        object: machine

通过合并上述块创建该文件后,必须在管理群集中执行以下命令开始置备三个新的裸机主机:

$ kubectl apply -f capi-provisioning-example.yaml

42.6 高级网络配置

定向网络置备工作流程允许在下游群集中使用静态 IP、绑定、VLAN 等网络配置。

以下章节将介绍使用高级网络配置置备下游群集需额外执行的步骤。

要求

配置

在继续操作之前,请参考以下章节,了解登记和置备主机所需执行的步骤:

任何高级网络配置都必须在登记时通过 BareMetalHost 主机定义以及包含 nmstate 格式 networkData 块的关联机密来应用。以下示例文件定义了一个包含所需 networkData 的机密,该机密会为下游群集主机请求静态 IPVLAN

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: ${CONTROLPLANE_INTERFACE}
      type: ethernet
      state: up
      mtu: 1500
      identifier: mac-address
      mac-address: "${CONTROLPLANE_MAC}"
      ipv4:
        address:
        - ip:  "${CONTROLPLANE_IP}"
          prefix-length: "${CONTROLPLANE_PREFIX}"
        enabled: true
        dhcp: false
    - name: floating
      type: vlan
      state: up
      vlan:
        base-iface: ${CONTROLPLANE_INTERFACE}
        id: ${VLAN_ID}
    dns-resolver:
      config:
        server:
        - "${DNS_SERVER}"
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: "${CONTROLPLANE_GATEWAY}"
        next-hop-interface: ${CONTROLPLANE_INTERFACE}

如您所见,该示例展示了启用配备静态 IP 的接口的配置,以及使用基础接口启用 VLAN 的配置,在实际应用时,需根据您的基础架构将以下变量替换为实际值:

  • ${CONTROLPLANE1_INTERFACE} — 用于边缘群集的控制平面接口(例如 eth0)。如果包含 identifier: mac-address,系统将会根据 MAC 地址自动检测命名,因此可以使用任何接口名称。

  • ${CONTROLPLANE1_IP} — 用作边缘群集端点的 IP 地址(必须与 kubeapi-server 端点匹配)。

  • ${CONTROLPLANE1_PREFIX} — 用于边缘群集的 CIDR(例如,如果您要使用 /24 子网掩码,请指定 24;也可以指定 255.255.255.0)。

  • ${CONTROLPLANE1_GATEWAY} — 用于边缘群集的网关(例如 192.168.100.1)。

  • ${CONTROLPLANE1_MAC} — 用于控制平面接口的 MAC 地址(例如 00:0c:29:3e:3e:3e)。

  • ${DNS_SERVER} — 用于边缘群集的 DNS(例如 192.168.100.2)。

  • ${VLAN_ID} — 用于边缘群集的 VLAN ID(例如 100)。

任何其他符合 nmstate 标准的定义都可用于配置下游群集的网络,以适应特定要求。例如,可以指定静态双栈配置:

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: ${CONTROLPLANE_INTERFACE}
      type: ethernet
      state: up
      mac-address: ${CONTROLPLANE_MAC}
      ipv4:
        enabled: true
        dhcp: false
        address:
        - ip: ${CONTROLPLANE_IP_V4}
          prefix-length: ${CONTROLPLANE_PREFIX_V4}
      ipv6:
        enabled: true
        dhcp: false
        autoconf: false
        address:
        - ip: ${CONTROLPLANE_IP_V6}
          prefix-length: ${CONTROLPLANE_PREFIX_V6}
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: ${CONTROLPLANE_GATEWAY_V4}
        next-hop-interface: ${CONTROLPLANE_INTERFACE}
      - destination: ::/0
        next-hop-address: ${CONTROLPLANE_GATEWAY_V6}
        next-hop-interface: ${CONTROLPLANE_INTERFACE}
    dns-resolver:
      config:
        server:
        - ${DNS_SERVER_V4}
        - ${DNS_SERVER_V6}

与前面的示例一样,请根据您的基础架构将以下变量替换为实际值:

  • ${CONTROLPLANE_IP_V4} - 分配给主机的 IPv4 地址

  • ${CONTROLPLANE_PREFIX_V4} - 主机 IP 所属网络的 IPv4 前缀

  • ${CONTROLPLANE_IP_V6} - 分配给主机的 IPv6 地址

  • ${CONTROLPLANE_PREFIX_V6} - 主机 IP 所属网络的 IPv6 前缀

  • ${CONTROLPLANE_GATEWAY_V4} - 与默认路由匹配的流量所用网关的 IPv4 地址

  • ${CONTROLPLANE_GATEWAY_V6} - 与默认路由匹配的流量所用网关的 IPv6 地址

  • ${CONTROLPLANE_INTERFACE} - 地址要分配到的接口的名称,该接口同时供与默认路由匹配的出站流量使用(适用于 IPv4 和 IPv6)

  • ${DNS_SERVER_V4} 和/或 ${DNS_SERVER_V6} - 要使用的 DNS 服务器的 IP 地址(可指定单项或多项,支持 IPv4 和/或 IPv6 地址)

重要
重要

IPv6 和双栈部署处于技术预览状态,不提供官方支持。

注意
注意

有关更复杂的示例(包括仅支持 IPv6 的配置和双栈配置),您可以参考 SUSE Edge for Telco 示例代码库

最后,无论网络配置详细信息如何,都要确保通过在 BaremetalHost 对象中附加 preprovisioningNetworkDataName 来引用该机密,以便成功在管理群集中登记主机。

apiVersion: v1
kind: Secret
metadata:
  name: example-demo-credentials
type: Opaque
data:
  username: ${BMC_USERNAME}
  password: ${BMC_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: example-demo
  labels:
    cluster-role: control-plane
spec:
  online: true
  bootMACAddress: ${BMC_MAC}
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: ${BMC_ADDRESS}
    disableCertificateVerification: true
    credentialsName: example-demo-credentials
  preprovisioningNetworkDataName: controlplane-0-networkdata
注意
注意
  • 如果需要部署多节点群集,必须对每个节点执行相同的过程。

  • 目前不支持 Metal3DataTemplatenetworkDataMetal3 IPAM;只有通过静态机密进行的配置才完全受支持。

42.7 电信功能(DPDK、SR-IOV、CPU 隔离、大页、NUMA 等)

定向网络置备工作流程允许将下游群集中使用的电信功能自动化,以便在这些服务器上运行电信工作负载。

要求

配置

基于以下两个章节的内容登记和置备主机:

本节将介绍以下电信功能:

  • DPDK 和 VF 创建

  • 工作负载使用的 SR-IOV 和 VF 分配

  • CPU 隔离和性能调优

  • 大页配置

  • 内核参数调优

注意
注意

有关电信功能的详细信息,请参见第 41 章 “电信功能配置

启用上述电信功能所需做出的更改都可以在 capi-provisioning-example.yaml 置备文件的 RKE2ControlPlane 块中完成。capi-provisioning-example.yaml 文件中的其余信息与置备相关章节(第 42.4 节 “使用定向网络置备来置备下游群集(单节点)”)中提供的信息相同。

明确地说,为启用电信功能而需在该块 (RKE2ControlPlane) 中进行的更改如下:

  • 指定 preRKE2Commands,该参数用于在 RKE2 安装过程开始之前执行命令。本例使用 modprobe 命令启用 vfio-pciSR-IOV 内核模块。

  • 指定 ignition 文件 /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml,该文件用于定义要创建且向工作负载公开的接口、驱动程序及 VF 数量。

    • 只有 sriov-custom-auto-config 配置映射中的值可以替换为实际值。

      • ${RESOURCE_NAME1} — 用于第一个 PF 接口的资源名称(例如 sriov-resource-du1)。它将添加到前缀 rancher.io 的后面,供工作负载用作标签(例如 rancher.io/sriov-resource-du1)。

      • ${SRIOV-NIC-NAME1} — 要使用的第一个 PF 接口的名称(例如 eth0)。

      • ${PF_NAME1} — 要使用的第一个物理功能 PF 的名称。可以使用此名称生成更复杂的过滤器(例如 eth0#2-5)。

      • ${DRIVER_NAME1} — 用于第一个 VF 接口的驱动程序名称(例如 vfio-pci)。

      • ${NUM_VFS1} — 要为第一个 PF 接口创建的 VF 数量(例如 8)。

  • 提供 /var/sriov-auto-filler.sh,用作高层级配置映射 sriov-custom-auto-config 与包含底层硬件信息的 sriovnetworknodepolicy 之间的转换器。创建此脚本的目的是简化用户操作,让其无需提前了解复杂的硬件信息。不需要在此文件中进行更改,但如果我们需要启用 sr-iov 并创建 VF,则应该提供此脚本。

  • 用于启用以下功能的内核参数:

参数

说明

isolcpus

domain,nohz,​managed_irq,1-30,33-62

隔离核心 1-30 和 33-62。

skew_tick

1

允许内核在隔离的 CPU 之间错开定时器中断。

nohz

on

允许内核在系统空闲时在单个 CPU 上运行定时器节拍周期。

nohz_full

1-30,33-62

内核引导参数是当前用于配置完整 dynticks 及 CPU 隔离的主接口。

rcu_nocbs

1-30,33-62

允许内核在系统空闲时在单个 CPU 上运行 RCU 回调。

irqaffinity

0,31,32,63

允许内核在系统空闲时在单个 CPU 上运行中断。

idle

poll

最大限度地减少因退出空闲状态造成的延迟。

iommu

pt

允许为 dpdk 接口使用 vfio。

intel_iommu

on

允许为 VF 使用 vfio。

hugepagesz

1G

允许将大页的大小设置为 1 G。

hugepages

40

先前定义的大页数量。

default_hugepagesz

1G

用于启用大页的默认值。

nowatchdog

 

禁用看门狗。

nmi_watchdog

0

禁用 NMI 看门狗。

  • 以下 systemd 服务用于启用下述功能:

    • rke2-preinstall.service,用于在置备过程中使用 Ironic 信息自动替换 BAREMETALHOST_UUIDnode-name

    • cpu-partitioning.service,用于启用 CPU 核心隔离(例如 1-30,33-62)。

    • performance-settings.service,用于调优 CPU 性能。

    • sriov-custom-auto-vfs.service,用于执行以下操作:安装 sriov Helm chart,等待自定义资源创建完成,运行 /var/sriov-auto-filler.sh 以替换配置映射 sriov-custom-auto-config 中的值,并创建工作负载要使用的 sriovnetworknodepolicy

  • ${RKE2_VERSION} 是要使用的 RKE2 版本,请替换此值(例如替换为 v1.32.4+rke2r1)。

做出上述所有更改后,capi-provisioning-example.yaml 中的 RKE2ControlPlane 块如下所示:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: calico
    cniMultusEnable: true
  preRKE2Commands:
    - modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
            - path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: ConfigMap
                  metadata:
                    name: sriov-custom-auto-config
                    namespace: kube-system
                  data:
                    config.json: |
                      [
                         {
                           "resourceName": "${RESOURCE_NAME1}",
                           "interface": "${SRIOV-NIC-NAME1}",
                           "pfname": "${PF_NAME1}",
                           "driver": "${DRIVER_NAME1}",
                           "numVFsToCreate": ${NUM_VFS1}
                         },
                         {
                           "resourceName": "${RESOURCE_NAME2}",
                           "interface": "${SRIOV-NIC-NAME2}",
                           "pfname": "${PF_NAME2}",
                           "driver": "${DRIVER_NAME2}",
                           "numVFsToCreate": ${NUM_VFS2}
                         }
                      ]
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/sriov-crd.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-crd
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/sriov-crd
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/sriov-network-operator.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-network-operator
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/sriov-network-operator
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
                    createNamespace: true
        kernel_arguments:
          should_exist:
            - intel_iommu=on
            - iommu=pt
            - idle=poll
            - mce=off
            - hugepagesz=1G hugepages=40
            - hugepagesz=2M hugepages=0
            - default_hugepagesz=1G
            - irqaffinity=${NON-ISOLATED_CPU_CORES}
            - isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
            - nohz_full=${ISOLATED_CPU_CORES}
            - rcu_nocbs=${ISOLATED_CPU_CORES}
            - rcu_nocb_poll
            - nosoftlockup
            - nowatchdog
            - nohz=on
            - nmi_watchdog=0
            - skew_tick=1
            - quiet
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
            - name: cpu-partitioning.service
              enabled: true
              contents: |
                [Unit]
                Description=cpu-partitioning
                Wants=network-online.target
                After=network.target network-online.target
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
                ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
                ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
                [Install]
                WantedBy=multi-user.target
            - name: performance-settings.service
              enabled: true
              contents: |
                [Unit]
                Description=performance-settings
                Wants=network-online.target
                After=network.target network-online.target cpu-partitioning.service
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
                [Install]
                WantedBy=multi-user.target
            - name: sriov-custom-auto-vfs.service
              enabled: true
              contents: |
                [Unit]
                Description=SRIOV Custom Auto VF Creation
                Wants=network-online.target  rke2-server.target
                After=network.target network-online.target rke2-server.target
                [Service]
                User=root
                Type=forking
                TimeoutStartSec=900
                ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --all ; do sleep 2 ; done"
                ExecStartPost=/bin/sh -c "while [ $(/var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml get sriovnetworknodestates.sriovnetwork.openshift.io --ignore-not-found --no-headers -A | wc -l) -eq 0 ]; do sleep 1; done"
                ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
                RemainAfterExit=yes
                KillMode=process
                [Install]
                WantedBy=multi-user.target
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

通过合并上述块创建该文件后,必须在管理群集中执行以下命令才能开始使用电信功能置备新的下游群集:

$ kubectl apply -f capi-provisioning-example.yaml

42.8 专用注册表

可以配置专用注册表作为工作负载所使用映像的镜像。

为此,我们可以创建机器,并在其中包含有关下游群集要使用的专用注册表的信息。

apiVersion: v1
kind: Secret
metadata:
  name: private-registry-cert
  namespace: default
data:
  tls.crt: ${TLS_CERTIFICATE}
  tls.key: ${TLS_KEY}
  ca.crt: ${CA_CERTIFICATE}
type: kubernetes.io/tls
---
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
  namespace: default
data:
  username: ${REGISTRY_USERNAME}
  password: ${REGISTRY_PASSWORD}

tls.crttls.keyca.crt 是用于对专用注册表进行身份验证的证书。usernamepassword 是用于对专用注册表进行身份验证的身份凭证。

注意
注意

在机密中使用 tls.crttls.keyca.crtusernamepassword 之前,必须对它们进行 base64 编码。

做出上述所有更改后,capi-provisioning-example.yaml 中的 RKE2ControlPlane 块如下所示:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  privateRegistriesConfig:
    mirrors:
      "registry.example.com":
        endpoint:
          - "https://registry.example.com:5000"
    configs:
      "registry.example.com":
        authSecret:
          apiVersion: v1
          kind: Secret
          namespace: default
          name: private-registry-auth
        tls:
          tlsConfigSecret:
            apiVersion: v1
            kind: Secret
            namespace: default
            name: private-registry-cert
  serverConfig:
    cni: calico
    cniMultusEnable: true
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"

其中,registry.example.com 是下游群集使用的专用注册表的示例名称,应将其替换为实际值。

42.9 在隔离场景中置备下游群集

定向网络置备工作流程允许在隔离场景中自动置备下游群集。

42.9.1 隔离场景的要求

  1. 使用 EIB 生成的原始映像必须包含用于在隔离场景中运行下游群集的特定容器映像(helm-chart OCI 和容器映像)。有关详细信息,请参见第 42.3 节 “为隔离场景准备下游群集映像”

  2. 如果使用 SR-IOV 或任何其他自定义工作负载,则必须按照有关预加载专用注册表的一节(第 42.3.2.7 节 “预加载包含隔离场景和 SR-IOV 所需映像的专用注册表(可选)”)所述,在专用注册表中预加载用于运行工作负载的映像。

42.9.2 在隔离场景中登记裸机主机

在管理群集中登记裸机主机的过程与上前面的章节(第 42.4 节 “使用定向网络置备来置备下游群集(单节点)”)中所述的过程相同。

42.9.3 在隔离场景中置备下游群集

需要进行一些重大更改才能在隔离场景中置备下游群集:

  1. capi-provisioning-example.yaml 文件中的 RKE2ControlPlane 必须包含 spec.agentConfig.airGapped: true 指令。

  2. 必须按照有关专用注册表的一节(第 42.8 节 “专用注册表”)所述,将专用注册表配置包含在 capi-provisioning-airgap-example.yaml 文件的 RKE2ControlPlane 块中。

  3. 如果您使用的是 SR-IOV 或任何其他需要安装 helm-chart 的 AdditionalUserData 配置(combustion 脚本),则必须修改配置内容以引用专用注册表,而不是使用公共注册表。

以下示例显示了 capi-provisioning-airgap-example.yaml 文件的 AdditionalUserData 块中的 SR-IOV 配置,以及为了引用专用注册表而需进行的修改。

  • 专用注册表机密引用

  • 在 Helm-Chart 定义中使用专用注册表而不是公共 OCI 映像。

# secret to include the private registry certificates
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-cert
  namespace: default
data:
  tls.crt: ${TLS_BASE64_CERT}
  tls.key: ${TLS_BASE64_KEY}
  ca.crt: ${CA_BASE64_CERT}
type: kubernetes.io/tls
---
# secret to include the private registry auth credentials
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
  namespace: default
data:
  username: ${REGISTRY_USERNAME}
  password: ${REGISTRY_PASSWORD}
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  privateRegistriesConfig:       # Private registry configuration to add your own mirror and credentials
    mirrors:
      docker.io:
        endpoint:
          - "https://$(PRIVATE_REGISTRY_URL)"
    configs:
      "192.168.100.22:5000":
        authSecret:
          apiVersion: v1
          kind: Secret
          namespace: default
          name: private-registry-auth
        tls:
          tlsConfigSecret:
            apiVersion: v1
            kind: Secret
            namespace: default
            name: private-registry-cert
          insecureSkipVerify: false
  serverConfig:
    cni: calico
    cniMultusEnable: true
  preRKE2Commands:
    - modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  agentConfig:
    airGapped: true       # Airgap true to enable airgap mode
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
            - path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: ConfigMap
                  metadata:
                    name: sriov-custom-auto-config
                    namespace: sriov-network-operator
                  data:
                    config.json: |
                      [
                         {
                           "resourceName": "${RESOURCE_NAME1}",
                           "interface": "${SRIOV-NIC-NAME1}",
                           "pfname": "${PF_NAME1}",
                           "driver": "${DRIVER_NAME1}",
                           "numVFsToCreate": ${NUM_VFS1}
                         },
                         {
                           "resourceName": "${RESOURCE_NAME2}",
                           "interface": "${SRIOV-NIC-NAME2}",
                           "pfname": "${PF_NAME2}",
                           "driver": "${DRIVER_NAME2}",
                           "numVFsToCreate": ${NUM_VFS2}
                         }
                      ]
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/sriov.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  data:
                    .dockerconfigjson: ${REGISTRY_AUTH_DOCKERCONFIGJSON}
                  kind: Secret
                  metadata:
                    name: privregauth
                    namespace: kube-system
                  type: kubernetes.io/dockerconfigjson
                  ---
                  apiVersion: v1
                  kind: ConfigMap
                  metadata:
                    namespace: kube-system
                    name: example-repo-ca
                  data:
                    ca.crt: |-
                      -----BEGIN CERTIFICATE-----
                      ${CA_BASE64_CERT}
                      -----END CERTIFICATE-----
                  ---
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-crd
                    namespace: kube-system
                  spec:
                    chart: oci://${PRIVATE_REGISTRY_URL}/sriov-crd
                    dockerRegistrySecret:
                      name: privregauth
                    repoCAConfigMap:
                      name: example-repo-ca
                    createNamespace: true
                    set:
                      global.clusterCIDR: 192.168.0.0/18
                      global.clusterCIDRv4: 192.168.0.0/18
                      global.clusterDNS: 10.96.0.10
                      global.clusterDomain: cluster.local
                      global.rke2DataDir: /var/lib/rancher/rke2
                      global.serviceCIDR: 10.96.0.0/12
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
                  ---
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: sriov-network-operator
                    namespace: kube-system
                  spec:
                    chart: oci://${PRIVATE_REGISTRY_URL}/sriov-network-operator
                    dockerRegistrySecret:
                      name: privregauth
                    repoCAConfigMap:
                      name: example-repo-ca
                    createNamespace: true
                    set:
                      global.clusterCIDR: 192.168.0.0/18
                      global.clusterCIDRv4: 192.168.0.0/18
                      global.clusterDNS: 10.96.0.10
                      global.clusterDomain: cluster.local
                      global.rke2DataDir: /var/lib/rancher/rke2
                      global.serviceCIDR: 10.96.0.0/12
                    targetNamespace: sriov-network-operator
                    version: 303.0.2+up1.5.0
              mode: 0644
              user:
                name: root
              group:
                name: root
        kernel_arguments:
          should_exist:
            - intel_iommu=on
            - iommu=pt
            - idle=poll
            - mce=off
            - hugepagesz=1G hugepages=40
            - hugepagesz=2M hugepages=0
            - default_hugepagesz=1G
            - irqaffinity=${NON-ISOLATED_CPU_CORES}
            - isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
            - nohz_full=${ISOLATED_CPU_CORES}
            - rcu_nocbs=${ISOLATED_CPU_CORES}
            - rcu_nocb_poll
            - nosoftlockup
            - nowatchdog
            - nohz=on
            - nmi_watchdog=0
            - skew_tick=1
            - quiet
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                ExecStart=/bin/sh -c "sed -i \"s/BAREMETALHOST_UUID/$(jq -r .uuid /mnt/openstack/latest/meta_data.json)/\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
            - name: cpu-partitioning.service
              enabled: true
              contents: |
                [Unit]
                Description=cpu-partitioning
                Wants=network-online.target
                After=network.target network-online.target
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
                ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
                ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
                [Install]
                WantedBy=multi-user.target
            - name: performance-settings.service
              enabled: true
              contents: |
                [Unit]
                Description=performance-settings
                Wants=network-online.target
                After=network.target network-online.target cpu-partitioning.service
                [Service]
                Type=oneshot
                User=root
                ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
                [Install]
                WantedBy=multi-user.target
            - name: sriov-custom-auto-vfs.service
              enabled: true
              contents: |
                [Unit]
                Description=SRIOV Custom Auto VF Creation
                Wants=network-online.target  rke2-server.target
                After=network.target network-online.target rke2-server.target
                [Service]
                User=root
                Type=forking
                TimeoutStartSec=1800
                ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --timeout=30m --all ; do sleep 10 ; done"
                ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
                RemainAfterExit=yes
                KillMode=process
                [Install]
                WantedBy=multi-user.target
    kubelet:
      extraArgs:
        - provider-id=metal3://BAREMETALHOST_UUID
    nodeName: "localhost.localdomain"
Documentation survey