3 使用 Edge Image Builder 配置独立群集 #
Edge Image Builder (EIB) 工具可以简化为引导计算机生成自定义的、随时可引导 (CRB) 磁盘映像的过程,即使在完全隔离式方案中也能做到这一点。EIB 用于创建所有三个 SUSE Edge 部署空间中使用的部署映像,因为它足够灵活,可以提供最简单的自定义,例如通过提供全面配置的映像来添加用户或设置时区。例如,该映像可以设置复杂的网络配置、部署多节点 Kubernetes 群集、部署客户工作负载,并通过 Rancher/Elemental 和 SUSE Manager 注册到集中式管理平台。EIB 以容器映像的形式运行,因此具有极高的跨平台可移植性,可确保所有必需的依赖项都是独立的,对系统中安装的用于操作该工具的软件包的影响极小。
有关详细信息,请阅读 Edge Image Builder 简介(第 9 章 “Edge Image Builder”)。
3.1 先决条件 #
一台运行 SLES 15 SP5、openSUSE Leap 15.5 或 openSUSE Tumbleweed 的 x86_64 物理主机(或虚拟机)。
一个可用的容器运行时(例如 Podman)
最新 SLE Micro 5.5 SelfInstall“GM2”ISO 映像的下载副本,可在此处找到。
只要有兼容的容器运行时,其他操作系统就可以正常运行,但尚未在其他平台上进行广泛的测试。文档重点介绍 Podman,但 Docker 应该也能实现相同的功能。
3.1.1 获取 EIB 映像 #
EIB 容器映像已公开提供,可以通过在映像构建主机上运行以下命令从 SUSE Edge 注册表下载:
podman pull registry.suse.com/edge/edge-image-builder:1.0.2
3.2 创建映像配置目录 #
由于 EIB 在容器中运行,我们需要从主机挂载一个配置目录,以便能够指定所需的配置,并使 EIB 能够在构建过程中访问任何所需的输入文件和支持项目。此目录必须遵循特定的结构。我们在主目录中创建此目录,并将其命名为“eib”:
export CONFIG_DIR=$HOME/eib mkdir -p $CONFIG_DIR/base-images
在上一步骤中,我们创建了“base-images”目录,用于托管 SLE Micro 5.5 输入映像,现在我们确保将下载的映像复制到配置目录:
cp /path/to/downloads/SLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.install.iso $CONFIG_DIR/base-images/slemicro.iso
在 EIB 运行过程中,不会修改原始基础映像;在 EIB 配置目录的根目录中,会使用所需的配置创建新的自定义版本。
此时,配置目录应如下所示:
└── base-images/ └── slemicro.iso
3.3 创建映像定义文件 #
定义文件描述 Edge Image Builder 支持的大多数可配置选项,可以在此处找到选项的完整示例,我们建议您查看上游构建映像指南,以获取比本文中更详细的示例。首先,我们需要为操作系统映像创建一个非常简单的定义文件:
cat << EOF > $CONFIG_DIR/iso-definition.yaml apiVersion: 1.0 image: imageType: iso arch: x86_64 baseImage: slemicro.iso outputImageName: eib-image.iso EOF
此定义指定我们要为基于 x86_64
的系统生成输出映像。用作基础的、要进一步修改的映像是名为
slemicro.iso
的 iso
映像,其预期位置为
$CONFIG_DIR/base-images/slemicro.iso
。此定义还概述了在 EIB
修改完映像后,输出映像将命名为 eib-image.iso
,默认情况下,该输出映像驻留在
$CONFIG_DIR
中。
现在,我们的目录结构应如下所示:
├── iso-definition.yaml └── base-images/ └── slemicro.iso
下面的章节将演练几个常见操作的示例:
3.3.1 配置操作系统用户 #
EIB 允许您为用户预先配置登录信息(例如口令或 SSH 密钥),包括设置固定的 root 口令。作为此示例的一部分,我们将修复 root
口令,而第一步是使用 OpenSSL
创建一次性的已加密口令:
openssl passwd -6 SecurePassword
此命令将输出如下所示的内容:
$6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
然后,我们可以在定义文件中添加一个名为 operatingSystem
的部分,其中包含
users
数组。生成的文件应如下所示:
apiVersion: 1.0
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
还可以添加其他用户、创建主目录、设置用户 ID、添加 ssh 密钥身份验证,以及修改组信息。请参见上游构建映像指南获取更多示例。
3.3.2 配置 RPM 软件包 #
EIB 的主要功能之一是提供一个机制来向映像添加更多软件包,以便在安装完成时,系统能够立即利用已安装的软件包。EIB 允许用户指定以下信息:
映像定义中按名称列出的软件包
要在其中搜索这些软件包的网络储存库
SUSE Customer Center (SCC) 身份凭证,用于在官方 SUSE 储存库中搜索列出的软件包
通过
$CONFIG_DIR/rpms
目录侧载网络储存库中不存在的自定义 RPM通过同一目录 (
$CONFIG_DIR/rpms/gpg-keys
) 指定 GPG 密钥,以便可以验证第三方软件包
然后,EIB 将在映像构建时运行软件包解析过程,将基础映像用作输入,并尝试提取和安装所有提供的软件包(通过列表指定或在本地提供)。EIB 将所有软件包(包括所有依赖项)下载到输出映像中存在的储存库,并指示系统在首次引导过程中安装这些软件包。在映像构建期间执行此过程可确保在首次引导期间成功将软件包安装在所需平台(例如边缘节点)上。在您要将其他软件包植入映像,而不是在操作时通过网络提取软件包的环境(例如隔离环境或网络受限的环境)中,此行为也很有利。
我们通过一个简单的示例来演示这一点:我们将安装由第三方供应商支持的 NVIDIA 储存库中的
nvidia-container-toolkit
RPM 软件包:
packages:
packageList:
- nvidia-container-toolkit
additionalRepos:
- url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
生成的定义文件如下所示:
apiVersion: 1.0
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
packages:
packageList:
- nvidia-container-toolkit
additionalRepos:
- url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
上面是一个简单的示例,但为了完整性,请在运行映像生成之前下载 NVIDIA 软件包签名密钥:
$ mkdir -p $CONFIG_DIR/rpms/gpg-keys
$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey > rpms/gpg-keys/nvidia.gpg
通过此方法添加其他 RPM 的目的是添加受支持的第三方组件或用户提供(和维护)的软件包;请不要使用此机制来添加通常不受 SLE Micro 支持的软件包。如果使用此机制从 openSUSE 储存库(不受支持)添加组件,包括从较新的版本或服务包添加组件,那么,尽管最终系统看似能够按预期运行,但您最终得到的可能是一种不受支持的配置,尤其是当依赖项解析导致操作系统的核心部分被替换时。如果您不确定,请联系您的 SUSE 代表,以帮助确定所需配置的支持性。
在上游安装软件包指南中可以找到更详细的指南和更多示例。
3.3.3 配置 Kubernetes 群集和用户工作负载 #
EIB 的另一个特点是,可以使用它来自动部署可“就地引导”(即,无需任何形式的集中式管理基础架构即可协调)的单节点和多节点高可用性 Kubernetes 群集。这种方法背后的主要推动因素是隔离式部署或网络受限的环境,但它也可以作为一种快速引导独立群集的方式,即使网络访问完全正常而不受限。
使用此方法不仅可以部署自定义的操作系统,还可以指定 Kubernetes 配置、通过 Helm chart 指定任何其他分层组件,以及通过提供的 Kubernetes 清单指定任何用户工作负载。但是,此方法幕后的设计原则是,我们默认假设用户想要隔离式部署,因此映像定义中指定的任何项目都将提取到映像中。这些项目包括用户提供的工作负载,在其中,EIB 将确保提供的定义所需的任何已发现映像都会在本地复制,并由最终部署的系统中的嵌入式映像注册表提供服务。
在下一个示例中,我们将采用现有的映像定义并指定 Kubernetes 配置(在本示例中,未列出系统及其角色,因此我们默认假设使用单节点群集),这会指示 EIB 置备单节点 RKE2 Kubernetes 群集。为了展示用户提供的工作负载(通过清单)和分层组件(通过 Helm)部署的自动化,我们将通过 SUSE Edge Helm chart 安装 KubeVirt,并通过 Kubernetes 清单安装 NGINX。需要追加到现有映像定义的附加配置如下:
kubernetes:
version: v1.28.9+rke2r1
manifests:
urls:
- https://k8s.io/examples/application/nginx-app.yaml
helm:
charts:
- name: kubevirt-chart
version: 0.2.4
repositoryName: suse-edge
repositories:
- name: suse-edge
url: oci://registry.suse.com/edge
生成的完整定义文件现在应如下所示:
apiVersion: 1.0
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$G392FCbxVgnLaFw1$Ujt00mdpJ3tDHxEg1snBU3GjujQf6f8kvopu7jiCBIhRbRvMmKUqwcmXAKggaSSKeUUOEtCP3ZUoZQY7zTXnC1
packages:
packageList:
- nvidia-container-toolkit
additionalRepos:
- url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
kubernetes:
version: v1.28.9+rke2r1
manifests:
urls:
- https://k8s.io/examples/application/nginx-app.yaml
helm:
charts:
- name: kubevirt-chart
version: 0.2.4
repositoryName: suse-edge
repositories:
- name: suse-edge
url: oci://registry.suse.com/edge
在上游文档中可以找到多节点部署、自定义网络等选项和 Helm chart 选项/值的更多示例。
3.3.4 配置网络 #
在本快速入门的最后一个示例中,我们来配置在使用 EIB 生成的映像置备系统时启动的网络。请务必知道,除非提供网络配置,否则默认模型是在引导时发现的所有接口上使用的 DHCP。但是,这种配置并非都很理想,特别是当 DHCP 不可用,并且您需要提供静态配置时、需要设置更复杂的网络结构(例如绑定、LACP 和 VLAN)或者需要覆盖某些参数(例如主机名、DNS 服务器和路由)时。
EIB 能够提供每个节点的配置(其中的相关系统由其 MAC 地址唯一标识),或者为每台计算机提供相同配置的覆盖值,这在系统 MAC
地址未知时更有用。EIB 使用一个称为 Network Manager Configurator(简称为
nmc
)的附加工具,这是 SUSE Edge 团队构建的工具,用于基于 nmstate.io
声明式网络纲要应用自定义网络配置,在引导时识别其正在引导的节点,并在任何服务启动之前应用所需的网络配置。
我们现在通过在所需 network
目录中特定于节点的文件中(基于所需主机名)描述所需网络状态,为使用单一接口的系统应用静态网络配置:
mkdir $CONFIG_DIR/network cat << EOF > $CONFIG_DIR/network/host1.local.yaml routes: config: - destination: 0.0.0.0/0 metric: 100 next-hop-address: 192.168.122.1 next-hop-interface: eth0 table-id: 254 - destination: 192.168.122.0/24 metric: 100 next-hop-address: next-hop-interface: eth0 table-id: 254 dns-resolver: config: server: - 192.168.122.1 - 8.8.8.8 interfaces: - name: eth0 type: ethernet state: up mac-address: 34:8A:B1:4B:16:E7 ipv4: address: - ip: 192.168.122.50 prefix-length: 24 dhcp: false enabled: true ipv6: enabled: false EOF
上述示例是针对默认 192.168.122.0/24
子网设置的,假设测试在虚拟机上执行,请根据您的环境进行调整,不要忘记设置 MAC 地址。由于可以使用同一映像来置备多个节点,EIB(通过
nmc
)配置的网络取决于它是否能够根据其 MAC 地址唯一标识节点,因此在引导期间
nmc
将向每台计算机应用正确的网络配置。这意味着,您需要知道所要安装到的系统的 MAC
地址。或者,默认行为是依赖 DHCP,但您可以利用 configure-network.sh
挂钩将通用配置应用于所有节点 - 有关更多细节,请参见网络指南(第 10 章 “边缘网络”)。
生成的文件结构应如下所示:
├── iso-definition.yaml ├── base-images/ │ └── slemicro.iso └── network/ └── host1.local.yaml
我们刚刚创建的网络配置将被分析,必要的 NetworkManager 连接文件将自动生成并插入到 EIB 要创建的新安装映像中。这些文件将在主机置备期间应用,从而生成完整的网络配置。
有关上述配置的更详细解释以及此功能的示例,请参见“边缘网络”组件(第 10 章 “边缘网络”)。
3.4 构建映像 #
获得基础映像和可供 EIB 使用的映像定义后,接下来我们需要构建映像。为此,只需使用 podman
结合“build”命令调用 EIB 容器,并指定定义文件:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/edge-image-builder:1.0.2 \
build --definition-file iso-definition.yaml
该命令应输出如下所示的内容:
Setting up Podman API listener... Generating image customization components... Identifier ................... [SUCCESS] Custom Files ................. [SKIPPED] Time ......................... [SKIPPED] Network ...................... [SUCCESS] Groups ....................... [SKIPPED] Users ........................ [SUCCESS] Proxy ........................ [SKIPPED] Resolving package dependencies... Rpm .......................... [SUCCESS] Systemd ...................... [SKIPPED] Elemental .................... [SKIPPED] Suma ......................... [SKIPPED] Downloading file: dl-manifest-1.yaml 100% (498/498 B, 5.9 MB/s) Populating Embedded Artifact Registry... 100% (3/3, 11 it/min) Embedded Artifact Registry ... [SUCCESS] Keymap ....................... [SUCCESS] Configuring Kubernetes component... The Kubernetes CNI is not explicitly set, defaulting to 'cilium'. Downloading file: rke2_installer.sh Downloading file: rke2-images-core.linux-amd64.tar.zst 100% (782/782 MB, 98 MB/s) Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (367/367 MB, 100 MB/s) Downloading file: rke2.linux-amd64.tar.gz 100% (34/34 MB, 101 MB/s) Downloading file: sha256sum-amd64.txt 100% (3.9/3.9 kB, 1.5 MB/s) Downloading file: dl-manifest-1.yaml 100% (498/498 B, 7.2 MB/s) Kubernetes ................... [SUCCESS] Certificates ................. [SKIPPED] Building ISO image... Kernel Params ................ [SKIPPED] Image build complete!
构建的 ISO 映像存储在 $CONFIG_DIR/eib-image.iso
中:
├── iso-definition.yaml ├── eib-image.iso ├── _build │ └── cache/ │ └── ... │ └── build-<timestamp>/ │ └── ... ├── base-images/ │ └── slemicro.iso └── network/ └── host1.local.yaml
每次构建都会在 $CONFIG_DIR/_build/
中创建一个带时间戳的文件夹,其中包含构建日志、构建期间使用的项目以及 combustion
和
artefacts
目录,这两个目录包含添加到 CRB 映像的所有脚本和项目。
此目录的内容如下所示:
├── build-<timestamp>/ │ │── combustion/ │ │ ├── 05-configure-network.sh │ │ ├── 10-rpm-install.sh │ │ ├── 12-keymap-setup.sh │ │ ├── 13b-add-users.sh │ │ ├── 20-k8s-install.sh │ │ ├── 26-embedded-registry.sh │ │ ├── 48-message.sh │ │ ├── network/ │ │ │ ├── host1.local/ │ │ │ │ └── eth0.nmconnection │ │ │ └── host_config.yaml │ │ ├── nmc │ │ └── script │ │── artefacts/ │ │ │── registry/ │ │ │ ├── hauler │ │ │ ├── nginx:1.14.2-registry.tar.zst │ │ │ ├── rancher_kubectl:v1.28.7-registry.tar.zst │ │ │ └── registry.suse.com_suse_sles_15.5_virt-operator:1.1.1-150500.8.12.1-registry.tar.zst │ │ │── rpms/ │ │ │ └── rpm-repo │ │ │ ├── addrepo0 │ │ │ │ └── x86_64 │ │ │ │ ├── nvidia-container-toolkit-1.15.0-1.x86_64.rpm │ │ │ │ ├── ... │ │ │ ├── repodata │ │ │ │ ├── ... │ │ │ └── zypper-success │ │ └── kubernetes/ │ │ ├── rke2_installer.sh │ │ ├── registries.yaml │ │ ├── server.yaml │ │ ├── images/ │ │ │ ├── rke2-images-cilium.linux-amd64.tar.zst │ │ │ └── rke2-images-core.linux-amd64.tar.zst │ │ ├── install/ │ │ │ ├── rke2.linux-amd64.tar.gz │ │ │ └── sha256sum-amd64.txt │ │ └── manifests/ │ │ ├── dl-manifest-1.yaml │ │ └── kubevirt-chart.yaml │ ├── createrepo.log │ ├── eib-build.log │ ├── embedded-registry.log │ ├── helm │ │ └── kubevirt-chart │ │ └── kubevirt-0.2.4.tgz │ ├── helm-pull.log │ ├── helm-template.log │ ├── iso-build.log │ ├── iso-build.sh │ ├── iso-extract │ │ └── ... │ ├── iso-extract.log │ ├── iso-extract.sh │ ├── modify-raw-image.sh │ ├── network-config.log │ ├── podman-image-build.log │ ├── podman-system-service.log │ ├── prepare-resolver-base-tarball-image.log │ ├── prepare-resolver-base-tarball-image.sh │ ├── raw-build.log │ ├── raw-extract │ │ └── ... │ └── resolver-image-build │ └──... └── cache └── ...
如果构建失败,首先会在 eib-build.log
中记录相关信息。该日志会指出哪个组件构建失败,方便您进行调试。
此时,您应该有了一个随时可用的映像,它可以:
部署 SLE Micro 5.5
配置 root 口令
安装
nvidia-container-toolkit
软件包配置嵌入式容器注册表以在本地处理内容
安装单节点 RKE2
配置静态网络
安装 KubeVirt
部署用户提供的清单
3.5 调试映像构建过程 #
如果映像构建过程失败,请参见上游调试指南。
3.6 测试新构建的映像 #
有关如何测试新构建的 CRB 映像的说明,请参见上游映像测试指南。