- SUSE Edge 3.6 文档
- I 快速入门
- II 组件
- III How-to 指南
- IV 提示和技巧
- V 第三方集成
- VI 第2天操作
- VII 查错
- VIII 附录
SUSE Edge 3.6 文档 #
欢迎阅读 SUSE Edge 文档。您将找到高层架构概述、快速入门指南、经过验证的设计、组件用法指南、第三方集成,以及有关管理边缘计算基础架构和工作负载的最佳实践。
1 什么是 SUSE Edge? #
SUSE Edge 是一种专为解决边缘基础架构和云原生应用部署的独特挑战而构建、紧密集成且经过全面验证的端到端解决方案。其核心重点是提供一个既有明确导向,又高度灵活、高度可伸缩且安全的平台,涵盖从初始部署镜像构建、节点配置和接入、应用程序部署、可观测性到完整的生命周期运维。该平台从底层构建于最优秀的开源软件之上,这与我们 30 多年来提供安全、稳定且经过认证的 SUSE Linux 平台的历史,以及我们在 Rancher 产品组合中提供高度可伸缩且功能丰富的 Kubernetes 管理方面的经验相一致。SUSE Edge 在这些功能的基础上构建,旨在提供能够满足众多细分市场需求的功能,包括零售、医疗、交通、物流、电信、智能制造和工业物联网。
2 设计理念 #
该解决方案的设计理念是,由于客户的需求和期望差异巨大,不存在“一刀切”的边缘平台。边缘部署促使我们去解决并不断演进一些最具挑战性的问题,包括大规模可扩展性、受限的网络可用性、物理空间限制、新的安全威胁和攻击向量、硬件体系结构和系统资源的差异、部署和对接遗留基础设施与应用程序的需求,以及具有延长生命周期的客户解决方案。由于其中许多挑战与传统思维方式(例如在数据中心或公有云中部署基础设施和应用程序)不同,我们必须以更细致的粒度深入研究设计,并重新思考许多常见的假设。
例如,我们认为极简主义、模块化和操作简便具有重要价值。极简主义对于边缘环境非常重要,因为系统越复杂,就越容易出故障。当管理数百个甚至多达数十万个地点时,复杂的系统会以复杂的方式出现故障。我们方案的模块化在去除已部署平台中不必要的复杂性的同时,为用户提供了更多选择。我们还需要在这些方面与操作的简便性之间取得平衡。人在重复执行数千次处理时可能会犯错,因此平台应确保任何潜在的错误都是可恢复的,从而无需现场技术人员到场,同时也应努力实现一致性和标准化。
3 高级体系结构 #
SUSE Edge 的高级体系结构分为两个核心类别,即“管理”集群和“下游”集群。管理集群负责远程管理一个或多个下游集群,尽管人们认识到在某些情况下,下游集群需要在没有远程管理的情况下运行,例如在边缘站点没有外部连接且需要独立运行的情况下。在 SUSE Edge 中,用于管理集群和下游集群操作的技术组件在很大程度上是通用的,尽管它们在系统规格和驻留其上的应用程序方面可能会有所不同,即管理集群将运行支持系统管理和生命周期操作的应用程序,而下游集群则用于服务用户应用程序。
3.1 SUSE Edge 中使用的组件 #
SUSE Edge 由现有的 SUSE 和 Rancher 组件以及 Edge 团队构建的附加功能和组件组成,使我们能够解决边缘计算中所需的约束和复杂性。下面解释了管理集群和下游集群中使用的组件,并附有一个简化的高级体系结构图,请注意这不是一个详尽的列表:
3.1.1 管理群集 #
管理:这是 SUSE Edge 的集中式部分,用于管理已连接下游集群的部署和生命周期。管理集群通常包括以下组件:
通过 Rancher Prime (第 4 章 “Rancher”) 进行多集群管理,为下游集群的接入以及基础设施和应用程序的持续生命周期管理提供了一个通用仪表板,同时还提供全面的租户隔离和
IDP(身份提供商)集成、大量的第三方集成和扩展市场,以及供应商中立的 API。通过 SUSE Multi-Linux Manager 进行 Linux 系统管理,实现对下游集群上运行的底层 Linux 操作系统(*SUSE Linux Micro (第 7 章 “SUSE Linux Micro”))的自动化 Linux 补丁和配置管理。请注意,虽然此组件已容器化,但目前需要在与其他管理组件不同的系统上运行,因此在上图中标记为“Linux 管理”。
一个专用的 生命周期管理 (第 19 章 “升级控制器”) 控制器,用于处理给定 SUSE Edge 版本的管理集群组件升级。
通过 Elemental (第 10 章 “Elemental”) 将远程系统接入 Rancher Prime,实现将连接的边缘节点后期绑定到所需的 Kubernetes 集群和应用程序部署(例如通过 GitOps)。
一个名为 Fleet (第 6 章 “Fleet”) 的可选 GitOps 引擎,用于管理下游集群及其上运行的应用程序的配置和生命周期。
支撑管理集群本身的是作为基础操作系统的 SUSE Linux Micro (第 7 章 “SUSE Linux Micro”),以及作为支持管理集群应用程序的 Kubernetes 发行版的 RKE2 (第 12 章 “RKE2”)。
3.1.2 下游集群 #
下游:这是 SUSE Edge 的分布式部分,用于在边缘运行用户工作负载,即在边缘位置本身运行的软件,通常由以下组件组成:
可选择的 Kubernetes 发行版,包括 K3s (第 11 章 “K3s”) 和 RKE2 (第 12 章 “RKE2”) 等安全且轻量级的发行版(
RKE2经过加固、认证和优化,适用于政府和受监管行业)。SUSE Security (第 14 章 “SUSE Security”),用于启用镜像漏洞扫描、深度数据包检测以及实时威胁和漏洞防护等安全功能。
使用 SUSE Storage (第 13 章 “SUSE Storage”) 提供块存储,以实现轻量级、持久、弹性和可扩展的块存储。
一种轻量级、针对容器优化的加固型 Linux 操作系统 SUSE Linux Micro (第 7 章 “SUSE Linux Micro”),为在边缘运行容器和虚拟机提供了一个不可变且高度弹性的操作系统。SUSE Linux Micro 可用于 AArch64 和 AMD64/Intel 64 架构,它还支持
Real-Time Kernel以满足延迟敏感型应用(例如电信应用场景)的需求。对于已连接的集群(即那些与管理集群保持连接的集群),会部署两个代理,分别是用于管理与 Rancher Prime 连接的 Rancher System Agent,以及用于接收来自 SUSE Multi-Linux Manager 的指令以应用 Linux 软件更新的 venv-salt-minion。管理断开连接的集群时不需要这些代理。
3.2 连接 #
上图提供了 已连接 下游集群及其与管理集群连接的高级架构概览。管理集群可以部署在各种底层基础设施平台上,包括本地和云端,具体取决于下游集群与目标管理集群之间的网络可用性。实现此功能的唯一要求是,连接下游集群节点与管理基础设施的网络必须能够访问 API 和回调 URL。
必须认识到,建立这种连接的方法与下游集群部署方式有所不同。下一节将更深入地解释其中的细节,但为了建立基础认知,将下游集群建立为“受管”集群主要有三种机制:
下游集群最初以“断开连接”的状态部署(例如通过 Edge Image Builder (第 8 章 “Edge Image Builder”)),然后在连接允许的情况下导入到管理集群中。
下游集群被配置为使用内置的接入机制 (例如通过 Elemental (第 10 章 “Elemental”)), 它们会在首次启动时自动注册到管理集群中,从而允许集群配置的后期绑定。
下游集群已配置了裸机管理功能(CAPI + Metal3),并且一旦集群部署和配置完成(通过 Rancher Turtles 操作器),它们就会自动导入到管理集群中。
4 常见的边缘部署模式 #
由于操作环境和生命周期要求各不相同,我们针对 SUSE Edge 运营所处的市场细分领域和用例,实施了对多种不同部署模式的支持。我们为每种部署模式都编写了快速入门指南,以帮助您根据自身需求熟悉 SUSE Edge 平台。我们目前支持的三种部署模式如下所述,并附有相应快速入门页面的链接。
4.1 “Phone Home”网络配置 #
有时您在这样的环境中运行:中央管理集群无法直接管理硬件(例如,您的远程网络位于防火墙之后,或者没有带外管理接口;这在边缘常见的“PC”类硬件中很常见)。在这种情况下,我们提供工具来远程部署集群及其工作负载,而无需在启动硬件时知道它将被运往何处。这正是大多数人在谈及边缘计算时所指的;成千上万甚至数万个在边缘位置启动、并安全地进行“Phone Home”、验证身份及接收指令的不知名系统。我们在此处的要求期望部署和生命周期管理几乎不需要用户干预,只需在工厂预先对机器进行镜像,或者简单地附加一个引导镜像(例如通过 USB)并打开系统电源即可。该领域的主要挑战是解决这些在实际环境中运行的设备在规模、一致性、安全性和生命周期方面的问题。
该解决方案在系统部署和接入方式上提供了极大的灵活性和一致性,无论其位置、系统类型或规格如何,也无论它们何时首次通电。SUSE Edge 通过 Edge Image Builder 实现系统的完全灵活性和定制化,并利用 Rancher 的 Elemental 产品进行节点接入和 Kubernetes 部署的注册功能,以及用于操作系统补丁的 SUSE Multi-Linux Manager。该解决方案的快速入门指南可在 第 1 章 “使用 Elemental 进行远程主机注册” 中找到。
4.2 基于镜像的部署 #
对于需要在独立、隔离的或网络受限环境中运行的客户,SUSE Edge 提供了一种解决方案,使客户能够生成完全定制的安装介质,其中包含在边缘启用单节点和多节点高可用 Kubernetes 集群所需的所有部署工件,包括所需的任何工作负载或额外的分层组件,且无需连接到外部网络,也无需集中式管理平台的干预。用户体验与“Phone Home”解决方案非常相似,即向目标系统提供安装介质,但该解决方案将“就地引导”。在这种情况下,可以将生成的集群连接到 Rancher 进行持续管理(即从“断开连接”模式转变为“连接”模式,而无需进行重大的重新配置或重新部署),也可以继续在隔离状态下运行。请注意,在这两种情况下,都可以应用相同的自动化生命周期操作的一致机制。
此外,该解决方案可用于快速创建管理集群,这些集群可以托管支持“定向网络配置”和“Phone Home 网络配置”模型的集中式基础设施,因为这可能是配置所有类型边缘基础设施最快捷、最简单的方法。该解决方案大量利用 SUSE Edge Image Builder 的功能来创建完全定制的无人值守安装介质;快速入门指南可在 第 2 章 “使用 Edge Image Builder 的独立集群” 中找到。
5 SUSE Edge 堆栈验证 #
所有 SUSE Edge 版本均由紧密集成且经过彻底验证的组件组成,这些组件作为一个整体进行版本控制。作为持续集成和堆栈验证工作的一部分,不仅要测试组件之间的集成,还要确保系统在强制故障场景下按预期运行,SUSE Edge 团队会将所有测试运行及其结果公开发布。结果以及所有输入参数可在 ci.edge.suse.com 中找到。
6 完整组件列表 #
组件的完整列表,以及每个组件的高级描述链接及其在 SUSE Edge 中的使用方式,请见下方:
Rancher (第 4 章 “Rancher”)
Rancher Dashboard 扩展 (第 5 章 “Rancher 仪表板扩展”)
SUSE Multi-Linux Manager
Fleet (第 6 章 “Fleet”)
SUSE Linux Micro (第 7 章 “SUSE Linux Micro”)
Edge Image Builder (第 8 章 “Edge Image Builder”)
NetworkManager Configurator (第 9 章 “边缘网络”)
Elemental (第 10 章 “Elemental”)
K3s (第 11 章 “K3s”)
RKE2 (第 12 章 “RKE2”)
SUSE Storage (第 13 章 “SUSE Storage”)
SUSE Security (第 14 章 “SUSE Security”)
MetalLB (第 15 章 “MetalLB”)
KubeVirt (第 17 章 “边缘虚拟化”)
系统升级控制器 (第 18 章 “系统升级控制器”)
Upgrade Controller (第 19 章 “升级控制器”)
第 I 部分 快速入门 #
快速入门
- 1 使用 Elemental 进行远程主机注册
本节记录了作为 SUSE Edge 一部分的“电话回拨网络配置”解决方案,我们使用 Elemental 来协助节点注册。Elemental 是一个软件栈,支持远程主机注册以及通过 Kubernetes 进行集中的云原生操作系统管理。在 SUSE Edge 栈中,我们使用 Elemental 的注册功能来实现远程主机注册至 Rancher,以便将主机集成到集中式管理平台中,并从那里统一部署和管理 Kubernetes 集群以及分层组件、应用程序及其生命周期。
- 2 使用 Edge Image Builder 的独立集群
Edge Image Builder (EIB) 是一款简化了为引导机器生成定制化、即开即用 (CRB) 磁盘镜像流程的工具,即使在完全隔离的环境中也能使用。EIB 用于为所有三种 SUSE Edge 部署足迹创建部署镜像,因为它足够灵活,既能提供最小化的自定义(例如添加用户或设置时区),也能提供全面配置的镜像(例如设置复杂的网络配置、部署多节点 Kubernetes 集群、部署客户工作负载,以及通过 Rancher/Elemental 和 SUSE Multi-Linux Manager 注册到集中式管理平台)。EIB 作为容器镜像运行,使其在不同平台间具有极高的可移植性,并确保所有必需的依…
- 3 SUSE Multi-Linux Manager
SUSE Edge 3.6 (5.0.6) 中包含的 SUSE Multi-Linux Manager 版本尚不支持 SUSE Linux Micro 6.2。它将在未来的 SUSE Edge 3.6 版本中进行更新并提供支持。
1 使用 Elemental 进行远程主机注册 #
本节记录了作为 SUSE Edge 一部分的“电话回拨网络配置”解决方案,我们使用 Elemental 来协助节点注册。Elemental 是一个软件栈,支持远程主机注册以及通过 Kubernetes 进行集中的云原生操作系统管理。在 SUSE Edge 栈中,我们使用 Elemental 的注册功能来实现远程主机注册至 Rancher,以便将主机集成到集中式管理平台中,并从那里统一部署和管理 Kubernetes 集群以及分层组件、应用程序及其生命周期。
当您想要控制的设备与管理集群不在同一网络,或者没有板载带外管理控制器以实现更直接的控制,并且您需要在边缘启动许多不同的“未知”系统,同时需要大规模安全地注册和管理它们时,这种方法非常有用。这对于零售、工业物联网或其他您无法控制设备安装所在网络的用例来说,是一种常见场景。
1.1 高级体系结构 #
1.2 所需资源 #
以下描述了完成此快速入门所需的最低系统和环境要求:
目标机器上现有的数据将在该过程中被覆盖,请确保备份连接到目标部署节点的所有 USB 存储设备和磁盘上的任何数据。
本指南是使用 Digital Ocean droplet 来托管上游群集,并使用 Intel NUC 作为下游设备创建的。构建安装介质时,使用的是 SUSE Linux Enterprise Server。
1.3 构建启动群集 #
首先创建一个能够托管 Rancher 和 Elemental 的群集。此群集需要能够从下游节点所连接的网络进行路由。
1.3.1 创建 Kubernetes 群集 #
如果您使用的是超大规模云服务商(例如 Azure、AWS 或 Google Cloud),设置群集的最简单方法是使用其内置工具。为了使本指南保持简洁,我们未详细介绍这些选项的每一个处理。
如果您要安装到裸机或其他需要您自行提供 Kubernetes 发行版的托管服务上,我们建议使用 RKE2。
1.3.2 设置 DNS #
在继续之前,您需要设置对群集的访问权限。与群集本身的设置一样,配置 DNS 的方式将根据其托管位置而有所不同。
如果您不想处理 DNS 记录的设置(例如,这只是一个临时测试服务器),则可以使用像 sslip.io 这样的服务来代替。使用此服务,您可以解析任何带有 <address>.sslip.io 的 IP 地址。
1.4 安装 Rancher #
要安装 Rancher,您需要获取对刚创建的群集的 Kubernetes API 的访问权限。这看起来会有所不同,具体取决于所使用的 Kubernetes 发行版。
对于 RKE2,kubeconfig 文件将被写入 /etc/rancher/rke2/rke2.yaml。
将此文件在本地系统上保存为 ~/.kube/config。
您可能需要编辑该文件以包含正确的外部可路由 IP 地址或主机名。
使用 Rancher 文档 中的命令轻松安装 Rancher:
安装 cert-manager:
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true然后安装 Rancher 本身:
helm repo add rancher-prime https://charts.rancher.com/server-charts/prime
helm repo update
helm install rancher rancher-prime/rancher \
--namespace cattle-system \
--create-namespace \
--set hostname=<DNS or sslip from above> \
--set replicas=1 \
--set bootstrapPassword=<PASSWORD_FOR_RANCHER_ADMIN> \
--version 2.14.2如果这旨在作为生产系统,请使用 cert-manager 配置真实证书(例如来自 Let’s Encrypt 的证书)。
浏览到您设置的主机名,并使用您使用的 bootstrapPassword 登录 Rancher。您将通过一个简短的设置过程。
1.5 安装 Elemental #
安装 Rancher 后,您现在可以安装 Elemental operator 和所需的 CRD。Elemental 的 Helm chart 作为 OCI 工件发布,因此安装比其他 chart 更简单。 它可以从您安装 Rancher 时使用的同一个 shell 中安装,也可以在浏览器中从 Rancher 的 shell 内安装。
helm install --create-namespace -n cattle-elemental-system \
elemental-operator-crds \
oci://registry.suse.com/rancher/elemental-operator-crds-chart \
--version 1.9.0
helm install -n cattle-elemental-system \
elemental-operator \
oci://registry.suse.com/rancher/elemental-operator-chart \
--version 1.9.01.5.1 (可选)安装 Elemental UI 扩展 #
1.6 配置 Elemental #
为简单起见,我们建议将变量 $ELEM 设置为您希望放置配置目录的完整路径:
export ELEM=$HOME/elemental
mkdir -p $ELEM要允许机器注册到 Elemental,我们需要在 fleet-default 命名空间中创建一个 MachineRegistration 对象。
让我们创建一个该对象的基本版本:
cat << EOF > $ELEM/registration.yaml
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
name: ele-quickstart-nodes
namespace: fleet-default
spec:
machineName: "\${System Information/Manufacturer}-\${System Information/UUID}"
machineInventoryLabels:
manufacturer: "\${System Information/Manufacturer}"
productName: "\${System Information/Product Name}"
EOF
kubectl apply -f $ELEM/registration.yamlcat 命令使用反斜杠 (\) 转义每个 $,以便 Bash 不会对它们进行模板化处理。如果手动复制,请删除反斜杠。
对象创建完成后,找到并记录分配的端点:
REGISURL=$(kubectl get machineregistration ele-quickstart-nodes -n fleet-default -o jsonpath='{.status.registrationURL}')或者,也可以通过 UI 完成此操作。
1.7 构建映像 #
虽然当前版本的 Elemental 有一种构建其自身安装介质的方法,但在 SUSE Edge 3.6 中,我们改用 Kiwi 和 Edge Image Builder 来执行此操作,因此生成的系统以 SUSE Linux Micro 作为基础操作系统。
有关 Kiwi 的更多详细信息,请先按照 Kiwi 映像构建器流程 (第 26 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 镜像”) 构建新映像;对于 Edge Image Builder,请查看 Edge Image Builder 入门指南 (第 2 章 “使用 Edge Image Builder 的独立集群”) 以及 组件文档 (第 8 章 “Edge Image Builder”)。
在安装了 Podman 的 Linux 系统上,创建目录并放置由 Kiwi 构建的基础映像:
mkdir -p $ELEM/eib_quickstart/base-images
cp /path/to/{micro-base-image-iso} $ELEM/eib_quickstart/base-images/
mkdir -p $ELEM/eib_quickstart/elementalcurl $REGISURL -o $ELEM/eib_quickstart/elemental/elemental_config.yamlcat << EOF > $ELEM/eib_quickstart/eib-config.yaml
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
outputImageName: elemental-image.iso
operatingSystem:
time:
timezone: Europe/London
ntp:
forceWait: true
pools:
- 2.suse.pool.ntp.org
servers:
- 10.0.0.1
- 10.0.0.2
isoConfiguration:
installDevice: /dev/vda
users:
- username: root
encryptedPassword: \$6\$jHugJNNd3HElGsUZ\$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
packages:
sccRegistrationCode: XXX
EOFtime部分是可选的,但强烈建议进行配置,以避免证书和时钟偏差带来的潜在问题。本示例中提供的值仅用于说明目的。请根据您的具体要求进行调整。未编码的密码为
eib。需要
sccRegistrationCode才能从官方源下载并安装必要的 RPM(或者,也可以手动旁加载elemental-register和elemental-system-agentRPM)。cat命令使用反斜杠 ($) 转义每个\,以便 Bash 不会对它们进行模板化处理。如果手动复制,请删除反斜杠。安装设备将在安装过程中被擦除。
podman run --privileged --rm -it -v $ELEM/eib_quickstart/:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-config.yaml如果您要引导物理设备,我们需要将映像刻录到 USB U 盘中。可以使用以下方式执行此操作:
sudo dd if=/eib_quickstart/elemental-image.iso of=/dev/<PATH_TO_DISK_DEVICE> status=progress1.8 引导下游节点 #
现在我们已经创建了安装媒体,可以使用它来引导下游节点。
对于您想要使用 Elemental 控制的每个系统,请添加安装媒体并引导设备。安装完成后,它将重启并自行注册。
如果您正在使用 UI 扩展,您应该会看到您的节点出现在“Inventory of Machines”中。
在看到登录提示之前,请勿移除安装媒体;在首次启动期间,系统仍会访问 USB U 盘上的文件。
1.9 创建下游集群 #
使用 Elemental 配置新集群时,我们需要创建两个对象。
- Linux
- UI 扩展
第一个是 MachineInventorySelectorTemplate。此对象允许我们指定集群与清单中机器之间的映射。
创建一个选择器,它将匹配清单中带有标签的任何机器:
cat << EOF > $ELEM/selector.yaml apiVersion: elemental.cattle.io/v1beta1 kind: MachineInventorySelectorTemplate metadata: name: location-123-selector namespace: fleet-default spec: template: spec: selector: matchLabels: locationID: '123' EOF将资源应用到集群:
kubectl apply -f $ELEM/selector.yaml获取机器名称并添加匹配的标签:
MACHINENAME=$(kubectl get MachineInventory -n fleet-default | awk 'NR>1 {print $1}') kubectl label MachineInventory -n fleet-default \ $MACHINENAME locationID=123创建一个简单的单节点 K3s 集群资源并将其应用到集群:
cat << EOF > $ELEM/cluster.yaml apiVersion: provisioning.cattle.io/v1 kind: Cluster metadata: name: location-123 namespace: fleet-default spec: kubernetesVersion: v1.35.4+k3s1 rkeConfig: machinePools: - name: pool1 quantity: 1 etcdRole: true controlPlaneRole: true workerRole: true machineConfigRef: kind: MachineInventorySelectorTemplate name: location-123-selector apiVersion: elemental.cattle.io/v1beta1 EOF kubectl apply -f $ELEM/cluster.yaml
创建这些对象后,您应该会看到一个新的 Kubernetes 集群使用您刚刚安装的新节点启动。
1.10 节点重置(可选) #
SUSE Rancher Elemental 支持执行“节点重置”的功能,当从 Rancher 中删除整个集群、从集群中删除单个节点或从机器清单中手动删除节点时,可以选择触发该功能。当您想要重置和清理任何孤立资源,并希望自动将清理后的节点带回机器清单以便重复使用时,这非常有用。默认情况下未启用此功能,因此任何被去除的系统都不会被清理(即数据不会被去除,任何 Kubernetes 集群资源将继续在下游集群上运行),并且需要人工干预来擦除数据并通过 Elemental 将机器重新注册到 Rancher。
如果您希望默认启用此功能,则需要确保您的 MachineRegistration 通过添加 config.elemental.reset.enabled: true 明确启用它,例如:
config:
elemental:
registration:
auth: tpm
reset:
enabled: true然后,所有使用此 MachineRegistration 注册的系统都将自动在其配置中接收 elemental.cattle.io/resettable: 'true' 注释。如果您希望在单个节点上手动执行此操作(例如,因为您现有的 MachineInventory 没有此注释,或者您已经部署了节点),您可以修改 MachineInventory 并添加 resettable 配置,例如:
apiVersion: elemental.cattle.io/v1beta1
kind: MachineInventory
metadata:
annotations:
elemental.cattle.io/os.unmanaged: 'true'
elemental.cattle.io/resettable: 'true'在 SUSE Edge 3.1 中,Elemental Operator 会在操作系统上放置一个标记,该标记将自动触发清理过程;它将停止所有 Kubernetes 服务,删除所有持久数据,卸载所有 Kubernetes 服务,清理任何剩余的 Kubernetes/Rancher 目录,并强制通过原始 Elemental MachineRegistration 配置重新注册到 Rancher。这是自动发生的,无需任何人工干预。被调用的脚本可以在 /opt/edge/elemental_node_cleanup.sh 中找到,并在放置标记后通过 systemd.path 触发,因此其执行是立即的。
使用 resettable 功能的前提是,从 Rancher 中删除节点/集群时,期望的行为是擦除数据并强制重新注册。在这种情况下肯定会丢失数据,因此只有在确定要执行自动重置时才使用此功能。
1.11 后续步骤 #
以下是使用本指南后建议研究的一些资源:
中的端到端自动化第 6 章 “Fleet”
中的其他网络配置选项第 9 章 “边缘网络”
2 使用 Edge Image Builder 的独立集群 #
Edge Image Builder (EIB) 是一款简化了为引导机器生成定制化、即开即用 (CRB) 磁盘镜像流程的工具,即使在完全隔离的环境中也能使用。EIB 用于为所有三种 SUSE Edge 部署足迹创建部署镜像,因为它足够灵活,既能提供最小化的自定义(例如添加用户或设置时区),也能提供全面配置的镜像(例如设置复杂的网络配置、部署多节点 Kubernetes 集群、部署客户工作负载,以及通过 Rancher/Elemental 和 SUSE Multi-Linux Manager 注册到集中式管理平台)。EIB 作为容器镜像运行,使其在不同平台间具有极高的可移植性,并确保所有必需的依赖项都是自包含的,对用于操作该工具的系统所安装的软件包影响极小。
对于多节点场景,EIB 会自动部署 MetalLB 和 Endpoint Copier Operator,以便使用相同构建镜像配置的主机能够自动加入 Kubernetes 集群。
有关更多信息,请阅读 Edge Image Builder 简介 (第 8 章 “Edge Image Builder”)。
Edge Image Builder 1.3.3.1 支持自定义 SUSE Linux Micro 6.2 镜像。 不支持较旧的版本,例如 SUSE Linux Enterprise Micro 5.5 或 6.0。
2.1 先决条件 #
一台运行 SLES 15 SP6 的 AMD64/Intel 64 构建主机(物理机或虚拟机)。
Podman 容器引擎
使用 Kiwi Builder 流程 (第 26 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 镜像”) 创建的 SUSE Linux Micro 6.2 SelfInstall ISO 映像
对于非生产用途,可以使用 openSUSE Leap 15.6 或 openSUSE Tumbleweed 作为构建主机。 只要有兼容的容器运行时,其他操作系统也可能可以运行。
2.1.1 获取 EIB 镜像 #
EIB 容器镜像已公开,可以通过在您的镜像构建主机上运行以下命令从 SUSE Edge 注册表下载:
podman pull registry.suse.com/edge/3.6/edge-image-builder:1.3.3.12.2 创建镜像配置目录 #
由于 EIB 在容器内运行,我们需要从主机挂载一个配置目录,以便您指定所需的配置,并且在构建过程中,EIB 可以访问任何所需的输入文件和支持工件。此目录必须遵循特定的结构。让我们创建它,假设该目录将存在于您的主目录中,并命名为“eib”:
export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR/base-images在上一步中,我们创建了一个“base-images”目录,用于存放 SUSE Linux Micro 6.2 输入镜像,现在让我们确保该镜像已复制到配置目录中:
cp /path/to/SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.iso在 EIB 运行期间,原始基础镜像 不会 被修改;系统会在 EIB 配置目录的根目录下创建一个包含所需配置的新的自定义版本。
此时的配置目录应如下所示:
└── base-images/
└── slemicro.iso2.3 创建镜像定义文件 #
定义文件描述了 Edge Image Builder 支持的大多数可配置选项,选项的完整示例可以在 此处 找到,我们建议您查看 上游构建镜像指南,以获取比我们下面要介绍的示例更全面的示例。让我们从一个非常基础的操作系统镜像定义文件开始:
cat << EOF > $CONFIG_DIR/iso-definition.yaml
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
EOF此定义指定我们正在为 AMD64/Intel 64 系统生成输出镜像。将用作进一步修改基础的镜像是一个名为 slemicro.iso 的 iso 镜像,预计位于 $CONFIG_DIR/base-images/slemicro.iso。它还概述了在 EIB 完成镜像修改后,输出镜像将被命名为 eib-image.iso,并默认驻留在 $CONFIG_DIR 中。
现在我们的目录结构应如下所示:
├── iso-definition.yaml
└── base-images/
└── slemicro.iso在接下来的章节中,我们将介绍几个常见操作的示例:
2.3.1 配置操作系统 (OS) #
EIB operatingSystem 部分旨在配置操作系统的安装位置、镜像大小等。
这是一个可选部分,除非应用了一个或多个自定义设置,否则不应包含该部分。
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-Base-RT-SelfInstall.iso
operatingSystem:
isoConfiguration:
installDevice: /dev/disk/by-id/ata-QEMU_HARDDISK_111-disk1 # first defined disk特定于类型的配置:根据所自定义镜像的类型,可以包含以下可选部分之一。
isoConfiguration- 可选;此部分中的配置仅适用于 ISO 映像。installDevice- 可选;指定应用作安装设备的磁盘。这必须是一个块设备,并且默认会自动擦除磁盘上找到的任何数据。 此外,指定此属性会触发 GRUB 覆盖,以自动安装操作系统,而不是提示用户开始安装,从而实现完全无人值守的自动化安装。如果省略,系统会提示用户从 GRUB 菜单中选择“安装”选项,并要求用户选择安装磁盘,并确认在此过程中将擦除该设备。注意installDevice部分中使用的设备可以指定为/dev/sda,或者使用/dev/disk/by-id、/dev/disk/by-path命名方式,以确保使用正确的设备。 如果使用 libvirt 虚拟机,则可以在为虚拟机创建磁盘时指定serial属性值(例如serial=111-disk1),以便将其用于installDevice值,并使用by-id命名方式,例如/dev/disk/by-id/ata-QEMU_HARDDISK_111-disk1(如果使用 ATA 设备,libvirt会自动为 ATA 设备添加ata-QEMU_HARDDISK_前缀,或为 virtio 设备添加virtio-前缀,有关更多信息,请参阅 #17670 virtio issue)。rawConfiguration- 可选;此部分中的配置仅适用于 RAW 镜像。diskSize- 可选;设置所需的原始磁盘镜像大小,EIB 会将生成的镜像调整为此大小。这一点很重要,以确保您的磁盘镜像足够大,能够容纳嵌入镜像中的任何工件。建议将其设置为略小于您的 SD 卡大小(如果直接写入磁盘,则为块设备大小),因为系统会在启动时自动扩展以填满块设备的大小。这是可选的,但强烈建议设置。指定为一个整数,并以“M”(兆字节)、“G”(吉字节)或“T”(太字节)作为后缀(例如)“32G”)。luksKey- 加密镜像必需;用于加密原始镜像的给定 LUKS 密钥,这是 EIB 完成构建过程所必需的。expandEncryptedPartition- 可选;默认禁用,启用后,会自动将加密分区扩展至其最大大小。例如,如果diskSize为25G且此字段为true,EIB 将在构建过程中将加密分区扩展至25G。
2.3.2 配置操作系统用户 #
EIB 允许您预配置具有登录信息(例如密码或 SSH 密钥)的用户,包括设置固定的 root 密码。作为本示例的一部分,我们将固定 root 密码,第一步是使用 OpenSSL 创建一个单向加密密码:
openssl passwd -6 SecurePassword这将输出类似以下内容:
$6$G392FCbxVgn[...]Y7zTXnC1然后,我们可以在定义文件中添加一个名为 operatingSystem 的部分,并在其中包含一个 users 数组。生成的文件应如下所示:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$G392FCbxVgn[...]Y7zTXnC12.3.3 配置操作系统时间 #
time 部分是可选的,但强烈建议进行配置,以避免证书和时钟偏差带来的潜在问题。EIB 将根据此处的参数配置 chronyd 和 /etc/localtime。
operatingSystem:
time:
timezone: Europe/London
ntp:
forceWait: true
pools:
- 2.suse.pool.ntp.org
servers:
- 10.0.0.1
- 10.0.0.2timezone以“地区/地点”格式指定时区(例如“欧洲/伦敦”)。可以通过在 Linux 系统上运行timedatectl list-timezones来找到完整列表。ntp - 定义与配置 NTP(使用 chronyd)相关的属性:
forceWait - 请求 chronyd 在启动其他服务之前尝试同步时间源,超时时间为 180 秒。
pools - 指定 chronyd 将用作数据源的池列表(使用
iburst以缩短初始同步所需的时间)。servers - 指定 chronyd 将用作数据源的服务器列表(使用
iburst以缩短初始同步所需的时间)。
本示例中提供的值仅供参考。请根据您的具体要求进行调整。
2.3.4 添加证书 #
存储在 certificates 目录中且扩展名为“.pem”或“.crt”的证书文件将被安装到节点系统范围的证书存储中:
.
├── definition.yaml
└── certificates
├── my-ca.pem
└── my-ca.crt有关更多信息,请参阅 “使用 TLS 证书保护通信”指南。
2.3.5 添加操作系统文件 #
放置在镜像配置目录中 os-files 目录下的文件会自动复制到所构建镜像的文件系统中。
复制时将保留完全相同的目录结构。
例如,如果文件存在于名为 os-files/etc 的子目录中,它将被放置在所构建镜像的 /etc 目录中。
如果 os-files 目录存在,它不能为空。
.
├── definition.yaml
└── os-files
└── etc
└── ssh
└── sshd_config2.3.6 配置 RPM 软件包 #
EIB 的主要功能之一是提供一种机制,将额外的软件包添加到镜像中,以便在安装完成后,系统能够立即利用已安装的软件包。EIB 允许用户指定以下内容:
镜像定义列表中按名称列出的软件包
用于搜索这些软件包的网络存储库
用于搜索官方 SUSE 存储库中列出软件包的 SUSE 客户中心 (SCC) 凭据
通过
$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.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$G392FCbxVgn[...]Y7zTXnC1
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 > $CONFIG_DIR/rpms/gpg-keys/nvidia.gpg通过此方法添加额外的 RPM 旨在用于添加受支持的第三方组件或用户提供(并维护)的软件包;此机制不应用于添加通常在 SUSE Linux Micro 上不受支持的软件包。如果使用此机制添加来自 openSUSE 存储库(不受支持)的组件(包括来自较新版本或服务包的组件),您最终可能会得到不受支持的配置,特别是当依赖项解析导致操作系统核心部分被替换时,即使生成的系统看起来运行正常。如果您不确定,请联系您的 SUSE 代表,以协助确定您所需配置的可支持性。
2.3.7 配置 Kubernetes 集群和用户工作负载 #
EIB 的另一个功能是能够使用它来自动化部署“就地引导”(即不需要任何形式的集中式管理基础设施来协调)的单节点和多节点高可用 Kubernetes 集群。这种方法背后的主要驱动因素是针对隔离部署或网络受限环境,但它也可用作快速启动独立集群的一种方式,即使在可以使用完整且不受限制的网络访问的情况下也是如此。
此方法不仅能够部署自定义操作系统,还能够指定 Kubernetes 配置、通过 Helm chart 提供的任何额外分层组件,以及通过提供的 Kubernetes 清单提供的任何用户工作负载。然而,使用此方法背后的设计原则是我们默认假设用户想要进行隔离部署。因此,镜像定义中指定的任何项目都将被拉取到镜像中,其中包括用户提供的工作负载。EIB 确保定义所需的任何已发现镜像都会被复制到本地,并由生成的已部署系统中的嵌入式镜像注册表提供服务。
在下一个示例中,我们将采用现有的镜像定义并指定 Kubernetes 配置(在此示例中,它没有列出系统及其角色,因此我们默认假设为单节点),这将指示 EIB 配置单节点 RKE2 Kubernetes 集群。为了展示用户提供的工作负载(通过清单)和分层组件(通过 Helm)部署的自动化,我们将通过 SUSE Edge Helm chart 安装 KubeVirt,并通过 Kubernetes 清单安装 NGINX。我们需要添加到现有镜像定义中的额外配置如下:
kubernetes:
version: v1.35.4+rke2r1
manifests:
urls:
- https://k8s.io/examples/application/nginx-app.yaml
helm:
charts:
- name: kubevirt
version: 306.0.2+up0.7.0
repositoryName: suse-edge
repositories:
- name: suse-edge
url: oci://registry.suse.com/edge/charts最终的完整定义文件现在应如下所示:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$G392FCbxVgn[...]Y7zTXnC1
packages:
packageList:
- nvidia-container-toolkit
additionalRepos:
- url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
kubernetes:
version: v1.35.4+k3s1
manifests:
urls:
- https://k8s.io/examples/application/nginx-app.yaml
helm:
charts:
- name: kubevirt
version: 306.0.2+up0.7.0
repositoryName: suse-edge
repositories:
- name: suse-edge
url: oci://registry.suse.com/edge/charts2.3.8 配置网络 #
在本快速入门的最后一个示例中,让我们配置当系统使用 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: 192.168.122.1
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 钩子将通用配置应用于所有节点 - 有关更多详细信息,请参阅 网络指南 (第 9 章 “边缘网络”)。
生成的文件结构应如下所示:
├── iso-definition.yaml
├── base-images/
│ └── slemicro.iso
└── network/
└── host1.local.yaml我们刚刚创建的网络配置将被解析,必要的 NetworkManager 连接文件将自动生成并插入到 EIB 将创建的新安装镜像中。这些文件将在主机配置期间应用,从而形成完整的网络配置。
2.4 构建镜像 #
现在我们已经有了基础镜像和供 EIB 使用的镜像定义,让我们继续构建镜像。为此,我们只需使用 podman 调用带有“build”命令的 EIB 容器,并指定定义文件:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file iso-definition.yaml命令的输出应类似于:
Setting up Podman API listener...
Downloading file: dl-manifest-1.yaml 100% (498/498 B, 9.5 MB/s)
Pulling selected Helm charts... 100% (1/1, 43 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% (3/3, 10 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% (657/657 MB, 48 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (368/368 MB, 48 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (35/35 MB, 50 MB/s)
Downloading file: sha256sum-amd64.txt 100% (4.3/4.3 kB, 6.2 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso构建的 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/ 中创建一个带时间戳的文件夹,其中包含构建日志、构建期间使用的工件,以及包含添加到 CRB 镜像的所有脚本和工件的 combustion 和 artefacts 目录。
此目录的内容应如下所示:
├── 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:<version>-registry.tar.zst
│ │ │ ├── rancher_kubectl:<version>-registry.tar.zst
│ │ │ └── registry.suse.com_suse_sles_15.6_virt-operator:<version>-registry.tar.zst
│ │ │── rpms/
│ │ │ └── rpm-repo
│ │ │ ├── addrepo0
│ │ │ │ ├── nvidia-container-toolkit-<version>.rpm
│ │ │ │ ├── nvidia-container-toolkit-base-<version>.rpm
│ │ │ │ ├── libnvidia-container1-<version>.rpm
│ │ │ │ └── libnvidia-container-tools-<version>.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.yaml
│ ├── createrepo.log
│ ├── eib-build.log
│ ├── embedded-registry.log
│ ├── helm
│ │ └── kubevirt
│ │ └── kubevirt-0.4.0.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 是包含相关信息的第一个日志。从那里,它将引导您找到失败的组件进行调试。
此时,您应该拥有一个可直接使用的镜像,它将:
部署 SUSE Linux Micro 6.2
配置 root 密码
安装
nvidia-container-toolkit软件包配置嵌入式容器注册表以在本地提供内容
安装单节点 RKE2
配置静态网络
安装 KubeVirt
部署用户提供的清单
2.5 调试镜像构建过程 #
如果镜像构建过程失败,请参考 上游调试指南。
2.6 测试您新构建的镜像 #
有关如何测试新构建的 CRB 镜像的说明,请参考 上游镜像测试指南。
3 SUSE Multi-Linux Manager #
SUSE Edge 3.6 (5.0.6) 中包含的 SUSE Multi-Linux Manager 版本尚不支持 SUSE Linux Micro 6.2。它将在未来的 SUSE Edge 3.6 版本中进行更新并提供支持。
SUSE Multi-Linux Manager 包含在 SUSE Edge 中,旨在提供自动化和控制功能,以确保您的边缘部署中所有节点上的 SUSE Linux Micro 作为底层操作系统始终保持最新状态。它还可用于管理 Kubernetes,以及管理部署在您边缘节点上、基于 Kubernetes 的应用程序。
本快速入门指南旨在帮助您尽快熟悉 SUSE Multi-Linux Manager,目标是为您的边缘节点提供操作系统更新。本快速入门指南不讨论诸如调整存储大小、创建和管理用于暂存目的的额外软件频道,或为大型部署管理用户、系统组和组织等主题。对于生产环境使用,我们强烈建议您熟悉全面的 SUSE Multi-Linux Manager 文档。
要有效地使用 SUSE Multi-Linux Manager,需要执行以下步骤来准备 SUSE Edge:
部署并配置 SUSE Multi-Linux Manager Server。
同步 SUSE Linux Micro 软件包储存库。
创建系统组。
创建激活密钥。
使用 Edge Image Builder 准备用于 SUSE Multi-Linux Manager 注册的安装介质
3.1 部署 SUSE Multi-Linux Manager Server #
如果您已经运行了 SUSE Multi-Linux Manager 5.1 实例,则可以跳过此步骤。
您可以在专用物理服务器上、在您自己硬件上的虚拟机中或在云中运行 SUSE Multi-Linux Manager Server。针对受支持的公有云提供了预配置的 SUSE Multi-Linux Server 虚拟机镜像。
在本快速入门中,我们使用 SUSE-Manager-Server.x86_64-5.0.4-Qcow-5.0-2025-04.qcow2 的“qcow2”镜像 AMD64/Intel 64,您可以在 https://www.suse.com/download/suse-manager/ 或 SUSE 客户中心找到该镜像。此镜像可在 KVM 等超级管理程序上作为虚拟机运行。请务必检查是否有最新版本的镜像,并将其用于新安装。
您也可以在任何其他受支持的硬件架构上安装 SUSE Multi-Linux Manager Server。在这种情况下,请选择与您的硬件架构相匹配的镜像。
下载镜像后,创建一个至少满足以下最低硬件规格的虚拟机:
16 GB RAM
4 个物理或虚拟核心
一个至少 100 GB 的额外块设备
使用 qcow2 镜像时,无需安装操作系统。您可以直接将该镜像附加为根分区。
您需要设置网络,以便边缘节点稍后能够使用包含完全限定域名(“FQDN”)的主机名访问 SUSE Multi-Linux Manager Server!
首次启动 SUSE Multi-Linux Manager 时,您需要执行一些初始配置:
选择您的键盘布局
接受该许可协议。
选择您所在的时区。
输入操作系统的 root 密码
接下来的步骤需要以“root”用户身份执行:
对于下一步,您需要 SUSE Multi-Linux Manager Extension 的注册代码,您可以在 SUSE 客户中心找到该注册代码。相同的代码可用于注册 SUSE Linux Micro 和 SUSE Multi-Linux Manager:
注册 SUSE Linux Micro:
transactional-update register -r <REGCODE> -e <your_email>注册 SUSE Multi-Linux Manager:
transactional-update register -p SUSE-Manager-Server/5.0/x86_64 -r <REGCODE>产品字符串取决于您的硬件架构!例如,如果您在 64 位 Arm 系统上使用 SUSE Multi-Linux Manager,则字符串为“SUSE-Manager-Server/5.0/aarch64”。
重引导
更新系统:
transactional-update除非没有更改,否则请重新启动以应用更新。
SUSE Multi-Linux Manager 通过由 Podman 管理的容器提供。mgradm 命令会为您处理设置和配置。
非常重要的一点是,您的 SUSE Multi-Linux Manager Server 必须配置有完全限定域名 (“FQDN”) 的主机名,以便您想要管理的边缘节点能够在您的网络中正确解析它!
在安装和配置 SUSE Multi-Linux Manager Server 容器之前,您需要准备之前添加的额外块设备。为此,您需要知道虚拟机分配给该设备的名称。例如,如果块设备是 /dev/vdb,您可以使用以下命令将其配置为供 SUSE Multi-Linux Manager 使用:
mgr-storage-server /dev/vdb部署 SUSE Multi-Linux Manager:
mgradm install podman <FQDN>提供 CA 证书的口令。此口令应与您的登录口令不同。您通常不需要在以后输入它,但应将其记下。
提供“admin”用户的口令。这是用于登录 SUSE Multi-Linux Manager 的初始用户。您稍后可以创建具有完全或受限权限的其他用户。
3.2 配置 SUSE Multi-Linux Manager #
部署完成后,您可以使用之前提供的主机名登录 SUSE Multi-Linux Manager Web UI。初始用户为“admin”。使用您在上一步中提供的口令。
在下一步中,您需要使用组织凭据,您可以在 SUSE 客户中心中,位于您组织的“Users”选项卡下第二个子标签页中找到这些凭据。有了这些凭据,SUSE Multi-Linux Manager 就可以同步您拥有订阅的所有产品。
选择 Admin > Setup Wizard。
在 Organization Credentials 选项卡上,使用您在 SUSE Customer Center 中找到的 Username 和 Password 创建一个新的凭据。
转至下一个选项卡 SUSE Products。您需要等待与 SUSE Customer Center 的首次数据同步完成。
列表填充完成后,使用过滤器仅显示“Micro 6.2”。
请在 下勾选适用于您边缘节点运行的硬件架构(x86_64 或 aarch64)的 SUSE Linux Micro 6.2 复选框。
单击 Add Products。这将添加 SUSE Linux Micro 的主软件包储存库(“频道”),并自动将 SUSE Manager 客户端工具的频道作为子频道添加。
根据您的互联网连接情况,首次同步可能需要一些时间。您可以立即开始执行后续步骤:
在 Systems > System Groups 下,至少创建一个系统在加入时会自动纳入的组。组是对系统进行分类的重要方式,因此您可以一次性对整组系统应用配置或操作。它们在概念上类似于 Kubernetes 中的标签。
点击 + Create Group
提供一个短名称(例如“Edge Nodes”)和详细描述。
在 Systems > Activation Keys 下,至少创建一个激活密钥。激活密钥可以被视为一种配置控制文件,当系统加入 SUSE Multi-Linux Manager 时,该控制文件会自动应用于这些系统。如果您希望将某些边缘节点添加到不同的组或使用不同的配置,您可以为它们创建单独的激活密钥,并在稍后的 Edge Image Builder 中使用它们来创建自定义安装介质。
激活密钥的一个典型高级用例是将您的测试集群分配到包含最新更新的软件频道,并将您的生产集群分配到仅在您于测试集群中测试过这些最新更新后才会获取它们的软件频道。
点击 + Create Key
选择一个简短的描述,例如“Edge Nodes”。 提供一个标识该密钥的唯一名称,例如,对于具有 AMD64/Intel 64 硬件架构的边缘节点,使用“edge-x86_64”。 密钥会自动添加数字前缀。对于默认组织,该数字始终为“1”。如果您在 SUSE Multi-Linux Manager 中创建了其他组织并为它们创建了密钥,则该数字可能会有所不同。
如果您尚未创建任何克隆的软件频道,则可以将“基础频道”(Base Channel) 的设置保留为“SUSE Manager Default”。这将自动为您的边缘节点分配正确的 SUSE 更新储存库。
在“子频道”(Child Channel) 中,为您的激活密钥所使用的硬件架构选择“包含推荐”(include recommended) 滑块。这将添加“SUSE-Manager-Tools-For-SL-Micro-6.2”频道。
在“组”(Groups) 选项卡上,添加您之前创建的组。所有使用此激活密钥加入的节点都将自动添加到该组中。
3.3 使用 Edge Image Builder 创建自定义安装映像 #
要使用 Edge Image Builder,您只需要一个可以启动基于 Linux 的 podman 容器的环境。
对于最小化的实验室设置,我们实际上可以使用 SUSE Multi-Linux Manager Server 所在的同一台虚拟机。请确保虚拟机中有足够的磁盘空间!这不建议用于生产环境。请参阅 第 2.1 节 “先决条件” 以了解我们测试过 Edge Image Builder 的主机操作系统。
以 root 用户身份登录您的 SUSE Multi-Linux Manager Server 主机。
拉取 Edge Image Builder 容器:
podman pull registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1创建目录 /opt/eib 和子目录 base-images:
mkdir -p /opt/eib/base-images在本快速入门中,我们使用 SUSE Linux Micro 映像的“self-install”版本。该映像稍后可以写入物理 USB 闪存驱动器,您可以使用它在物理服务器上进行安装。如果您的服务器具有通过 BMC(基板管理控制器)远程挂载安装 .iso 映像的选项,您也可以使用该方法。最后,该映像也可以与大多数虚拟化工具一起使用。
如果您想将镜像直接预加载到物理节点,或者直接从虚拟机启动它,您也可以使用“raw”镜像类型。
您可以在 SUSE 客户中心或 https://www.suse.com/download/sle-micro/ 上找到这些镜像。
下载或复制镜像 SL-Micro.x86_64-6.2-Default-SelfInstall-GM.install.iso 到 base-images 目录,并将其命名为“slemicro.iso”。
在基于 Arm® 的构建主机上构建 AArch64 镜像,是在 SUSE Edge 3.6 中的一项技术预览。它很可能会起作用,但目前尚不支持。如果您想尝试一下,您需要在 64 位 Arm® 机器上运行 Podman,并且需要将所有示例和代码片段中的“x86_64”替换为“aarch64”。
在 /opt/eib 中,创建一个名为 iso-definition.yaml 的文件。这是您用于 Edge Image Builder 的构建定义。
这是一个简单的示例,它安装 SL Micro 6.2,设置 root 密码、一个附加用户和键盘映射,启动 Cockpit 图形界面,并将您的节点注册到 SUSE Multi-Linux Manager:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
createHomeDir: true
encryptedPassword: $6$aaBTHyqDRUMY1HAp$pmBY7.qLtoVlCGj32XR/Ogei4cngc3f4OX7fwBD/gw7HWyuNBOKYbBWnJ4pvrYwH2WUtJLKMbinVtBhMDHQIY0
- username: admin
createHomeDir: true
encryptedPassword: $6$8EGZXU1iFcLiHHxk$Hs3nVtzO.yZhApT.YBHaNvLRZvXG3Iv/km92BtiNiGXhSSUG0ZbNHxlm7c//ROFj3W9M5xIkB.RLQpPKOFxP91
keymap: de
systemd:
enable:
- cockpit.socket
packages:
noGPGCheck: true
suma:
host: ${fully qualified hostname of your SUSE Multi-Linux Manager Server}
activationKey: 1-edge-x86_64Edge Image Builder 还可以配置网络、在节点上自动安装 Kubernetes,甚至通过 Helm chart 部署应用程序。有关更全面的示例,请参阅 第 2 章 “使用 Edge Image Builder 的独立集群”。
对于 baseImage,请指定您要在 base-images 目录中使用的 ISO 的实际名称。
在此示例中,root 密码将为“root”。有关为您想要使用的安全密码创建密码哈希的信息,请参阅 第 2.3.2 节 “配置操作系统用户”。
由于 Cockpit 禁止以 root 用户身份连接,因此需要一个附加用户。在此示例中,该用户为“admin”,密码为“admin”。
将键盘映射设置为您希望系统在安装后使用的实际键盘布局。
如前所述,您的 SUSE Multi-Linux Manager 主机需要一个完全限定的主机名,该主机名可以在您的边缘节点启动的网络中解析。
activationKey 的值需要与您在 SUSE Multi-Linux Manager 中创建的密钥相匹配。
要构建一个在安装后自动将您的边缘节点注册到 SUSE Multi-Linux Manager 的安装镜像,您还需要准备两个工件:
用于安装 SUSE Multi-Linux Manager 管理代理的 Salt minion 软件包
您的 SUSE Multi-Linux Manager 服务器的 CA 证书
3.3.1 下载 venv-salt-minion 软件包 #
在 /opt/eib 中,创建一个子目录 rpms。
将软件包 venv-salt-minion 从您的 SUSE Multi-Linux Manager 服务器下载到该目录中。您可以选择通过 Web UI 获取它,方法是在 Software > Channel List 下找到该软件包并从 SUSE-Manager-Tools … 频道下载,或者使用 curl 等工具从 SUSE Multi-Linux Manager “启动储存库”下载:
curl -O http://${HOSTNAME_OF_SUSE_MANAGER}/pub/repositories/slmicro/6/1/bootstrap/x86_64/venv-salt-minion-3006.0-8.1.x86_64.rpm如果已经发布了更新的版本,实际的软件包名称可能会有所不同。如果有多个软件包可供选择,请始终选择最新的版本。
为了解决 SUSE Multi-Linux Manager 发行说明 中记录的一个问题,您还需要将最新版本的构建密钥软件包放入 rpms 目录中(编写本文档时为 suse-build-key-12.0-slfo.1.1_3.1.noarch.rpm)。您可以在 SUSE Multi-Linux Manager 的 Software 部分,通过 SL Micro 的 Pool 频道的 Packages 选项卡找到它。在 Details 视图中有一个 Download 按钮。
3.4 下载 SUSE Multi-Linux Manager CA 证书 #
在 /opt/eib 中,创建一个子目录 certificates
将 CA 证书从 SUSE Multi-Linux Manager 下载到该目录中:
curl -O http://${HOSTNAME_OF_SUSE_MANAGER}/pub/RHN-ORG-TRUSTED-SSL-CERT您必须将证书重命名为 RHN-ORG-TRUSTED-SSL-CERT.crt。Edge Image Builder 随后将确保在安装过程中在边缘节点上安装并激活该证书。
现在您可以运行 Edge Image Builder:
cd /opt/eib
podman run --rm -it --privileged -v /opt/eib:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file iso-definition.yaml如果您为 YAML 定义文件使用了不同的名称,或者想要使用不同版本的 Edge Image Builder,则需要相应地调整命令。
构建完成后,您将在 /opt/eib 目录中找到名为 eib-image.iso 的安装 ISO。
该镜像现在可用于部署将尝试向 SUSE Multi-Linux Manager 注册的节点。
节点完全安装后,您将在 SUSE Multi-Linux Manager 的 Salt/Keys 部分中看到其密钥列为 pending。一旦您接受了该密钥,节点将自动加入 SUSE Multi-Linux Manager,并在该过程完成后显示在 Systems 列表中。它将拥有您在激活密钥中提供的系统组。
在应用任何其他配置之前,您应该安排一次重启。
请注意,接受密钥的过程可以如 此处 所述,通过使用白名单来完全自动化。
第 II 部分 组件 #
Edge 组件列表
- 4 Rancher
请参阅 https://ranchermanager.docs.rancher.com/v2.14. 处的 Rancher 文档
- 5 Rancher 仪表板扩展
扩展允许用户、开发人员、合作伙伴和客户扩展和增强 Rancher UI。SUSE Edge 提供 KubeVirt 仪表板扩展。
- 6 Fleet
Fleet 是一个容器管理和部署引擎,旨在为用户提供对本地群集的更多控制,并通过 GitOps 进行持续监控。Fleet 不仅专注于扩展能力,还为用户提供了高度的控制和可见性,以监控集群上安装的确切内容。
- 7 SUSE Linux Micro
- 8 Edge Image Builder
请参阅 官方储存库。
- 9 边缘网络
本节介绍了 SUSE Edge 解决方案中的网络配置方法。 我们将展示如何在 SUSE Linux Micro 上以声明方式配置 NetworkManager,并解释相关工具是如何集成的。
- 10 Elemental
Elemental 是一套软件栈,支持通过 Kubernetes 实现集中式、完全云原生的操作系统管理。Elemental 栈由多个组件组成,这些组件要么驻留在 Rancher 本身,要么驻留在边缘节点上。核心组件包括:
- 11 K3s
K3s 是一款高可用、经过认证的 Kubernetes 发行版,专为无人值守、资源受限、远程位置或物联网设备内部的生产工作负载而设计。
- 12 RKE2
请参阅 RKE2 官方文档。
- 13 SUSE Storage
SUSE Storage 是适用于 Kubernetes 的轻量级、可靠且易于使用的分布式块存储系统。它是一款基于 Longhorn 的产品,Longhorn 是最初由 Rancher Labs 开发并目前在 CNCF 下孵化的开源项目。
- 14 SUSE Security
SUSE Security 是一款适用于 Kubernetes 的安全解决方案,它在一个统一的软件包中提供 L7 网络安全、运行时安全、供应链安全和合规性检查。
- 15 MetalLB
请参阅 MetalLB 官方文档。
- 16 端点复制器操作员
端点复制器操作员 是一个 Kubernetes 操作员,其目的是创建 Kubernetes 服务和端点的副本并保持它们同步。
- 17 边缘虚拟化
本节介绍如何使用边缘虚拟化在边缘节点上运行虚拟机。边缘虚拟化专为轻量级虚拟化用例而设计,旨在利用通用的工作流程来部署和管理虚拟化及容器化应用程序。
- 18 系统升级控制器
请参阅 系统升级控制器文档。
- 19 升级控制器
一种能够对以下 SUSE Edge 平台组件执行升级的 Kubernetes 控制器:
- 20 SUSE Multi-Linux Manager
SUSE Multi-Linux Manager 包含在 SUSE Edge 中,旨在提供自动化和控制功能,以确保边缘部署中所有节点的 SUSE Linux Micro 作为底层操作系统始终保持最新状态。
4 Rancher #
请参阅 https://ranchermanager.docs.rancher.com/v2.14. 处的 Rancher 文档
Rancher 是一个功能强大的开源 Kubernetes 管理平台,可简化跨多个环境的 Kubernetes 集群的部署、操作和监控。无论您是在本地、云端还是边缘管理集群,Rancher 都能为您所有的 Kubernetes 需求提供一个统一且集中的平台。
4.1 Rancher 的主要功能 #
多集群管理:Rancher 直观的界面让您可以从任何地方(公有云、私有数据中心和边缘位置)管理 Kubernetes 集群。
安全和合规性:Rancher 在您的 Kubernetes 环境中强制执行安全策略、基于角色的访问控制 (RBAC) 和合规性标准。
简化的集群操作:Rancher 自动执行集群配置、升级和故障排除,从而简化了各种规模团队的 Kubernetes 操作。
集中式应用程序目录:Rancher 应用程序目录提供了多种 Helm Chart 和 Kubernetes Operator,使部署和管理容器化应用程序变得简单。
持续交付:Rancher 支持 GitOps 和 CI/CD 流水线,实现自动化和简化的应用程序交付流程。
4.2 Rancher 在 SUSE Edge 中的使用 #
Rancher 为 SUSE Edge 堆栈提供了多项核心功能:
4.2.1 集中式 Kubernetes 管理 #
在具有大量分布式集群的典型边缘部署中,Rancher 充当管理这些 Kubernetes 集群的中央控制平面。它提供了一个用于配置、升级、监控和故障排除的统一界面,从而简化操作并确保一致性。
4.2.2 简化的集群部署 #
Rancher 简化了轻量级 SUSE Linux Micro 操作系统上的 Kubernetes 集群创建,通过强大的 Kubernetes 功能轻松实现边缘基础设施的部署。
4.2.3 应用程序部署和管理 #
集成的 Rancher 应用程序目录可以简化跨 SUSE Edge 集群部署和管理容器化应用程序的过程,从而实现无缝的边缘工作负载部署。
4.2.4 安全与策略执行 #
Rancher 提供基于策略的治理工具、基于角色的访问控制 (RBAC) 以及与外部身份验证提供程序的集成。这有助于 SUSE Edge 部署保持安全性和合规性,这在分布式环境中至关重要。
4.3 最佳实践 #
4.3.1 GitOps #
Rancher 将 Fleet 作为内置组件包含在内,允许使用存储在 git 中的代码来管理集群配置和应用程序部署。
4.3.2 可观测性 #
Rancher 包含内置的监控和日志记录工具(如 Prometheus 和 Grafana),可全面了解集群的健康状况和性能。
4.4 使用 Edge Image Builder 进行安装 #
SUSE Edge 正在使用 第 8 章 “Edge Image Builder” 来定制基础 SUSE Linux Micro 操作系统镜像。 请遵循 第 25.6 节 “Rancher 安装” 以在 EIB 配置的 Kubernetes 集群之上进行 Rancher 的隔离的安装。
4.5 其他资源 #
5 Rancher 仪表板扩展 #
扩展允许用户、开发人员、合作伙伴和客户扩展和增强 Rancher UI。SUSE Edge 提供 KubeVirt 仪表板扩展。
有关 Rancher 仪表板扩展的一般信息,请参阅 Rancher documentation。
5.1 安装 #
所有 SUSE Edge 3.6 组件(包括仪表板扩展)均作为 OCI 制品分发。要安装 SUSE Edge 扩展,您可以使用 Rancher 仪表板 UI、Helm 或 Fleet:
5.1.1 使用 Rancher 仪表板 UI 安装 #
点击导航侧边栏 配置 部分中的 扩展。
在“扩展”页面上,点击右上角的三点菜单并选择 管理储存库。
每个扩展都通过其自己的 OCI 制品进行分发。它们可从 SUSE Edge Helm charts 储存库获取。
在 储存库页面 上,点击
Create。在表单中,指定储存库名称和 URL,然后点击
Create。SUSE Edge Helm charts 储存库 URL:
oci://registry.suse.com/edge/charts您可以看到扩展储存库已添加到列表中,并且处于
Active状态。导航回导航侧边栏 配置 部分中的 扩展。
在 可用 选项卡中,您可以查看可供安装的扩展。
在扩展卡片上,点击
Install并确认安装。扩展安装完成后,Rancher UI 会提示重新加载页面,如
https://ranchermanager.docs.rancher.com/v2.14/integrations-in-rancher/rancher-extensions#installing-extensions中所述。
5.1.2 使用 Helm 安装 #
# KubeVirt extension
helm install kubevirt-dashboard-extension oci://registry.suse.com/edge/charts/kubevirt-dashboard-extension --version 306.0.4+up1.3.3 --namespace cattle-ui-plugin-system扩展需要安装在 cattle-ui-plugin-system 名称空间中。
扩展安装完成后,需要重新加载 Rancher 仪表板 UI。
5.1.3 使用 Fleet 安装 #
使用 Fleet 安装仪表板扩展需要定义一个 gitRepo 资源,该资源指向包含自定义 fleet.yaml 捆绑包配置文件的 Git 储存库。
# KubeVirt extension fleet.yaml
defaultNamespace: cattle-ui-plugin-system
helm:
releaseName: kubevirt-dashboard-extension
chart: oci://registry.suse.com/edge/charts/kubevirt-dashboard-extension
version: "306.0.4+up1.3.3"releaseName 属性是必需的,并且需要与扩展名称匹配,才能正确安装扩展。
cat <<- EOF | kubectl apply -f -
apiVersion: fleet.cattle.io/v1alpha1
metadata:
name: edge-dashboard-extensions
namespace: fleet-local
spec:
repo: https://github.com/suse-edge/fleet-examples.git
branch: main
paths:
- fleets/kubevirt-dashboard-extension/
EOF有关详细信息,请参见 第 6 章 “Fleet” 和 fleet-examples 储存库。
扩展安装完成后,它们会列在 扩展 部分下的 已安装 选项卡中。由于它们不是通过 Apps/Marketplace 安装的,因此它们被标记为 Third-Party 标签。
5.2 KubeVirt 仪表板扩展 #
KubeVirt 扩展为 Rancher 仪表板 UI 提供了基本的虚拟机管理功能。其功能在 第 17.7.2 节 “使用 KubeVirt Rancher 仪表板扩展” 中有描述。
6 Fleet #
Fleet 是一个容器管理和部署引擎,旨在为用户提供对本地群集的更多控制,并通过 GitOps 进行持续监控。Fleet 不仅专注于扩展能力,还为用户提供了高度的控制和可见性,以监控集群上安装的确切内容。
Fleet 可以管理来自 Git 的原始 Kubernetes YAML、Helm chart、Kustomize 或这三者的任意组合的部署。无论来源如何,所有资源都会被动态转换为 Helm chart,并使用 Helm 作为引擎在集群中部署所有资源。因此,用户可以享受对其集群的高度控制、一致性和可审计性。
有关 Fleet 工作原理的信息,请参阅 Fleet 架构。
6.1 使用 Helm 安装 Fleet #
Fleet 内置于 Rancher 中,但也可以使用 Helm 作为独立应用程序,在任何 Kubernetes 集群上 安装。
6.2 在 Rancher 中使用 Fleet #
Rancher 使用 Fleet 在受管集群中部署应用程序。Fleet 的持续交付引入了大规模 GitOps,旨在管理运行在大量集群上的应用程序。
Fleet 作为 Rancher 的集成部分表现出色。通过 Rancher 管理的集群会在安装/导入过程中自动部署 Fleet agent,并且该集群可立即由 Fleet 进行管理。
6.3 在 Rancher UI 中访问 Fleet #
Fleet 在 Rancher 中预装,并由 Rancher UI 中的 持续交付 选项进行管理。
持续交付部分包含以下项目:
6.3.1 仪表板 #
所有工作区中所有 GitOps 储存库的概览页面。仅显示包含储存库的工作区。
6.3.2 Git 储存库 #
所选工作区中的 GitOps 储存库列表。使用页面顶部的下拉列表选择活动工作区。
6.3.3 群集 #
托管集群列表。默认情况下,所有 Rancher 托管的集群都会添加到 fleet-default 工作区中。fleet-local 工作区包含本地(管理)群集。在此处,您可以 Pause 或 Force update 集群,或将集群移动到另一个工作区。编辑集群允许更新用于对集群进行分组的标签和注释。
6.3.4 集群组 #
本节允许使用选择器对工作区内的集群进行自定义分组。
6.3.5 高级 #
“高级”部分允许管理工作区和其他相关的 Fleet 资源。
6.4 使用 Rancher 仪表板通过 Rancher 和 Fleet 安装 KubeVirt 的示例 #
创建一个包含
fleet.yaml文件的 Git 储存库:defaultNamespace: kubevirt helm: chart: "oci://registry.suse.com/edge/charts/kubevirt" version: "306.0.2+up0.7.0" # kubevirt namespace is created by kubevirt as well, we need to take ownership of it takeOwnership: true在 Rancher 仪表板中,导航至 ☰ > 持续交付 > Git 储存库 并点击
Add Repository。储存库创建向导将引导您完成 Git 储存库的创建。提供 名称、储存库 URL(引用在上一步中创建的 Git 储存库),并选择相应的分支或修订版本。对于更复杂的储存库,请指定 路径 以在单个储存库中使用多个目录。
单击
Next。在下一步中,您可以定义工作负载的部署位置。集群选择提供了几个基本选项:您可以选择不选择集群、选择所有集群,或者直接选择特定的托管集群或集群组(如果已定义)。“高级”选项允许通过 YAML 直接编辑选择器。
单击
Create。储存库已创建。从现在起,工作负载将在匹配储存库定义的集群上进行安装并保持同步。
6.5 调试与故障排除 #
“高级”导航部分提供了底层 Fleet 资源的概览。 Bundle 是一种用于编排 Git 资源的内部资源。当扫描 Git 存储库时,它会生成一个或多个 Bundle。
要查找与特定储存库相关的 Bundle,请转到 Git 储存库详细信息页面并点击 Bundles 选项卡。
对于每个集群,该 Bundle 会被应用到所创建的 BundleDeployment 资源中。要查看 BundleDeployment 详细信息,请点击 Git 储存库详细信息页面右上角的 Graph 按钮。
系统会加载一张 Repo > Bundles > BundleDeployments 的图表。点击图表中的 BundleDeployment 以查看其详细信息,并点击 Id 以查看 BundleDeployment YAML。
有关 Fleet 故障排除技巧的更多信息,请参阅 此处。
6.6 Fleet 示例 #
Edge 团队维护着一个 储存库,其中包含使用 Fleet 安装 Edge 项目的示例。
Fleet 项目包含一个 fleet-examples 储存库,涵盖了 Git 储存库结构 的所有用例。
7 SUSE Linux Micro #
SUSE Linux Micro 是一款适用于边缘计算的轻量级且安全的操作系统。它将 SUSE Linux Enterprise 的企业强化组件与开发人员需要的各种功能融入一套现代的不可变操作系统。从而形成一个可靠的基础设施平台,不仅具有最佳的合规性,而且易于使用。
7.1 SUSE Edge 如何使用 SUSE Linux Micro? #
我们将 SUSE Linux Micro 用作我们平台堆栈的基础操作系统。这为我们提供了一个安全、稳定且精简的基础,以便在其上进一步构建。
SUSE Linux Micro 的独特之处在于它使用文件系统 (Btrfs) 快照,以便在升级出现问题时轻松回滚。即使在出现问题且无法进行物理访问的情况下,这也允许对整个平台进行安全的远程升级。
7.2 最佳实践 #
7.2.1 安装媒体 #
SUSE Edge 使用 Edge Image Builder (第 8 章 “Edge Image Builder”) 来预配置 SUSE Linux Micro 自安装安装镜像。
7.2.2 本地管理 #
SUSE Linux Micro 附带 Cockpit,允许通过 Web 应用程序对主机进行本地管理。
此服务默认处于禁用状态,但可以通过启用 systemd 服务 cockpit.socket 来启动。
由于 Cockpit 默认禁止 root 登录,建议创建具有管理权限的用户。有关更多信息,请参阅 SUSE Linux Micro 官方文档。
7.3 已知问题 #
目前 SUSE Linux Micro 中没有可用的桌面环境,但正在开发容器化解决方案。
8 Edge Image Builder #
请参阅 官方储存库。
Edge Image Builder (EIB) 是一款用于简化生成定制化、即启即用 (CRB) 磁盘镜像以引导机器的工具。这些镜像支持通过单个镜像实现整个 SUSE 软件栈的端到端部署。
虽然 EIB 可以为所有配置场景创建 CRB 镜像,但 EIB 在网络受限或完全隔离的部署中展现出了巨大的价值。
8.1 SUSE Edge 如何使用 Edge Image Builder? #
SUSE Edge使用 EIB 来简化和快速配置用于各种场景的定制化 SUSE Linux Micro 镜像。这些场景包括对虚拟机和裸机的引导,具体如下:
完全隔离环境下的 K3s/RKE2 Kubernetes 部署(单节点和多节点)
完全隔离环境下的 Helm chart 和 Kubernetes 清单部署
通过 Elemental API 注册到 Rancher
Metal3
定制化网络(例如,静态 IP、主机名、VLAN、绑定等)
定制化操作系统配置(例如,用户、组、密码、SSH 密钥、代理、NTP、自定义 SSL 证书等)
主机级和侧载 RPM 包的隔离安装(包括依赖项解析)
注册到 SUSE Multi-Linux Manager 进行操作系统管理
嵌入式容器镜像
内核命令行参数
在引导时启用/禁用的 Systemd 单元
用于任何手动任务的自定义脚本和文件
8.2 入门 #
有关 Edge Image Builder 使用和测试的综合文档可以在 此处 找到。
此外,请参阅涵盖基本部署场景的 第 2 章 “使用 Edge Image Builder 的独立集群”。
一旦您熟悉了此工具,请在我们的 EIB 提示与技巧部分 (第 IV 部分 “提示和技巧”) 页面上查找更多有用的信息。
8.3 已知问题 #
EIB 通过对 Helm chart 进行模板化并解析模板内的所有镜像来实现 Helm chart 的隔离。如果 Helm chart 没有将其所有镜像保留在模板内,而是侧载了这些镜像,则 EIB 将无法自动对这些镜像进行隔离。解决此问题的办法是手动将任何未检测到的镜像添加到定义文件的
embeddedArtifactRegistry部分。
9 边缘网络 #
本节介绍了 SUSE Edge 解决方案中的网络配置方法。 我们将展示如何在 SUSE Linux Micro 上以声明方式配置 NetworkManager,并解释相关工具是如何集成的。
9.1 NetworkManager 概述 #
NetworkManager 是用于管理主网络连接和其他连接接口的工具。
NetworkManager 将网络配置存储为包含期望状态的连接文件。
这些连接以文件的形式存储在 /etc/NetworkManager/system-connections/ 目录中。
有关 NetworkManager 的详细信息,请参阅 SUSE Linux Micro 文档。
9.2 nmstate 概述 #
nmstate 是一个被广泛采用的库(附带一个 CLI 工具),它通过预定义的模式为网络配置提供声明式 API。
有关 nmstate 的详细信息,请参阅 上游文档。
9.3 Enter:NetworkManager 配置器 (nmc) #
SUSE Edge 中提供的网络自定义选项是通过一个名为 NetworkManager 配置器(简称 nmc)的 CLI 工具实现的。 它利用了 nmstate 库提供的功能,因此完全能够配置静态 IP 地址、DNS 服务器、VLAN、网络绑定、网桥等。 该工具允许我们根据预定义的期望状态生成网络配置,并以自动化的方式在许多不同的节点上应用这些配置。
有关 NetworkManager 配置器 (nmc) 的详细信息,请参阅 上游储存库。
9.4 SUSE Edge 如何使用 NetworkManager 配置器? #
SUSE Edge 在各种不同的配置模型中利用 nmc 进行网络自定义: * 基于镜像的置备场景中的声明式静态配置 (第 2 章 “使用 Edge Image Builder 的独立集群”)
9.5 使用 Edge Image Builder 进行配置 #
Edge Image Builder (EIB) 是一款能够使用单个操作系统映像配置多个主机的工具。 在本节中,我们将展示如何使用声明式方法来描述所需的网络状态,这些状态如何转换为相应的 NetworkManager 连接,然后在置备过程中应用。
9.5.1 先决条件 #
如果您正在阅读本指南,则假定您已具备以下条件:
一台运行 SLES 15 SP6 或 openSUSE Leap 15.6 的 AMD64/Intel 64 物理主机(或虚拟机)
一个可用的容器运行时(例如 Podman)
一份 SUSE Linux Micro 6.2 RAW 映像副本,可在 此处 找到
9.5.2 获取 Edge Image Builder 容器映像 #
EIB 容器映像是公开可用的,可以通过运行以下命令从 SUSE Edge 注册表中下载:
podman pull registry.suse.com/edge/3.6/edge-image-builder:1.3.3.19.5.3 创建映像配置目录 #
让我们从创建配置目录开始:
export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR/base-images现在,我们将确保已下载的基础映像副本被移动到配置目录中:
mv /path/to/downloads/SL-Micro.x86_64-6.2-Base-GM.raw $CONFIG_DIR/base-images/注意EIB 绝不会修改基础映像输入。它将创建一个包含其修改内容的新映像。
此时,配置目录应如下所示:
└── base-images/
└── SL-Micro.x86_64-6.2-Base-GM.raw9.5.4 创建映像定义文件 #
定义文件描述了 Edge Image Builder 支持的大多数可配置选项。
让我们从一个非常基础的操作系统映像定义文件开始:
cat << EOF > $CONFIG_DIR/definition.yaml
apiVersion: 1.3
image:
arch: x86_64
imageType: raw
baseImage: SL-Micro.x86_64-6.2-Base-GM.raw
outputImageName: modified-image.raw
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOFimage 部分是必需的,它指定了输入映像、其架构和类型,以及输出映像的名称。
operatingSystem 部分是可选的,包含用于启用使用 root/eib 用户名/密码登录到置备系统的配置。
注意请随意使用您自己的加密密码,方法是运行
openssl passwd -6 <password>。
此时,配置目录应如下所示:
├── definition.yaml
└── base-images/
└── SL-Micro.x86_64-6.2-Base-GM.raw9.5.5 定义网络配置 #
所需的网络配置不属于我们刚刚创建的镜像定义文件。
我们现在将把它们填充到特殊的 network/ 目录下。让我们创建它:
mkdir -p $CONFIG_DIR/network如前所述,NetworkManager 配置器 (nmc) 工具期望以预定义模式的形式输入。 您可以在 上游 NMState 示例文档 中找到如何设置各种不同的网络选项。
本指南将解释如何配置三个不同节点上的网络:
使用两个以太网接口的节点
使用网络绑定的节点
使用网络网桥的节点
在生产构建中不建议使用完全不同的网络设置,尤其是在配置 Kubernetes 集群时。 网络配置通常应在节点之间保持同构,或者至少在给定集群内的角色之间保持同构。 本指南包含各种不同的选项,仅供参考。
注意以下内容假设使用具有 IP 地址范围
192.168.122.1/24的默认libvirt网络。 如果您的环境有所不同,请相应地进行调整。
让我们为第一个节点创建所需的状态,我们将其称为 node1.suse.com:
cat << EOF > $CONFIG_DIR/network/node1.suse.com.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: 192.168.122.1
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:E1
ipv4:
address:
- ip: 192.168.122.50
prefix-length: 24
dhcp: false
enabled: true
ipv6:
enabled: false
- name: eth3
type: ethernet
state: down
mac-address: 34:8A:B1:4B:16:E2
ipv4:
address:
- ip: 192.168.122.55
prefix-length: 24
dhcp: false
enabled: true
ipv6:
enabled: false
EOF在此示例中,我们定义了两个以太网接口(eth0 和 eth3)的所需状态、它们请求的 IP 地址、路由和 DNS 解析。
您必须确保列出所有以太网接口的 MAC 地址。 这些地址在置备过程中用作节点的标识符,并用于确定应应用哪些配置。 这就是我们能够使用单个 ISO 或 RAW 镜像配置多个节点的方法。
接下来是第二个节点,我们将称之为 node2.suse.com,它将使用网络绑定:
cat << EOF > $CONFIG_DIR/network/node2.suse.com.yaml
routes:
config:
- destination: 0.0.0.0/0
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: bond99
table-id: 254
- destination: 192.168.122.0/24
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: bond99
table-id: 254
dns-resolver:
config:
server:
- 192.168.122.1
- 8.8.8.8
interfaces:
- name: bond99
type: bond
state: up
ipv4:
address:
- ip: 192.168.122.60
prefix-length: 24
enabled: true
link-aggregation:
mode: balance-rr
options:
miimon: '140'
port:
- eth0
- eth1
- name: eth0
type: ethernet
state: up
mac-address: 34:8A:B1:4B:16:E3
ipv4:
enabled: false
ipv6:
enabled: false
- name: eth1
type: ethernet
state: up
mac-address: 34:8A:B1:4B:16:E4
ipv4:
enabled: false
ipv6:
enabled: false
EOF在此示例中,我们定义了两个以太网接口(eth0 和 eth1)的所需状态,它们未启用 IP 寻址,以及一个具有轮询策略的网络绑定及其将用于转发网络流量的相应地址。
最后,我们将创建第三个也是最后一个所需状态文件,它将利用网络网桥,我们将称之为 node3.suse.com:
cat << EOF > $CONFIG_DIR/network/node3.suse.com.yaml
routes:
config:
- destination: 0.0.0.0/0
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: linux-br0
table-id: 254
- destination: 192.168.122.0/24
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: linux-br0
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:E5
ipv4:
enabled: false
ipv6:
enabled: false
- name: linux-br0
type: linux-bridge
state: up
ipv4:
address:
- ip: 192.168.122.70
prefix-length: 24
dhcp: false
enabled: true
bridge:
options:
group-forward-mask: 0
mac-ageing-time: 300
multicast-snooping: true
stp:
enabled: true
forward-delay: 15
hello-time: 2
max-age: 20
priority: 32768
port:
- name: eth0
stp-hairpin-mode: false
stp-path-cost: 100
stp-priority: 32
EOF此时,配置目录应如下所示:
├── definition.yaml
├── network/
│ │── node1.suse.com.yaml
│ │── node2.suse.com.yaml
│ └── node3.suse.com.yaml
└── base-images/
└── SL-Micro.x86_64-6.2-Base-GM.raw注意
network/目录下的文件名是刻意这样命名的。 它们对应于将在置备过程中设置的主机名。
9.5.6 构建操作系统镜像 #
现在所有必要的配置都已就绪,我们可以通过简单地运行以下命令来构建镜像:
podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 build --definition-file definition.yaml输出应如下所示:
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Systemd ...................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Embedded Artifact Registry ... [SKIPPED]
Keymap ....................... [SUCCESS]
Kubernetes ................... [SKIPPED]
Certificates ................. [SKIPPED]
Building RAW image...
Kernel Params ................ [SKIPPED]
Image build complete!上面的代码片段告诉我们 Network 组件已成功配置,我们可以继续配置边缘节点。
注意可以在生成的
_build目录下的时间戳目录中检查日志文件 (network-config.log) 和相应的 NetworkManager 连接文件。
9.5.7 配置边缘节点 #
让我们复制生成的 RAW 镜像:
mkdir edge-nodes && cd edge-nodes
for i in {1..4}; do cp $CONFIG_DIR/modified-image.raw node$i.raw; done您会注意到我们复制了四次构建的镜像,但只指定了三个节点的网络配置。 这是因为我们还想展示如果我们配置一个与任何所需配置都不匹配的节点会发生什么。
我们将使用 virt-install 来使用复制的原始磁盘创建虚拟机。
每个虚拟机将使用 10 GB 的 RAM 和 6 个 vCPU。
9.5.7.1 配置第一个节点 #
让我们创建虚拟机:
virt-install --name node1 --ram 10000 --vcpus 6 --disk path=node1.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E1 --network default,mac=34:8A:B1:4B:16:E2 --virt-type kvm --import注意重要的是,我们要使用与上述预期状态中相同的 MAC 地址来创建网络接口。
操作完成后,我们将看到类似以下的内容:
Starting install...
Creating domain...
Running text console command: virsh --connect qemu:///system console node1
Connected to domain 'node1'
Escape character is ^] (Ctrl + ])
Welcome to SUSE Linux Micro 6.0 (x86_64) - Kernel 6.4.0-18-default (tty1).
SSH host key: SHA256:XN/R5Tw43reG+QsOw480LxCnhkc/1uqMdwlI6KUBY70 (RSA)
SSH host key: SHA256:/96yGrPGKlhn04f1rb9cXv/2WJt4TtrIN5yEcN66r3s (DSA)
SSH host key: SHA256:Dy/YjBQ7LwjZGaaVcMhTWZNSOstxXBsPsvgJTJq5t00 (ECDSA)
SSH host key: SHA256:TNGqY1LRddpxD/jn/8dkT/9YmVl9hiwulqmayP+wOWQ (ED25519)
eth0: 192.168.122.50
eth1:
Configured with the Edge Image Builder
Activate the web console with: systemctl enable --now cockpit.socket
node1 login:我们现在可以使用 root:eib 凭据对登录。
如果我们更喜欢使用 SSH 登录主机,而不是此处显示的 virsh console,我们也可以这样做。
登录后,让我们确认所有设置均已就绪。
验证主机名是否设置正确:
node1:~ # hostnamectl
Static hostname: node1.suse.com
...验证路由配置是否正确:
node1:~ # ip r
default via 192.168.122.1 dev eth0 proto static metric 100
192.168.122.0/24 dev eth0 proto static scope link metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.50 metric 100验证互联网连接是否可用:
node1:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.2 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.4 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 13.248/13.304/13.361/0.056 ms验证是否配置了恰好两个以太网接口,且其中只有一个处于活动状态:
node1:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e1 brd ff:ff:ff:ff:ff:ff
altname enp0s2
altname ens2
inet 192.168.122.50/24 brd 192.168.122.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e2 brd ff:ff:ff:ff:ff:ff
altname enp0s3
altname ens3
node1:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME UUID TYPE DEVICE FILENAME
eth0 dfd202f5-562f-5f07-8f2a-a7717756fb70 ethernet eth0 /etc/NetworkManager/system-connections/eth0.nmconnection
eth1 7e211aea-3d14-59cf-a4fa-be91dac5dbba ethernet -- /etc/NetworkManager/system-connections/eth1.nmconnection您会注意到第二个接口是 eth1,而不是我们预期的网络状态中预定义的 eth3。
这是因为 NetworkManager 配置器 (nmc) 能够检测到操作系统为 MAC 地址为 34:8a:b1:4b:16:e2 的 NIC 分配了不同的名称,并相应地调整了其设置。
通过检查置备的 Combustion 阶段来验证这一点是否确实发生:
node1:~ # journalctl -u combustion | grep nmc
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO nmc::apply_conf] Identified host: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO nmc::apply_conf] Set hostname: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO nmc::apply_conf] Processing interface 'eth0'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO nmc::apply_conf] Processing interface 'eth3'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO nmc::apply_conf] Using interface name 'eth1' instead of the preconfigured 'eth3'
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO nmc] Successfully applied config我们现在将置备其余节点,但仅展示最终配置中的差异。 您可以随意对即将置备的所有节点应用上述全部或部分检查。
9.5.7.2 置备第二个节点 #
让我们创建虚拟机:
virt-install --name node2 --ram 10000 --vcpus 6 --disk path=node2.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E3 --network default,mac=34:8A:B1:4B:16:E4 --virt-type kvm --import一旦虚拟机启动并运行,我们就可以确认该节点正在使用网络绑定。
node2:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
altname enp0s2
altname ens2
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff permaddr 34:8a:b1:4b:16:e4
altname enp0s3
altname ens3
4: bond99: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.60/24 brd 192.168.122.255 scope global noprefixroute bond99
valid_lft forever preferred_lft forever确认路由正在使用该网络绑定:
node2:~ # ip r
default via 192.168.122.1 dev bond99 proto static metric 100
192.168.122.0/24 dev bond99 proto static scope link metric 100
192.168.122.0/24 dev bond99 proto kernel scope link src 192.168.122.60 metric 300确保正确使用了静态连接文件:
node2:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME UUID TYPE DEVICE FILENAME
bond99 4a920503-4862-5505-80fd-4738d07f44c6 bond bond99 /etc/NetworkManager/system-connections/bond99.nmconnection
eth0 dfd202f5-562f-5f07-8f2a-a7717756fb70 ethernet eth0 /etc/NetworkManager/system-connections/eth0.nmconnection
eth1 0523c0a1-5f5e-5603-bcf2-68155d5d322e ethernet eth1 /etc/NetworkManager/system-connections/eth1.nmconnection9.5.7.3 配置第三个节点 #
让我们创建虚拟机:
virt-install --name node3 --ram 10000 --vcpus 6 --disk path=node3.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E5 --virt-type kvm --import一旦虚拟机启动并运行,我们就可以确认该节点正在使用网络桥接:
node3:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master linux-br0 state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
altname enp0s2
altname ens2
3: linux-br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.70/24 brd 192.168.122.255 scope global noprefixroute linux-br0
valid_lft forever preferred_lft forever确认路由正在使用该网桥:
node3:~ # ip r
default via 192.168.122.1 dev linux-br0 proto static metric 100
192.168.122.0/24 dev linux-br0 proto static scope link metric 100
192.168.122.0/24 dev linux-br0 proto kernel scope link src 192.168.122.70 metric 425确保正确使用了静态连接文件:
node3:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME UUID TYPE DEVICE FILENAME
linux-br0 1f8f1469-ed20-5f2c-bacb-a6767bee9bc0 bridge linux-br0 /etc/NetworkManager/system-connections/linux-br0.nmconnection
eth0 dfd202f5-562f-5f07-8f2a-a7717756fb70 ethernet eth0 /etc/NetworkManager/system-connections/eth0.nmconnection9.5.7.4 配置第四个节点 #
最后,我们将配置一个节点,该节点的 MAC 地址与任何预定义的配置均不匹配。 在这些情况下,我们将默认使用 DHCP 来配置网络接口。
让我们创建虚拟机:
virt-install --name node4 --ram 10000 --vcpus 6 --disk path=node4.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import一旦虚拟机启动并运行,我们就可以确认该节点正在为其网络接口使用随机 IP 地址:
localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:56:63:71 brd ff:ff:ff:ff:ff:ff
altname enp0s2
altname ens2
inet 192.168.122.86/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
valid_lft 3542sec preferred_lft 3542sec
inet6 fe80::5054:ff:fe56:6371/64 scope link noprefixroute
valid_lft forever preferred_lft forever验证 nmc 是否未能为此节点应用静态配置:
localhost:~ # journalctl -u combustion | grep nmc
Apr 23 12:15:45 localhost.localdomain combustion[1357]: [2024-04-23T12:15:45Z ERROR nmc] Applying config failed: None of the preconfigured hosts match local NICs验证以太网接口是否已通过 DHCP 配置:
localhost:~ # journalctl | grep eth0
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7801] manager: (eth0): new Ethernet device (/org/freedesktop/NetworkManager/Devices/2)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7802] device (eth0): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7929] device (eth0): carrier: link connected
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7931] device (eth0): state change: unavailable -> disconnected (reason 'carrier-changed', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7944] device (eth0): Activation: starting connection 'Wired Connection' (300ed658-08d4-4281-9f8c-d1b8882d29b9)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7945] device (eth0): state change: disconnected -> prepare (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7947] device (eth0): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7953] device (eth0): state change: config -> ip-config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info> [1713874529.7964] dhcp4 (eth0): activation: beginning transaction (timeout in 90 seconds)
Apr 23 12:15:33 localhost.localdomain NetworkManager[704]: <info> [1713874533.1272] dhcp4 (eth0): state changed new lease, address=192.168.122.86
localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME UUID TYPE DEVICE FILENAME
Wired Connection 300ed658-08d4-4281-9f8c-d1b8882d29b9 ethernet eth0 /var/run/NetworkManager/system-connections/default_connection.nmconnection9.5.8 统一节点配置 #
在某些情况下,无法依赖已知的 MAC 地址。在这些情况下,我们可以选择所谓的 统一配置,它允许我们在 _all.yaml 文件中指定设置,然后将其应用于所有已配置的节点。
我们将使用不同的配置结构构建并配置边缘节点。按照从 第 9.5.3 节 “创建映像配置目录” 到 第 9.5.5 节 “定义网络配置” 的所有步骤操作。
在此示例中,我们定义了两个以太网接口(eth0 和 eth1)的期望状态——一个使用 DHCP,另一个分配了静态 IP 地址。
mkdir -p $CONFIG_DIR/network
cat <<- EOF > $CONFIG_DIR/network/_all.yaml
interfaces:
- name: eth0
type: ethernet
state: up
ipv4:
dhcp: true
enabled: true
ipv6:
enabled: false
- name: eth1
type: ethernet
state: up
ipv4:
address:
- ip: 10.0.0.1
prefix-length: 24
enabled: true
dhcp: false
ipv6:
enabled: false
EOF让我们构建镜像:
podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 build --definition-file definition.yaml镜像构建成功后,让我们使用它创建一个虚拟机:
virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --network default --virt-type kvm --import配置过程可能需要几分钟。完成后,使用提供的凭据登录系统。
验证路由配置是否正确:
localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.100 metric 100
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.1 metric 101
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.100 metric 100验证互联网连接是否可用:
localhost:~ # ping google.com
PING google.com (142.250.72.46) 56(84) bytes of data.
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=1 ttl=56 time=14.3 ms
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=2 ttl=56 time=14.2 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 14.196/14.260/14.324/0.064 ms验证以太网接口是否已配置并处于活动状态:
localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:26:44:7a brd ff:ff:ff:ff:ff:ff
altname enp1s0
inet 192.168.122.100/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
valid_lft 3505sec preferred_lft 3505sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:ec:57:9e brd ff:ff:ff:ff:ff:ff
altname enp7s0
inet 10.0.0.1/24 brd 10.0.0.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME UUID TYPE DEVICE FILENAME
eth0 dfd202f5-562f-5f07-8f2a-a7717756fb70 ethernet eth0 /etc/NetworkManager/system-connections/eth0.nmconnection
eth1 0523c0a1-5f5e-5603-bcf2-68155d5d322e ethernet eth1 /etc/NetworkManager/system-connections/eth1.nmconnection
localhost:~ # cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
[ipv4]
dhcp-client-id=mac
dhcp-send-hostname=true
dhcp-timeout=2147483647
ignore-auto-dns=false
ignore-auto-routes=false
method=auto
never-default=false
[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled
localhost:~ # cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth1
interface-name=eth1
type=802-3-ethernet
uuid=0523c0a1-5f5e-5603-bcf2-68155d5d322e
[ipv4]
address0=10.0.0.1/24
dhcp-timeout=2147483647
method=manual
[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled9.5.9 自定义网络配置 #
我们已经介绍了 Edge Image Builder 的默认网络配置,它依赖于 NetworkManager Configurator。 不过,也可以选择通过自定义脚本进行修改。虽然此选项非常灵活且不依赖于 MAC 地址,但其局限性在于,当使用单个镜像引导多个节点时,使用它会很不方便。
注意建议通过
/network目录下描述所需网络状态的文件来使用默认网络配置。 仅当该行为不适用于您的用例时,才选择自定义脚本。
我们将使用不同的配置结构构建并配置边缘节点。按照从 第 9.5.3 节 “创建映像配置目录” 到 第 9.5.5 节 “定义网络配置” 的所有步骤操作。
在此示例中,我们将创建一个自定义脚本,为所有已配置节点上的 eth0 接口应用静态配置,并删除和禁用 NetworkManager 自动创建的有线连接。这在您希望确保集群中的每个节点都具有相同网络配置的情况下非常有用,因此您无需在创建镜像之前关注每个节点的 MAC 地址。
让我们首先将连接文件存储在 /custom/files 目录中:
mkdir -p $CONFIG_DIR/custom/files
cat << EOF > $CONFIG_DIR/custom/files/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000
[ipv4]
dhcp-timeout=2147483647
method=auto
[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled
EOF现在静态配置已创建,我们还将创建自定义网络脚本:
mkdir -p $CONFIG_DIR/network
cat << EOF > $CONFIG_DIR/network/configure-network.sh
#!/bin/bash
set -eux
# Remove and disable wired connections
mkdir -p /etc/NetworkManager/conf.d/
printf "[main]\nno-auto-default=*\n" > /etc/NetworkManager/conf.d/no-auto-default.conf
rm -f /var/run/NetworkManager/system-connections/* || true
# Copy pre-configured network configuration files into NetworkManager
mkdir -p /etc/NetworkManager/system-connections/
cp eth0.nmconnection /etc/NetworkManager/system-connections/
chmod 600 /etc/NetworkManager/system-connections/*.nmconnection
EOF
chmod a+x $CONFIG_DIR/network/configure-network.sh注意nmc 二进制文件仍将默认包含,因此如有必要,它也可以在
configure-network.sh脚本中使用。
自定义脚本必须始终放置在配置目录下的 /network/configure-network.sh 中。如果存在,所有其他文件都将被忽略。
无法同时使用 YAML 格式的静态配置和自定义脚本来配置网络。
此时,配置目录应如下所示:
├── definition.yaml
├── custom/
│ └── files/
│ └── eth0.nmconnection
├── network/
│ └── configure-network.sh
└── base-images/
└── SL-Micro.x86_64-6.2-Base-GM.raw让我们构建镜像:
podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 build --definition-file definition.yaml镜像构建成功后,让我们使用它创建一个虚拟机:
virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import配置过程可能需要几分钟。完成后,使用提供的凭据登录系统。
验证路由配置是否正确:
localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.185 metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.185 metric 100验证互联网连接是否可用:
localhost:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.6 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.6 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 13.592/13.599/13.606/0.007 ms验证以太网接口是否使用我们的连接文件进行了静态配置且处于活动状态:
localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:31:d0:1b brd ff:ff:ff:ff:ff:ff
altname enp0s2
altname ens2
inet 192.168.122.185/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME UUID TYPE DEVICE FILENAME
eth0 dfd202f5-562f-5f07-8f2a-a7717756fb70 ethernet eth0 /etc/NetworkManager/system-connections/eth0.nmconnection
localhost:~ # cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000
[ipv4]
dhcp-timeout=2147483647
method=auto
[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled10 Elemental #
Elemental 是一套软件栈,支持通过 Kubernetes 实现集中式、完全云原生的操作系统管理。Elemental 栈由多个组件组成,这些组件要么驻留在 Rancher 本身,要么驻留在边缘节点上。核心组件包括:
elemental-operator - 驻留在 Rancher 上并处理来自客户端注册请求的核心 operator。
elemental-register - 运行在边缘节点上的客户端,允许通过
elemental-operator进行注册。elemental-system-agent - 驻留在边缘节点上的代理;其配置由
elemental-register提供,并接收用于配置rancher-system-agent的plan。rancher-system-agent - 一旦边缘节点完全注册,该代理将接管
elemental-system-agent的工作,并等待来自 Rancher Manager 的进一步plans(例如用于 Kubernetes 安装)。
有关 Elemental 及其与 Rancher 关系的完整信息,请参阅 Elemental 上游文档。
10.1 SUSE Edge 如何使用 Elemental? #
我们使用 Elemental 的部分功能来管理无法使用 Metal3 的远程设备(例如,没有 BMC,或者设备位于 NAT 网关之后)。此工具允许操作员在实验室中启动其设备,而无需预先知道设备何时或将被运往何处。具体而言,我们利用 elemental-register 和 elemental-system-agent 组件,使 SUSE Linux Micro 主机能够接入 Rancher,以实现“自动回连”(phone home)网络配置用例。当使用 Edge Image Builder (EIB) 创建部署镜像时,可以通过在 EIB 的配置目录中指定注册配置,来实现通过 Elemental 进行 Rancher 自动注册。
在 SUSE Edge 3.6 中,我们*不*利用 Elemental 的操作系统管理功能,因此无法通过 Rancher 管理您的操作系统补丁。与其使用 Elemental 工具构建部署镜像,SUSE Edge 使用了 Edge Image Builder 工具,该工具会使用注册配置。
10.2 最佳实践 #
10.2.1 安装媒体 #
在“自动回连网络配置”部署场景下,推荐的 SUSE Edge 构建部署镜像方法是按照 使用 Elemental 进行远程主机接入 (第 1 章 “使用 Elemental 进行远程主机注册”) 快速入门中详述的说明操作,以便利用 Elemental 向 Rancher 注册。
10.2.2 标签 #
Elemental 使用 MachineInventory CRD 跟踪其清单,并提供了一种基于标签选择清单的方法,例如用于选择要部署 Kubernetes 集群的机器。这为用户提供了一种在购买硬件之前预定义大部分(如果不是全部)基础设施需求的方法。此外,由于节点可以在各自的清单对象上添加或去除标签(通过重新运行 elemental-register 并附加标志 --label "FOO=BAR"),我们可以编写脚本来检测并让 Rancher 知道节点从哪里启动。
10.3 已知问题 #
Elemental UI 目前不知道如何构建安装媒体或更新非“Elemental Teal”操作系统。这应该会在未来的版本中得到解决。
11 K3s #
K3s 是一款高可用、经过认证的 Kubernetes 发行版,专为无人值守、资源受限、远程位置或物联网设备内部的生产工作负载而设计。
它被打包为一个单一且小型化的二进制文件,因此安装和更新既快速又简便。
11.1 SUSE Edge 如何使用 K3s? #
K3s 可用作支持 SUSE Edge 堆栈的 Kubernetes 发行版。 它旨在安装在 SUSE Linux Micro 操作系统上。
仅当 etcd 作为后端不符合您的约束条件时,才建议将 K3s 用作 SUSE Edge 堆栈的 Kubernetes 发行版。如果 etcd 作为后端是可行的,则最好使用 RKE2 (第 12 章 “RKE2”)。
11.2 最佳实践 #
11.2.1 安装 #
将 K3s 作为 SUSE Edge 堆栈一部分进行安装的推荐方法是使用 Edge Image Builder (EIB)。有关如何配置它以部署 K3s 的更多详细信息,请参阅 其文档 (第 8 章 “Edge Image Builder”)。
它自动支持高可用性 (HA) 设置以及 Elemental 设置。
11.2.2 用于 GitOps 工作流的 Fleet #
SUSE Edge 堆栈使用 Fleet 作为其首选的 GitOps 工具。 有关其安装和使用的更多信息,请参阅本文档中的 Fleet 部分 (第 6 章 “Fleet”)。
11.2.3 存储管理 #
K3s 预配置了 local-path 存储,适用于单节点集群。 对于跨多个节点的集群,我们建议使用 SUSE Storage (第 13 章 “SUSE Storage”)。
11.2.4 负载平衡与高可用性 (HA) #
如果您使用 EIB 安装了 K3s,此部分已包含在 EIB 文档的高可用性 (HA) 部分中。
否则,您需要按照我们的 MetalLB 文档 (第 21 章 “K3s 上的 MetalLB(使用层 2 模式)”) 安装并配置 MetalLB。
12 RKE2 #
请参阅 RKE2 官方文档。
RKE2 是一款完全合规的 Kubernetes 发行版,通过以下方式专注于安全性和合规性:
提供默认设置和配置选项,使集群在仅需最小化运维干预的情况下即可通过 CIS Kubernetes Benchmark v1.6 或 v1.23
启用 FIPS 140-2 合规性
在 RKE2 构建流水线中使用 trivy 定期扫描组件的 CVE
RKE2 将控制平面组件作为静态 Pod 启动,并由 kubelet 管理。内置的容器运行时是 containerd。
注意:RKE2 也被称为 RKE Government,以传达其目前针对的另一个用例和领域。
12.1 RKE2 vs K3s #
K3s 是一款完全合规且轻量级的 Kubernetes 发行版,专注于边缘计算、物联网和 ARM 架构,针对易用性和资源受限的环境进行了优化。
RKE2 结合了 RKE 1.x 版本(以下简称 RKE1)和 K3s 的优点。
它继承了 K3s 的可用性、易操作性和部署模型。
它继承了 RKE1 与上游 Kubernetes 的紧密一致性。在某些方面,K3s 为了优化边缘部署而偏离了上游 Kubernetes,但 RKE1 和 RKE2 可以与上游保持高度一致。
12.2 SUSE Edge 如何使用 RKE2? #
RKE2 是 SUSE Edge 技术栈的基础组成部分。它位于SUSE Linux Micro (第 7 章 “SUSE Linux Micro”)之上,提供部署边缘工作负载所需的标准 Kubernetes 接口。
12.3 最佳实践 #
12.3.1 安装 #
将 RKE2 作为 SUSE Edge 技术栈的一部分进行安装的推荐方法是使用 Edge Image Builder (EIB)。有关如何配置它以部署 RKE2 的更多详细信息,请参阅EIB 文档 (第 8 章 “Edge Image Builder”)。
EIB 非常灵活,足以支持 RKE2 所需的任何参数,例如指定 RKE2 版本、 服务器或 代理配置,涵盖了所有边缘用例。
12.3.2 高可用性 #
对于高可用性部署,EIB 会自动部署并配置 MetalLB (第 15 章 “MetalLB”) 和 Endpoint Copier Operator (第 16 章 “端点复制器操作员”),以在外部公开 RKE2 API 端点。
12.3.3 网络 #
SUSE Edge 堆栈支持 Cilium、 Calico,并以 Cilium 作为其默认 CNI。当 Pod 需要多个网络接口时,也可以使用 Multus元插件。RKE2 独立版支持 更广泛的 CNI 选项。
12.3.4 存储 #
RKE2 不提供任何类型的持久存储类或操作器。对于跨多个节点的集群,建议使用SUSE Storage (第 13 章 “SUSE Storage”)。
13 SUSE Storage #
SUSE Storage 是适用于 Kubernetes 的轻量级、可靠且易于使用的分布式块存储系统。它是一款基于 Longhorn 的产品,Longhorn 是最初由 Rancher Labs 开发并目前在 CNCF 下孵化的开源项目。
13.1 先决条件 #
如果您正在阅读本指南,则假定您已具备以下条件:
至少安装有一台 SUSE Linux Micro 6.2 的主机;可以是物理机或虚拟机
已安装 Kubernetes 集群;K3s 或 RKE2 均可
Helm
13.2 手动安装 SUSE Storage #
13.2.1 安装 Open-iSCSI #
部署和使用 SUSE Storage 的核心要求是在所有 Kubernetes 节点上安装 open-iscsi 软件包并运行 iscsid 守护程序。
这是必要的,因为 Longhorn 依赖主机上的 iscsiadm 来为 Kubernetes 提供持久卷。
让我们安装它:
transactional-update pkg install open-iscsi需要注意的是,操作完成后,由于 SUSE Linux Micro 是不可变操作系统,该软件包仅安装到新的快照中。
为了加载它并使 iscsid 守护程序开始运行,我们必须重启进入刚才创建的新快照。
准备好后,发出重启命令:
reboot13.2.2 安装 SUSE Storage #
有几种方法可以在您的 Kubernetes 集群上安装 SUSE Storage。 本指南将介绍 Helm 安装方式,但如果您希望使用其他方法,请随时参考 官方文档。
登录 Rancher 应用合集:
helm registry login dp.apps.rancher.io --username $APPS.RANCHER.IO_USERNAME --password $APPS.RANCHER.IO_ACCESS_TOKEN在
longhorn-system名称空间中安装 SUSE Storage 并添加您的容器镜像仓库凭据:helm install longhorn oci://dp.apps.rancher.io/charts/suse-storage \ --version 1.11.2 \ --namespace longhorn-system \ --create-namespace \ --set privateRegistry.createSecret=true \ --set privateRegistry.registryUrl=dp.apps.rancher.io \ --set privateRegistry.registryUser=$APPS.RANCHER.IO_USERNAME \ --set privateRegistry.registryPasswd=$APPS.RANCHER.IO_ACCESS_TOKEN \ --set privateRegistry.registrySecret=application-collection确认部署成功:
kubectl -n longhorn-system get podslocalhost:~ # kubectl -n longhorn-system get pods NAME READY STATUS RESTARTS AGE csi-attacher-7656559cf4-pkhh6 1/1 Running 0 103s csi-attacher-7656559cf4-pnzw5 1/1 Running 0 103s csi-attacher-7656559cf4-z94mm 1/1 Running 0 103s csi-provisioner-6d9cf6456d-kcwtq 1/1 Running 0 103s csi-provisioner-6d9cf6456d-mvvml 1/1 Running 0 103s csi-provisioner-6d9cf6456d-q4f88 1/1 Running 0 103s csi-resizer-f587cd467-clr2n 1/1 Running 0 103s csi-resizer-f587cd467-z28v4 1/1 Running 0 103s csi-resizer-f587cd467-zxmtx 1/1 Running 0 103s csi-snapshotter-6dcdf78684-757mg 1/1 Running 0 103s csi-snapshotter-6dcdf78684-8ktgc 1/1 Running 0 103s csi-snapshotter-6dcdf78684-ffsqr 1/1 Running 0 103s engine-image-ei-099f845a-lvdtr 1/1 Running 0 2m21s instance-manager-4adffddaffe02374cd5635b8a6113de7 1/1 Running 0 111s longhorn-csi-plugin-w7pwr 3/3 Running 0 103s longhorn-driver-deployer-6886fb84bc-wm9h6 1/1 Running 2 (2m32s ago) 2m45s longhorn-manager-zblbl 2/2 Running 0 2m45s longhorn-ui-6bcc65d4bd-mcn6r 1/1 Running 0 2m45s longhorn-ui-6bcc65d4bd-rwf97 1/1 Running 0 2m45s
13.3 创建 SUSE Storage 卷 #
SUSE Storage 利用名为 StorageClass 的 Kubernetes 资源,以便为 Pod 自动配置 PersistentVolume 对象。
可以将 StorageClass 视为管理员描述其提供的存储 类 或 控制文件 的一种方式。
让我们创建一个带有某些默认选项的 StorageClass:
kubectl apply -f - <<EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: longhorn-example
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "2880" # 48 hours in minutes
fromBackup: ""
fsType: "ext4"
EOF现在我们已经有了 StorageClass,我们需要一个引用它的 PersistentVolumeClaim。
PersistentVolumeClaim (PVC) 是用户对存储的请求。PVC 会消耗 PersistentVolume 资源。
声明可以请求特定的存储大小和访问模式(例如,可以一次以读/写模式挂载,或多次以只读模式挂载)。
让我们创建一个 PersistentVolumeClaim:
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-volv-pvc
namespace: longhorn-system
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn-example
resources:
requests:
storage: 2Gi
EOF就是这样!一旦创建了 PersistentVolumeClaim,我们就可以继续将其附加到 Pod。
当 Pod 部署完成后,Kubernetes 会创建 Longhorn 卷,并在存储可用时将其绑定到 Pod。
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: volume-test
namespace: longhorn-system
spec:
containers:
- name: volume-test
image: nginx:stable-alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- name: volv
mountPath: /data
ports:
- containerPort: 80
volumes:
- name: volv
persistentVolumeClaim:
claimName: longhorn-volv-pvc
EOF在此示例中,结果应如下所示:
localhost:~ # kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
longhorn (default) driver.longhorn.io Delete Immediate true 12m
longhorn-example driver.longhorn.io Delete Immediate true 24s
localhost:~ # kubectl get pvc -n longhorn-system
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
longhorn-volv-pvc Bound pvc-f663a92e-ac32-49ae-b8e5-8a6cc29a7d1e 2Gi RWO longhorn-example 54s
localhost:~ # kubectl get pods -n longhorn-system
NAME READY STATUS RESTARTS AGE
csi-attacher-5c4bfdcf59-qmjtz 1/1 Running 0 14m
csi-attacher-5c4bfdcf59-s7n65 1/1 Running 0 14m
csi-attacher-5c4bfdcf59-w9xgs 1/1 Running 0 14m
csi-provisioner-667796df57-fmz2d 1/1 Running 0 14m
csi-provisioner-667796df57-p7rjr 1/1 Running 0 14m
csi-provisioner-667796df57-w9fdq 1/1 Running 0 14m
csi-resizer-694f8f5f64-2rb8v 1/1 Running 0 14m
csi-resizer-694f8f5f64-z9v9x 1/1 Running 0 14m
csi-resizer-694f8f5f64-zlncz 1/1 Running 0 14m
csi-snapshotter-959b69d4b-5dpvj 1/1 Running 0 14m
csi-snapshotter-959b69d4b-lwwkv 1/1 Running 0 14m
csi-snapshotter-959b69d4b-tzhwc 1/1 Running 0 14m
engine-image-ei-5cefaf2b-hvdv5 1/1 Running 0 14m
instance-manager-0ee452a2e9583753e35ad00602250c5b 1/1 Running 0 14m
longhorn-csi-plugin-gd2jx 3/3 Running 0 14m
longhorn-driver-deployer-9f4fc86-j6h2b 1/1 Running 0 15m
longhorn-manager-z4lnl 1/1 Running 0 15m
longhorn-ui-5f4b7bbf69-bln7h 1/1 Running 3 (14m ago) 15m
longhorn-ui-5f4b7bbf69-lh97n 1/1 Running 3 (14m ago) 15m
volume-test 1/1 Running 0 26s13.4 访问 UI #
如果您使用 kubectl 或 Helm 安装了 SUSE Storage,则需要设置 Ingress 控制器以允许外部流量进入集群。默认情况下未启用身份验证。如果使用了 Rancher 应用合集,Rancher 会自动创建一个带有访问控制(rancher-proxy)的 Ingress 控制器。
获取 Longhorn 的外部服务 IP 地址:
kubectl -n longhorn-system get svc获取
longhorn-frontendIP 地址后,您可以通过在浏览器中导航至该地址来开始使用 UI。
13.5 使用 Edge Image Builder 进行安装 #
SUSE Edge 正在使用 第 8 章 “Edge Image Builder” 来定制基础 SUSE Linux Micro OS 镜像。 我们将演示如何执行此操作,以便在其上部署带有 SUSE Storage 的 RKE2 集群。
让我们创建定义文件:
export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR
cat << EOF > $CONFIG_DIR/iso-definition.yaml
apiVersion: 1.3
image:
imageType: iso
baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
arch: x86_64
outputImageName: eib-image.iso
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: suse-storage
releaseName: longhorn
version: 1.11.2
repositoryName: rancher-application-collection
targetNamespace: longhorn-system
createNamespace: true
installationNamespace: kube-system
repositories:
- name: rancher-application-collection
url: oci://dp.apps.rancher.io/charts
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
registries:
- uri: dp.apps.rancher.io
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
images:
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.11.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-14.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.1.0-6.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.5.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.18.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.16.0-13.2
- name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.11.2-4.1
- name: dp.apps.rancher.io/containers/longhorn-engine:1.11.2-4.2
- name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.11.2-4.3
- name: dp.apps.rancher.io/containers/longhorn-manager:1.11.2-4.2
- name: dp.apps.rancher.io/containers/longhorn-share-manager:1.11.2-4.1
- name: dp.apps.rancher.io/containers/longhorn-ui:1.11.2-4.1
- name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.84-9.4
operatingSystem:
packages:
sccRegistrationCode: <reg-code>
packageList:
- open-iscsi
users:
- username: root
encryptedPassword: \$6\$jHugJNNd3HElGsUZ\$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOF让我们构建镜像:
podman run --rm --privileged -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 build --definition-file $CONFIG_DIR/iso-definition.yaml镜像构建完成后,您可以使用它在物理主机或虚拟机上安装操作系统。
配置完成后,您可以使用 root:eib 所提供的凭据登录系统。
确保 SUSE Storage 已成功部署:
localhost:~ # /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml -n longhorn-system get pods
NAME READY STATUS RESTARTS AGE
csi-attacher-5c4bfdcf59-qmjtz 1/1 Running 0 103s
csi-attacher-5c4bfdcf59-s7n65 1/1 Running 0 103s
csi-attacher-5c4bfdcf59-w9xgs 1/1 Running 0 103s
csi-provisioner-667796df57-fmz2d 1/1 Running 0 103s
csi-provisioner-667796df57-p7rjr 1/1 Running 0 103s
csi-provisioner-667796df57-w9fdq 1/1 Running 0 103s
csi-resizer-694f8f5f64-2rb8v 1/1 Running 0 103s
csi-resizer-694f8f5f64-z9v9x 1/1 Running 0 103s
csi-resizer-694f8f5f64-zlncz 1/1 Running 0 103s
csi-snapshotter-959b69d4b-5dpvj 1/1 Running 0 103s
csi-snapshotter-959b69d4b-lwwkv 1/1 Running 0 103s
csi-snapshotter-959b69d4b-tzhwc 1/1 Running 0 103s
engine-image-ei-5cefaf2b-hvdv5 1/1 Running 0 109s
instance-manager-0ee452a2e9583753e35ad00602250c5b 1/1 Running 0 109s
longhorn-csi-plugin-gd2jx 3/3 Running 0 103s
longhorn-driver-deployer-9f4fc86-j6h2b 1/1 Running 0 2m28s
longhorn-manager-z4lnl 1/1 Running 0 2m28s
longhorn-ui-5f4b7bbf69-bln7h 1/1 Running 3 (2m7s ago) 2m28s
longhorn-ui-5f4b7bbf69-lh97n 1/1 Running 3 (2m10s ago) 2m28s14 SUSE Security #
SUSE Security 是一款适用于 Kubernetes 的安全解决方案,它在一个统一的软件包中提供 L7 网络安全、运行时安全、供应链安全和合规性检查。
SUSE Security 是一款以多个容器组成的平台形式部署的安全产品,每个容器通过各种端口和接口进行通信。在底层,它使用 NeuVector 作为其基础容器安全组件。SUSE Security 平台由以下容器组成:
Manager。一个提供基于 Web 的控制台的无状态容器。通常只需要一个,并且可以在任何地方运行。Manager 的故障不会影响控制器或 Enforcer 的任何操作。但是,某些通知(事件)和最近的连接数据由 Manager 缓存在内存中,因此查看这些数据会受到影响。
控制器。SUSE Security 的“控制平面”必须部署在高可用性 (HA) 配置中,以确保在节点故障时不会丢失配置。它们可以在任何地方运行,尽管客户通常因为其关键性而选择将它们放置在“管理”、主节点或基础架构节点上。
Enforcer。此容器作为 DaemonSet 部署,因此每个要保护的节点上都有一个 Enforcer。通常部署到每个工作节点,但也可以启用主节点和基础架构节点的调度以将其部署到这些节点上。注意:如果 Enforcer 不在集群节点上,并且连接来自该节点上的 Pod,SUSE Security 会将其标记为“非托管”工作负载。
扫描程序。在控制器的指导下,使用内置的 CVE 数据库执行漏洞扫描。可以部署多个扫描程序以提高扫描容量。扫描程序可以在任何地方运行,但通常在控制器运行的节点上运行。有关扫描程序节点的规模调整注意事项,请参见下文。当用于构建阶段扫描时,扫描程序也可以独立调用,例如在触发扫描、检索结果并停止扫描程序的流水线中。扫描程序包含最新的 CVE 数据库,因此应每天更新。
更新程序。当需要更新 CVE 数据库时,更新程序会通过 Kubernetes 定时任务触发扫描程序的更新。请务必针对您的环境进行配置。
更深入的 SUSE Security 入门和最佳实践文档可以在 这里找到。
14.1 SUSE Edge 如何使用 SUSE Security? #
SUSE Edge 为边缘部署提供了一个更精简的 SUSE Security 配置作为起点。
14.2 重要注意事项 #
Scanner容器必须有足够的内存,以便将要扫描的镜像拉取到内存中并展开。要扫描超过 1 GB 的镜像,请将扫描程序的内存增加到略高于预期最大镜像大小的值。在保护模式下预计会有大量的网络连接。
Enforcer在保护(内联防火墙拦截)模式下需要处理器和内存来保持和检查连接以及可能的有效负载(DLP)。增加内存并为Enforcer专用一个处理器核心可以确保足够的包过滤能力。
14.3 使用 Edge Image Builder 进行安装 #
SUSE Edge 正在使用 第 8 章 “Edge Image Builder” 以自定义基础 SUSE Linux Micro OS 镜像。 请遵循 第 25.7 节 “SUSE Security 安装” 以在 EIB 配置的 Kubernetes 集群之上进行 SUSE Security 的隔离的安装。
15 MetalLB #
请参阅 MetalLB 官方文档。
MetalLB 是一种用于裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。
在裸机环境中,设置网络负载均衡器比在云环境中要复杂得多。与云设置中简单的 API 调用不同,裸机需要专用网络设备或负载均衡器与虚拟 IP (VIP) 配置的组合,以管理高可用性 (HA) 或解决单节点负载均衡器中固有的潜在单点故障 (SPOF) 问题。这些配置不易自动化,给组件动态扩缩容的 Kubernetes 部署带来了挑战。
MetalLB 通过利用 Kubernetes 模型来创建 LoadBalancer 类型服务,从而解决了这些挑战,即使在裸机设置中也能像在云环境中一样运行。
有两种不同的方法,通过 L2 模式(使用 ARP 技巧)或通过 BGP。主要是 L2 不需要任何特殊的网络设备,但 BGP 通常更好。这取决于使用场景。
15.1 SUSE Edge 如何使用 MetalLB? #
SUSE Edge 以三种关键方式使用 MetalLB:
作为负载均衡器解决方案:MetalLB 用作裸机的负载均衡解决方案。
对于 HA K3s/RKE2 设置:MetalLB 允许使用虚拟 IP 地址对 Kubernetes API 进行负载均衡。
作为一种L3 BGP解决方案,MetalLB将服务IP的路由通告给附近的路由器。
为了能够暴露 API,使用Endpoint Copier Operator (第 16 章 “端点复制器操作员”)将K8s API端点从`kubernetes`服务同步到`kubernetes-vip` LoadBalancer服务。
15.2 最佳实践 #
L2模式下MetalLB的安装在第 21 章 “K3s 上的 MetalLB(使用层 2 模式)”中描述,L3模式的安装在第 22 章 “K3s 上的 MetalLB(使用层 3 模式)”中描述。
关于在`kube-api-server`前端安装 MetalLB 以实现高可用性拓扑的指南,可以在第 24 章 “Kubernetes API 服务器前的 MetalLB”中找到。
15.3 已知问题 #
K3s自带其名为`Klipper`的负载均衡器解决方案。要使用MetalLB,必须禁用`Klipper`。这可以通过使用`--disable servicelb`选项启动K3s服务器来完成,如 K3s文档中所述。
16 端点复制器操作员 #
端点复制器操作员 是一个 Kubernetes 操作员,其目的是创建 Kubernetes 服务和端点的副本并保持它们同步。
16.1 SUSE Edge 如何使用端点复制器操作员? #
在 SUSE Edge,端点复制器操作员在实现 K3s/RKE2 集群的高可用性设置方面发挥着至关重要的作用。这是通过创建一个 kubernetes-vip 类型为 LoadBalancer 的服务来实现的,确保其端点与 Kubernetes 端点保持持续同步。利用 MetalLB (第 15 章 “MetalLB”) 来管理 kubernetes-vip 服务,因为从其他节点加入集群时会使用暴露的 IP 地址。
16.2 最佳实践 #
有关使用端点复制器操作员的完整文档可以在 此处 找到。
此外,请参阅 我们的指南 (第 21 章 “K3s 上的 MetalLB(使用层 2 模式)”),了解如何使用端点复制器操作员和 MetalLB 实现 K3s/RKE2 高可用性设置。
16.3 已知问题 #
目前,端点复制器操作员仅限于处理一个服务/端点。未来计划进行增强以支持多个服务/端点。
17 边缘虚拟化 #
本节介绍如何使用边缘虚拟化在边缘节点上运行虚拟机。边缘虚拟化专为轻量级虚拟化用例而设计,旨在利用通用的工作流程来部署和管理虚拟化及容器化应用程序。
SUSE Edge 虚拟化支持两种运行虚拟机的方法:
通过 libvirt+qemu-kvm 在主机级别手动部署虚拟机(不涉及 Kubernetes)
部署 KubeVirt 操作器以实现基于 Kubernetes 的虚拟机管理
这两种选项均有效,但下文仅介绍第二种。如果您想使用 SUSE Linux Micro 提供的标准开箱即用虚拟化机制,可以在 此处 找到综合指南,虽然它主要是为 SUSE Linux Enterprise Server 编写的,但其概念几乎相同。
本指南首先说明如何将额外的虚拟化组件部署到已预先部署的系统上,随后介绍如何通过 Edge Image Builder 将此配置嵌入到初始部署中。如果您不想了解基础知识并手动进行设置,请直接跳至该部分。
17.1 KubeVirt 概述 #
KubeVirt 允许在 Kubernetes 中与您的其他容器化工作负载一起管理虚拟机。它通过在容器中运行 Linux 虚拟化堆栈的用户空间部分来实现这一点。这最大限度地减少了对主机系统的要求,从而简化了设置和管理。
有关 KubeVirt 架构的详细信息,请参阅 上游文档。
17.2 先决条件 #
如果您正在遵循本指南,我们假设您已具备以下条件:
17.3 手动安装边缘虚拟化 #
本指南不会引导您完成 Kubernetes 的部署,但它假设您已经安装了 SUSE Edge 对应版本的 K3s 或 RKE2,并且您已相应地配置了 kubeconfig,以便可以以超级用户身份执行标准的 kubectl 命令。我们假设您的节点构成一个单节点集群,尽管对于多节点部署,预计不会有重大差异。
SUSE Edge 虚拟化通过三个独立的 Helm chart 进行部署,具体如下:
KubeVirt:核心虚拟化组件,即启用 Kubernetes 部署和管理虚拟机所需的 Kubernetes CRDs、Operator 和其他组件。
KubeVirt Dashboard Extension:一个可选的 Rancher UI 扩展,允许进行基本的虚拟机管理,例如启动/停止虚拟机以及访问控制台。
Containerized Data Importer (CDI):一个额外的组件,为 KubeVirt 启用持久存储集成,使虚拟机能够使用现有的 Kubernetes 存储后端来存储数据,同时也允许用户为虚拟机导入或克隆数据卷。
这些 Helm chart 中的每一个都根据您当前使用的 SUSE Edge 版本进行版本控制。对于生产/受支持的使用场景,请使用可在 SUSE Registry 中找到的制品。
首先,确保您的 kubectl 访问正常:
$ kubectl get nodes这应该显示类似于以下内容:
NAME STATUS ROLES AGE VERSION
node1.edge.rdo.wales Ready control-plane,etcd,master 4h20m v1.30.5+rke2r1
node2.edge.rdo.wales Ready control-plane,etcd,master 4h15m v1.30.5+rke2r1
node3.edge.rdo.wales Ready control-plane,etcd,master 4h15m v1.30.5+rke2r1现在,您可以继续安装 KubeVirt 和 Containerized Data Importer (CDI) Helm chart:
$ helm install kubevirt oci://registry.suse.com/edge/charts/kubevirt --namespace kubevirt-system --create-namespace
$ helm install cdi oci://registry.suse.com/edge/charts/cdi --namespace cdi-system --create-namespace几分钟后,您应该就部署好了所有 KubeVirt 和 CDI 组件。您可以通过检查 kubevirt-system 和 cdi-system 名称空间中所有已部署的资源来验证这一点。
验证 KubeVirt 资源:
$ kubectl get all -n kubevirt-system这应该显示类似于以下内容:
NAME READY STATUS RESTARTS AGE
pod/virt-operator-5fbcf48d58-p7xpm 1/1 Running 0 2m24s
pod/virt-operator-5fbcf48d58-wnf6s 1/1 Running 0 2m24s
pod/virt-handler-t594x 1/1 Running 0 93s
pod/virt-controller-5f84c69884-cwjvd 1/1 Running 1 (64s ago) 93s
pod/virt-controller-5f84c69884-xxw6q 1/1 Running 1 (64s ago) 93s
pod/virt-api-7dfc54cf95-v8kcl 1/1 Running 1 (59s ago) 118s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubevirt-prometheus-metrics ClusterIP None <none> 443/TCP 2m1s
service/virt-api ClusterIP 10.43.56.140 <none> 443/TCP 2m1s
service/kubevirt-operator-webhook ClusterIP 10.43.201.121 <none> 443/TCP 2m1s
service/virt-exportproxy ClusterIP 10.43.83.23 <none> 443/TCP 2m1s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/virt-handler 1 1 1 1 1 kubernetes.io/os=linux 93s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/virt-operator 2/2 2 2 2m24s
deployment.apps/virt-controller 2/2 2 2 93s
deployment.apps/virt-api 1/1 1 1 118s
NAME DESIRED CURRENT READY AGE
replicaset.apps/virt-operator-5fbcf48d58 2 2 2 2m24s
replicaset.apps/virt-controller-5f84c69884 2 2 2 93s
replicaset.apps/virt-api-7dfc54cf95 1 1 1 118s
NAME AGE PHASE
kubevirt.kubevirt.io/kubevirt 2m24s Deployed验证 CDI 资源:
$ kubectl get all -n cdi-system这应该显示类似于以下内容:
NAME READY STATUS RESTARTS AGE
pod/cdi-operator-55c74f4b86-692xb 1/1 Running 0 2m24s
pod/cdi-apiserver-db465b888-62lvr 1/1 Running 0 2m21s
pod/cdi-deployment-56c7d74995-mgkfn 1/1 Running 0 2m21s
pod/cdi-uploadproxy-7d7b94b968-6kxc2 1/1 Running 0 2m22s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cdi-uploadproxy ClusterIP 10.43.117.7 <none> 443/TCP 2m22s
service/cdi-api ClusterIP 10.43.20.101 <none> 443/TCP 2m22s
service/cdi-prometheus-metrics ClusterIP 10.43.39.153 <none> 8080/TCP 2m21s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/cdi-operator 1/1 1 1 2m24s
deployment.apps/cdi-apiserver 1/1 1 1 2m22s
deployment.apps/cdi-deployment 1/1 1 1 2m21s
deployment.apps/cdi-uploadproxy 1/1 1 1 2m22s
NAME DESIRED CURRENT READY AGE
replicaset.apps/cdi-operator-55c74f4b86 1 1 1 2m24s
replicaset.apps/cdi-apiserver-db465b888 1 1 1 2m21s
replicaset.apps/cdi-deployment-56c7d74995 1 1 1 2m21s
replicaset.apps/cdi-uploadproxy-7d7b94b968 1 1 1 2m22s要验证 VirtualMachine 自定义资源定义 (CRD) 是否已部署,您可以使用以下命令进行验证:
$ kubectl explain virtualmachine这应该会打印出 VirtualMachine 对象的定义,其打印结果如下:
GROUP: kubevirt.io
KIND: VirtualMachine
VERSION: v1
DESCRIPTION:
VirtualMachine handles the VirtualMachines that are not running or are in a
stopped state The VirtualMachine contains the template to create the
VirtualMachineInstance. It also mirrors the running state of the created
VirtualMachineInstance in its status.
(snip)17.4 部署虚拟机 #
现在 KubeVirt 和 CDI 已经部署完毕,让我们定义一个基于 openSUSE Tumbleweed 的简单虚拟机。此虚拟机具有最简单的配置,使用标准的“pod 网络”来实现与任何其他 pod 相同的网络配置。它还采用了非持久性存储,确保存储是临时的,就像任何没有 PVC 的容器一样。
$ cat <<EOF > user-data.yaml
#cloud-config
disable_root: false
ssh_pwauth: True
users:
- default
- name: suse
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: False
plain_text_passwd: 'suse'
EOF
$ kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: tumbleweed
namespace: default
spec:
runStrategy: Always
template:
spec:
domain:
devices: {}
machine:
type: q35
memory:
guest: 2Gi
resources: {}
volumes:
- containerDisk:
image: quay.io/containerdisks/opensuse-tumbleweed:1.0.0
name: tumbleweed-containerdisk-0
- cloudInitNoCloud:
userDataBase64: $(cat user-data.yaml | base64 -w 0)
name: cloudinitdisk
EOF这应该会打印出已创建 VirtualMachine 的信息:
virtualmachine.kubevirt.io/tumbleweed created此 VirtualMachine 定义非常简单,几乎没有指定任何配置。它只是简单地概述了它是一种内存为 2 GB 的“ q35”机器类型,使用基于临时 containerDisk 的磁盘镜像(即存储在远程镜像仓库的容器镜像中的磁盘镜像),并指定了一个 base64 编码的 cloudInit 磁盘,我们仅将其用于在启动时创建用户和强制执行密码(使用 base64 -d 进行解码)。
注意此虚拟机镜像仅用于测试。该镜像不受官方支持,仅作为文档示例。
这台机器需要几分钟才能启动,因为它需要下载 openSUSE Tumbleweed 磁盘镜像,但一旦下载完成,您可以通过查看虚拟机信息来了解有关该虚拟机的更多详细信息:
$ kubectl get vmi这应该会打印出启动该虚拟机的节点以及该虚拟机的 IP 地址。请记住,由于它使用 pod 网络,报告的 IP 地址将与任何其他 pod 一样,并且可以进行相应的路由:
NAME AGE PHASE IP NODENAME READY
tumbleweed 4m24s Running 10.42.2.98 node3.edge.rdo.wales True当在 Kubernetes 集群节点本身上运行这些命令,且 CNI 将流量直接路由到 pod(例如 Cilium)时,您应该能够直接 ssh 到机器本身。将以下 IP 地址替换为您分配给虚拟机的 IP 地址:
$ ssh suse@10.42.2.98
(password is "suse")进入此虚拟机后,您可以随意操作,但请记住它的资源有限,且仅有 1 GB 磁盘空间。完成后,Ctrl-D 或 exit 以断开 SSH 会话。
虚拟机进程仍然封装在标准的 Kubernetes pod 中。VirtualMachine CRD 是所需虚拟机的表示,但实际启动虚拟机的过程是通过 virt-launcher pod(一个标准的 Kubernetes pod,就像任何其他应用程序一样)进行的。对于启动的每个虚拟机,您可以看到有一个 virt-launcher pod:
$ kubectl get pods这应该会显示我们定义的 Tumbleweed 机器的那个 virt-launcher pod:
NAME READY STATUS RESTARTS AGE
virt-launcher-tumbleweed-8gcn4 3/3 Running 0 10m如果我们查看这个 virt-launcher pod,您会发现它正在执行 libvirt 和 qemu-kvm 进程。我们可以进入 pod 本身并查看其内部,请注意您需要根据您的 pod 名称调整以下命令:
$ kubectl exec -it virt-launcher-tumbleweed-8gcn4 -- bash进入 pod 后,尝试运行 virsh 命令并查看处理。您将看到正在运行的 qemu-system-x86_64 二进制文件,以及用于监控虚拟机的某些处理。您还将看到磁盘镜像的位置以及网络是如何连接的(作为 tap 设备):
qemu@tumbleweed:/> ps ax
PID TTY STAT TIME COMMAND
1 ? Ssl 0:00 /usr/bin/virt-launcher-monitor --qemu-timeout 269s --name tumbleweed --uid b9655c11-38f7-4fa8-8f5d-bfe987dab42c --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/run/kubevirt-ephemeral-disks --container-disk-dir /var/run/kube
12 ? Sl 0:01 /usr/bin/virt-launcher --qemu-timeout 269s --name tumbleweed --uid b9655c11-38f7-4fa8-8f5d-bfe987dab42c --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/run/kubevirt-ephemeral-disks --container-disk-dir /var/run/kubevirt/con
24 ? Sl 0:00 /usr/sbin/virtlogd -f /etc/libvirt/virtlogd.conf
25 ? Sl 0:01 /usr/sbin/virtqemud -f /var/run/libvirt/virtqemud.conf
83 ? Sl 0:31 /usr/bin/qemu-system-x86_64 -name guest=default_tumbleweed,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/run/kubevirt-private/libvirt/qemu/lib/domain-1-default_tumbleweed/master-key.aes"} -machine pc-q35-7.1,usb
286 pts/0 Ss 0:00 bash
320 pts/0 R+ 0:00 ps ax
qemu@tumbleweed:/> virsh list --all
Id Name State
------------------------------------
1 default_tumbleweed running
qemu@tumbleweed:/> virsh domblklist 1
Target Source
---------------------------------------------------------------------------------------------
sda /var/run/kubevirt-ephemeral-disks/disk-data/tumbleweed-containerdisk-0/disk.qcow2
sdb /var/run/kubevirt-ephemeral-disks/cloud-init-data/default/tumbleweed/noCloud.iso
qemu@tumbleweed:/> virsh domiflist 1
Interface Type Source Model MAC
------------------------------------------------------------------------------
tap0 ethernet - virtio-non-transitional e6:e9:1a:05:c0:92
qemu@tumbleweed:/> exit
exit最后,让我们删除此虚拟机以进行清理:
$ kubectl delete vm/tumbleweed
virtualmachine.kubevirt.io "tumbleweed" deleted17.5 使用 virtctl #
除了标准的 Kubernetes CLI 工具(即 kubectl)外,KubeVirt 还附带了一个 CLI 实用程序,它允许您以一种弥合虚拟化世界与 Kubernetes 设计初衷之间的某些差距的方式与集群进行交互。例如,virtctl 工具提供了管理虚拟机生命周期(启动、停止、重启等)、提供对虚拟控制台的访问、上传虚拟机镜像以及与 Kubernetes 结构(如服务)进行交互的功能,而无需直接使用 API 或 CRD。
让我们下载 virtctl 工具的最新稳定版本:
$ export VERSION=v0.7.0
$ wget https://github.com/kubevirt/kubevirt/releases/download/$VERSION/virtctl-$VERSION-linux-amd64如果您使用的是不同的架构或非 Linux 机器,可以在 此处找到其他版本。在继续之前,您需要使其可执行,将其移动到`$PATH`中的某个位置可能会很有用:
$ mv virtctl-$VERSION-linux-amd64 /usr/local/bin/virtctl
$ chmod a+x /usr/local/bin/virtctl然后,您可以使用 virtctl 命令行工具来创建虚拟机。让我们复制之前的虚拟机,注意我们将输出直接通过管道传输到`kubectl apply`:
$ cat <<EOF > user-data.yaml
#cloud-config
disable_root: false
ssh_pwauth: True
users:
- default
- name: suse
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: False
plain_text_passwd: 'suse'
EOF
$ alias virtctl=echo
$ virtctl create vm --name virtctl-example --memory=1Gi \
--volume-containerdisk=src:quay.io/containerdisks/opensuse-tumbleweed:1.0.0 \
--cloud-init-user-data "$(cat user-data.yaml | base64 -w 0)"此时应该会显示虚拟机正在运行(鉴于容器镜像已被缓存,这次启动速度应该会快得多):
$ kubectl get vmi
NAME AGE PHASE IP NODENAME READY
virtctl-example 52s Running 10.42.2.29 node3.edge.rdo.wales True现在我们可以使用 virtctl 直接连接到虚拟机:
$ virtctl ssh suse@virtctl-example
(password is "suse" - Ctrl-D to exit)virtctl 还可以使用许多其他命令。例如,如果网络无法正常工作,virtctl console 可以让您访问串行控制台,并且您可以使用 virtctl guestosinfo 获取全面的操作系统信息,前提是客户机已安装并运行 qemu-guest-agent。
最后,让我们暂停并恢复虚拟机:
$ virtctl pause vm virtctl-example
VMI virtctl-example was scheduled to pause您会发现 VirtualMachine 对象显示为 Paused,而 VirtualMachineInstance 对象显示为 Running,但 READY=False:
$ kubectl get vm
NAME AGE STATUS READY
virtctl-example 8m14s Paused False
$ kubectl get vmi
NAME AGE PHASE IP NODENAME READY
virtctl-example 8m15s Running 10.42.2.29 node3.edge.rdo.wales False您还会发现无法再连接到该虚拟机:
$ virtctl ssh suse@virtctl-example
can't access VMI virtctl-example: Operation cannot be fulfilled on virtualmachineinstance.kubevirt.io "virtctl-example": VMI is paused让我们恢复虚拟机并重试:
$ virtctl unpause vm virtctl-example
VMI virtctl-example was scheduled to unpause现在我们应该能够重新建立连接:
$ virtctl ssh suse@virtctl-example
suse@vmi/virtctl-example.default's password:
suse@virtctl-example:~> exit
logout最后,让我们去除该虚拟机:
$ kubectl delete vm/virtctl-example
virtualmachine.kubevirt.io "virtctl-example" deleted17.6 简单的入口网络 #
在本节中,我们将展示如何将虚拟机作为标准 Kubernetes 服务公开,并通过 Kubernetes 入口服务使其可用,例如 Traefik with RKE2或 Traefik with K3s。本文档假设这些组件已正确配置,并且您拥有适当的 DNS 指针(例如通过通配符),指向您的 Kubernetes 服务器节点或入口虚拟 IP,以便进行正确的入口解析。
注意在 SUSE Edge 3.1+ 版本中,如果您在多服务器节点配置中使用 K3s,可能需要为 Ingress 配置基于 MetalLB 的 VIP;RKE2 则不需要这样做。
在示例环境中,部署了另一台 openSUSE Tumbleweed 虚拟机,使用 cloud-init 在启动时安装 NGINX 作为简单的 Web 服务器,并配置了一条简单的消息,以便在调用时验证其是否按预期工作。要了解具体操作,只需`base64 -d`下方输出中的 cloud-init 部分即可。
现在让我们创建这台虚拟机:
$ cat <<EOF > user-data.yaml
#cloud-config
disable_root: false
ssh_pwauth: True
users:
- default
- name: suse
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: False
plain_text_passwd: 'suse'
EOF
$ kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: ingress-example
namespace: default
spec:
runStrategy: Always
template:
metadata:
labels:
app: nginx
spec:
domain:
devices: {}
machine:
type: q35
memory:
guest: 2Gi
resources: {}
volumes:
- containerDisk:
image: quay.io/containerdisks/opensuse-tumbleweed:1.0.0
name: tumbleweed-containerdisk-0
- cloudInitNoCloud:
userDataBase64: $(cat user-data.yaml | base64 -w 0)
name: cloudinitdisk
EOF当该虚拟机成功启动后,我们可以使用 virtctl 命令来公开 VirtualMachineInstance,其外部端口为 8080,目标端口为 80(NGINX 默认侦听该端口)。我们在此处使用 virtctl 命令,因为它能够理解虚拟机对象与 Pod 之间的映射关系。这为我们创建了一个新服务:
$ virtctl expose vmi ingress-example --port=8080 --target-port=80 --name=ingress-example
Service ingress-example successfully exposed for vmi ingress-example然后,我们将自动创建一个相应的服务:
$ kubectl get svc/ingress-example
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-example ClusterIP 10.43.217.19 <none> 8080/TCP 9s接下来,如果您随后使用 kubectl create ingress,我们可以创建一个指向此服务的 ingress 对象。在此处调整 URL(在 ingress 对象中称为“host”),以匹配您的 DNS 配置,并确保将其指向端口 8080:
$ kubectl create ingress ingress-example --rule=ingress-example.suse.local/=ingress-example:8080在正确配置 DNS 后,您应该能够立即 curl 该 URL:
$ curl ingress-example.suse.local
It works!让我们通过去除此虚拟机及其服务和 ingress 资源来进行清理:
$ kubectl delete vm/ingress-example svc/ingress-example ingress/ingress-example
virtualmachine.kubevirt.io "ingress-example" deleted
service "ingress-example" deleted
ingress.networking.k8s.io "ingress-example" deleted17.7 使用 Rancher UI 扩展 #
SUSE Edge Virtualization 为 Rancher Manager 提供了一个 UI 扩展,支持使用 Rancher 仪表板 UI 进行基本的虚拟机管理。
17.7.1 安装 #
有关安装指南,请参阅 Rancher Dashboard Extensions (第 5 章 “Rancher 仪表板扩展”)。
17.7.2 使用 KubeVirt Rancher 仪表板扩展 #
该扩展在集群资源管理器中引入了一个新的 KubeVirt 部分。此部分将添加到任何安装了 KubeVirt 的托管集群中。
该扩展允许您直接与 KubeVirt 虚拟机资源交互,以管理虚拟机的生命周期。
17.7.2.1 创建虚拟机 #
导航至 Cluster Explorer,点击左侧导航栏中启用了 KubeVirt 的托管集群。
导航至 KubeVirt > Virtual Machines 页面,然后点击屏幕右上角的
Create from YAML。填写或粘贴虚拟机定义,然后按
Create。使用“部署虚拟机”部分中的虚拟机定义作为参考。
17.7.2.2 虚拟机操作 #
您可以使用每个虚拟机右侧 ⋮ 下拉列表中的操作菜单来执行启动、停止、暂停或软重启操作。或者,您也可以通过选择要对其执行操作的虚拟机,使用列表顶部的组操作。
执行这些操作可能会对虚拟机运行策略产生影响。 请参阅 KubeVirt 文档中的表格以了解更多详细信息。
17.7.2.3 访问虚拟机控制台 #
“虚拟机”列表提供了一个 Console 下拉列表,允许使用 VNC 或串行控制台 连接到机器。此操作仅适用于正在运行的机器。
在某些情况下,刚启动的虚拟机需要片刻时间才能访问控制台。
17.8 使用 Edge Image Builder 进行安装 #
SUSE Edge 正在使用 第 8 章 “Edge Image Builder” 来定制基础 SUSE Linux Micro OS 镜像。 请遵循 第 25.9 节 “KubeVirt 和 CDI 安装”,以便在 EIB 配置的 Kubernetes 集群之上进行 KubeVirt 和 CDI 的隔离的安装。
18 系统升级控制器 #
请参阅 系统升级控制器文档。
系统升级控制器 (SUC) 旨在提供一个通用的、Kubernetes 原生的升级控制器(针对节点)。它引入了一个新的 CRD,即 Plan,用于定义您的所有升级策略/要求。Plan 是对集群中节点进行变更的待处理意图。
18.1 SUSE Edge 如何使用系统升级控制器? #
SUSE Edge 使用 SUC 来促进与管理集群和下游集群上的操作系统及 Kubernetes 版本升级相关的各种“第 2 天”操作。
“第 2 天”操作通过 SUC Plans 定义。基于这些计划,SUC 在每个节点上部署工作负载以执行相应的“第 2 天”操作。
SUC 也用于 第 19 章 “升级控制器” 中。要了解有关 SUC 与 Upgrade Controller 之间主要区别的更多信息,请参阅 第 19.2 节 “升级控制器与系统升级控制器”。
18.2 安装系统升级控制器 #
从 Rancher v2.10.0 开始,System Upgrade Controller 会自动安装。
仅当您的环境 not 由 Rancher 管理,或者您的 Rancher 版本低于 v2.10.0 时,请遵循以下步骤 only。
我们建议您通过位于 suse-edge/fleet-examples 储存库中的 Fleet (第 6 章 “Fleet”) 安装 SUC。
suse-edge/fleet-examples 储存库提供的资源 必须 始终从有效的 fleet-examples 版本 中使用。要确定您需要使用哪个版本,请参阅 发行说明 (第 41 章 “发行说明”)。
如果您无法使用 Fleet 安装 SUC,则可以通过 Rancher 的 Helm chart 储存库进行安装,或者将 Rancher 的 Helm chart 合并到您自己的第三方 GitOps 工作流程中。
本节涵盖:
18.2.1 System Upgrade Controller Fleet 安装 #
使用 Fleet,有两种可能的资源可用于部署 SUC:
GitRepo 资源 - 适用于有外部/本地 Git 服务器可用的用例。有关安装说明,请参阅 System Upgrade Controller 安装 - GitRepo (第 18.2.1.1 节 “System Upgrade Controller 安装 - GitRepo”)。
Bundle 资源 - 适用于不支持本地 Git 服务器选项的隔离的用例。有关安装说明,请参阅 System Upgrade Controller 安装 - Bundle (第 18.2.1.2 节 “系统升级控制器安装 - Bundle”)。
18.2.1.1 System Upgrade Controller 安装 - GitRepo #
在您的 管理 集群中:
确定要在哪些集群上部署 SUC。这可以通过在您的 管理 集群上的正确 Fleet 工作区中部署 SUC
GitRepo资源来完成。默认情况下,Fleet 有两个工作区:fleet-local- 用于需要在 管理 集群上部署的资源。fleet-default- 用于需要部署在 下游 集群上的资源。有关 Fleet 工作区的更多信息,请参阅 上游 文档。
部署
GitRepo资源:要在您的管理集群上部署 SUC:
kubectl apply -n fleet-local -f - <<EOF apiVersion: fleet.cattle.io/v1alpha1 kind: GitRepo metadata: name: system-upgrade-controller spec: revision: release-3.6.1 paths: - fleets/day2/system-upgrade-controller repo: https://github.com/suse-edge/fleet-examples.git EOF要在您的下游集群上部署 SUC:
注意在部署以下资源之前,您 必须 提供有效的
targets配置,以便 Fleet 知道在哪些下游集群上部署您的资源。有关如何映射到下游集群的信息,请参阅 Mapping to Downstream Clusters。kubectl apply -n fleet-default -f - <<EOF apiVersion: fleet.cattle.io/v1alpha1 kind: GitRepo metadata: name: system-upgrade-controller spec: revision: release-3.6.1 paths: - fleets/day2/system-upgrade-controller repo: https://github.com/suse-edge/fleet-examples.git targets: - clusterSelector: CHANGEME # Example matching all clusters: # targets: # - clusterSelector: {} EOF
验证
GitRepo资源是否已部署:# Namespace will vary based on where you want to deploy SUC kubectl get gitrepo system-upgrade-controller -n <fleet-local/fleet-default> NAME REPO COMMIT BUNDLEDEPLOYMENTS-READY STATUS system-upgrade-controller https://github.com/suse-edge/fleet-examples.git release-3.6.1 1/1验证系统升级控制器部署:
kubectl get deployment system-upgrade-controller -n cattle-system NAME READY UP-TO-DATE AVAILABLE AGE system-upgrade-controller 1/1 1 1 2m20s
18.2.1.2 系统升级控制器安装 - Bundle #
本节说明如何使用 fleet-cli 从标准 Fleet 配置构建和部署 Bundle 资源。
在具有网络访问权限的机器上下载
fleet-cli:注意请确保您下载的 fleet-cli 版本与集群上部署的 Fleet 版本相匹配。
对于 Mac 用户,有一个 fleet-cli Homebrew 公式。
对于 Linux 和 Windows 用户,二进制文件作为每个 Fleet release 的 assets 提供。
Linux AMD:
curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/vv0.15.2/fleet-linux-amd64Linux ARM:
curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/vv0.15.2/fleet-linux-arm64
使
fleet-cli成为一个可执行程序:chmod +x fleet-cli克隆您希望使用的
suse-edge/fleet-examplesrelease:git clone -b release-3.6.1 https://github.com/suse-edge/fleet-examples.git导航到位于
fleet-examples储存库中的 SUC fleet:cd fleet-examples/fleets/day2/system-upgrade-controller确定要在哪些集群上部署 SUC。这可以通过在管理集群内的正确 Fleet 工作区中部署 SUC Bundle 来完成。默认情况下,Fleet 有两个工作区:
fleet-local- 用于需要在 管理 集群上部署的资源。fleet-default- 用于需要部署在 下游 集群上的资源。有关 Fleet 工作区的更多信息,请参阅 upstream 文档。
如果您打算仅在下游集群上部署 SUC,请创建一个与特定集群匹配的
targets.yaml文件:cat > targets.yaml <<EOF targets: - clusterSelector: CHANGEME EOF有关如何映射到下游集群的信息,请参阅 映射到下游集群。
继续构建 Bundle:
注意请确保您 not 在
fleet-examples/fleets/day2/system-upgrade-controller目录中下载 fleet-cli,否则它会被打包到 Bundle 中,这不被建议。要在您的管理集群上部署 SUC,请执行:
fleet-cli apply --compress -n fleet-local -o - system-upgrade-controller . > system-upgrade-controller-bundle.yaml要在您的下游集群上部署 SUC,请执行:
fleet-cli apply --compress --targets-file=targets.yaml -n fleet-default -o - system-upgrade-controller . > system-upgrade-controller-bundle.yaml有关此过程的更多信息,请参阅 将 Helm Chart 转换为 Bundle。
有关
fleet-cli apply命令的更多信息,请参阅 fleet apply。
将
system-upgrade-controller-bundle.yamlbundle 传输到您的管理集群机器:scp system-upgrade-controller-bundle.yaml <machine-address>:<filesystem-path>在您的管理集群上,部署
system-upgrade-controller-bundle.yamlBundle:kubectl apply -f system-upgrade-controller-bundle.yaml在您的管理集群上,验证 Bundle 是否已部署:
# Namespace will vary based on where you want to deploy SUC kubectl get bundle system-upgrade-controller -n <fleet-local/fleet-default> NAME BUNDLEDEPLOYMENTS-READY STATUS system-upgrade-controller 1/1根据您部署 Bundle 的 Fleet 工作区,导航至该集群并验证 SUC 部署:
注意SUC 始终部署在 cattle-system 名称空间中。
kubectl get deployment system-upgrade-controller -n cattle-system NAME READY UP-TO-DATE AVAILABLE AGE system-upgrade-controller 1/1 1 1 111s
18.2.2 System Upgrade Controller Helm 安装 #
添加 Rancher chart 储存库:
helm repo add rancher-charts https://charts.rancher.io/部署 SUC chart:
helm install system-upgrade-controller rancher-charts/system-upgrade-controller --version 109.0.1 --set global.cattle.psp.enabled=false -n cattle-system --create-namespace这将安装 Edge 3.6 平台所需的 SUC 版本 v0.19.1。
验证 SUC 部署:
kubectl get deployment system-upgrade-controller -n cattle-system NAME READY UP-TO-DATE AVAILABLE AGE system-upgrade-controller 1/1 1 1 37s
18.3 监控 System Upgrade Controller 计划 #
可以通过以下方式查看 SUC 计划:
通过 Rancher UI (第 18.3.1 节 “监控 System Upgrade Controller 计划 - Rancher UI”)。
通过集群内部的 manual monitoring (第 18.3.2 节 “监控 System Upgrade Controller 计划 - 手动”)。
为 SUC 计划部署的 Pod 在成功执行后会保持存活 15 分钟。此后,它们将由创建它们的相应 Job 移除。若要在此时间段后访问 Pod 的日志,您应该为集群启用日志记录。有关如何在 Rancher 中执行此操作的信息,请参阅 Rancher Integration with Logging Services。
18.3.1 监控 System Upgrade Controller 计划 - Rancher UI #
要检查特定 SUC 计划的 Pod 日志:
在左上角,☰ → <your-cluster-name>
选择 Workloads → Pods
选择
Only User Namespaces下拉菜单并添加cattle-system名称空间在 Pod 筛选栏中,输入您的 SUC 计划 Pod 的名称。名称将采用以下模板格式:
apply-<plan_name>-on-<node_name>注意对于特定的 SUC 计划,可能同时存在
Completed和UnknownPod。这是预期情况,由某些升级的性质导致。选择您要查看日志的 Pod,然后导航至 ⋮ → View Logs
18.3.2 监控 System Upgrade Controller 计划 - 手动 #
以下步骤假设 kubectl 已配置为连接到部署了 SUC 计划 的集群。
列出已部署的 SUC 计划:
kubectl get plans -n cattle-system获取 SUC 计划的 Pod:
kubectl get pods -l upgrade.cattle.io/plan=<plan_name> -n cattle-system注意对于特定的 SUC 计划,可能同时存在
Completed和UnknownPods。这是预期的情况,由于某些升级的性质所致。获取 Pod 的日志:
kubectl logs <pod_name> -n cattle-system
19 升级控制器 #
一种能够对以下 SUSE Edge 平台组件执行升级的 Kubernetes 控制器:
操作系统 (SUSE Linux Micro)
Kubernetes (K3s & RKE2)
其他组件(Rancher、Elemental、SUSE Security 等)
升级控制器通过将上述组件的复杂性封装在单个`user-facing`资源中,简化了它们的升级过程,该资源可作为升级的*触发器*。用户只需配置此资源,其余工作均由`Upgrade Controller`处理。
19.1 SUSE Edge如何使用升级控制器? #
*升级控制器*对于自动化(以前需要手动执行的)将管理集群从一个SUSE Edge发布版本升级到下一个版本所需的“第 2 天”操作至关重要。
为了实现这种自动化,升级控制器利用了诸如系统升级控制器 (第 18 章 “系统升级控制器”)和Helm 控制器等工具。
有关升级控制器工作原理的更多详细信息,请参见第 19.5 节 “升级控制器如何工作?”。
有关升级控制器的已知限制,请参见第 19.8 节 “已知限制”。
有关升级控制器与系统升级控制器之间区别的信息,请参见第 19.2 节 “升级控制器与系统升级控制器”。
19.2 升级控制器与系统升级控制器 #
系统升级控制器 (SUC) (第 18 章 “系统升级控制器”) 是一种通用工具,用于将升级指令传播到特定的 Kubernetes 节点。
虽然它支持 SUSE Edge 平台的某些“第 2 天”操作,但它 并不 涵盖所有操作。此外,即使对于受支持的操作,用户也必须手动配置、维护和部署多个 SUC Plans —— 这是一个容易出错的过程,可能会导致意外问题。
这导致需要一种工具来 自动化 并 抽象 管理 SUSE Edge 平台各种“第 2 天”操作的复杂性。因此,开发了 Upgrade Controller。它通过引入一个驱动升级的单一 user-facing resource 来简化升级过程。用户只需管理此资源,其余工作由 Upgrade Controller 处理。
19.3 安装升级控制器 #
19.3.1 先决条件 #
系统升级控制器 (第 18.2 节 “安装系统升级控制器”)
一个 Kubernetes 集群;K3s 或 RKE2 均可
19.3.2 步骤 #
在您的管理集群上安装 Upgrade Controller Helm chart:
helm install upgrade-controller oci://registry.suse.com/edge/charts/upgrade-controller --version 306.0.4+up0.1.3 --create-namespace --namespace upgrade-controller-system验证 Upgrade Controller 部署:
kubectl get deployment -n upgrade-controller-system验证 Upgrade Controller Pod:
kubectl get pods -n upgrade-controller-system验证 Upgrade Controller Pod 日志:
kubectl logs <pod_name> -n upgrade-controller-system
19.4 通过 Edge Image Builder 安装 Upgrade Controller #
作为上述手动安装的替代方案,可以在Edge Image Builder (第 8 章 “Edge Image Builder”)编排的初始部署中安装 Upgrade Controller。
在这种情况下,需要将以下 Helm chart 配置添加到 EIB 配置文件中:
kubernetes:
helm:
charts:
- name: cert-manager
repositoryName: jetstack
version: {version-cert-manager}
targetNamespace: cert-manager
valuesFile: certmanager-values.yaml
createNamespace: true
installationNamespace: kube-system
- name: upgrade-controller
version: {version-upgrade-controller-chart}
repositoryName: suse-edge-charts
targetNamespace: upgrade-controller-system
createNamespace: true
installationNamespace: kube-system19.5 升级控制器如何工作? #
为了执行 Edge 版本升级,Upgrade Controller 引入了两个新的 Kubernetes 自定义资源:
UpgradePlan (第 19.6.1 节 “UpgradePlan”) - 由用户创建;包含有关 Edge 版本升级的配置。
ReleaseManifest (第 19.6.2 节 “ReleaseManifest”) - 由 Upgrade Controller 创建;包含特定于某个 Edge 发布版本的组件版本。此文件不得由用户编辑。
Upgrade Controller 随后会创建一个 ReleaseManifest 资源,其中包含用户在 UpgradePlan 资源的 releaseVersion 属性下指定的 Edge 发布版本的组件数据。
使用来自 ReleaseManifest 的组件数据,Upgrade Controller 按以下顺序升级 Edge 发布组件:
操作系统 (OS) (第 19.5.1 节 “操作系统升级”)。
Kubernetes (第 19.5.2 节 “Kubernetes 升级”)。
附加组件 (第 19.5.3 节 “附加组件升级”)。
在升级过程中,Upgrade Controller 会持续将升级信息输出到所创建的 UpgradePlan 中。有关如何跟踪升级过程的更多信息,请参阅跟踪升级过程 (第 19.7 节 “跟踪升级过程”)。
19.5.1 操作系统升级 #
为了升级操作系统,Upgrade Controller 会创建具有以下命名模板的SUC (第 18 章 “系统升级控制器”)计划:
对于与控制平面节点操作系统升级相关的 SUC 计划 -
control-plane-<os-name>-<os-version>-<suffix>。对于与工作节点操作系统升级相关的 SUC 计划 -
workers-<os-name>-<os-version>-<suffix>。
基于这些计划,SUC 会在集群的每个节点上创建执行实际操作系统升级的工作负载。
根据 ReleaseManifest,操作系统升级可能包括:
仅软件包更新 - 用于 Edge 版本之间操作系统版本不发生变化的使用场景。
完整操作系统迁移 - 用于 Edge 版本之间操作系统版本发生变化的使用场景。
升级按*one*节点的顺序执行,首先从控制平面节点开始。只有在控制平面节点升级完成后,工作节点才会开始升级。
Upgrade Controller 会配置 OS SUC 计划,如果集群中指定类型的节点超过*one*,则对集群节点执行排空操作。
对于控制平面节点*greater than* one且只有*only one*工作节点的集群,仅会对控制平面节点执行排空操作,反之亦然。
有关如何完全禁用节点排空的信息,请参阅UpgradePlan (第 19.6.1 节 “UpgradePlan”)部分。
19.5.2 Kubernetes 升级 #
要升级集群的 Kubernetes 发行版,升级控制器会创建具有以下命名模板的SUC (第 18 章 “系统升级控制器”)计划:
对于与控制平面节点 Kubernetes 升级相关的 SUC 计划 -
control-plane-<k8s-version>-<suffix>。对于与工作节点 Kubernetes 升级相关的 SUC 计划 -
workers-<k8s-version>-<suffix>。
基于这些计划,SUC 将继续在集群的每个节点上创建执行实际 Kubernetes 升级的工作负载。
Kubernetes 升级将按*one*节点的顺序执行,首先从控制平面节点开始。只有在控制平面节点升级完成后,工作节点才会开始升级。
升级控制器会配置 Kubernetes SUC 计划,如果集群中指定类型的节点超过*one*,则对集群节点执行排空操作。
对于控制平面节点*greater than* one且只有*only one*工作节点的集群,仅会对控制平面节点执行排空操作,反之亦然。
有关如何完全禁用节点排空的信息,请参阅 第 19.6.1 节 “UpgradePlan”。
19.5.3 附加组件升级 #
目前,所有附加组件均通过 Helm 图表安装。有关特定版本组件的完整列表,请参阅Release Notes (第 41 章 “发行说明”)。
对于通过EIB (第 8 章 “Edge Image Builder”)部署的 Helm 图表,升级控制器会更新每个组件现有的HelmChart CR。
对于在 EIB 之外部署的 Helm 图表,升级控制器会为每个组件创建一个 HelmChart 资源。
在创建/更新 HelmChart 资源后,升级控制器会依赖 helm-controller 来获取此更改并继续进行实际的组件升级。
图表将根据其在 ReleaseManifest 中的顺序依次升级。还可以通过 UpgradePlan 传递其他值。如果图表的版本在新的 SUSE Edge 发行版中保持不变,则不会对其进行升级。有关更多信息,请参见第 19.6.1 节 “UpgradePlan”。
19.6 Kubernetes API 扩展 #
由升级控制器引入的 Kubernetes API 扩展。
19.6.1 UpgradePlan #
升级控制器引入了一种新的 Kubernetes 自定义资源,称为 UpgradePlan。
UpgradePlan 用作升级控制器的指令机制,它支持以下配置:
releaseVersion- 集群应升级到的 Edge 发行版本。发行版本必须遵循semantic版本控制,并应从Release Notes (第 41 章 “发行说明”)中获取。disableDrain- 可选;指示升级控制器是否禁用节点 驱逐。适用于您拥有带有 中断预算 的工作负载的情况。禁用控制平面节点驱逐的示例:
spec: disableDrain: controlPlane: true禁用控制平面和工作节点驱逐的示例:
spec: disableDrain: controlPlane: true worker: true
helm- 可选;指定通过 Helm 安装的组件的其他值。警告仅建议将此字段用于对升级至关重要的值。标准的 Chart 值更新应在相应的 Chart 升级到下一个版本后执行。
示例:
spec: helm: - chart: foo values: bar: baz
19.6.2 ReleaseManifest #
升级控制器引入了一种新的 Kubernetes 自定义资源,称为 ReleaseManifest。
ReleaseManifest 资源由升级控制器创建,并保存 一个 特定 Edge 发行版本的数据。这意味着每个 Edge 发行版本的升级都将由不同的 ReleaseManifest 资源表示。
发布清单应始终由升级控制器创建。
不建议手动创建或编辑 ReleaseManifest 资源。决定这样做的用户应 自行承担风险。
发布清单附带的组件数据包括但不限于:
有关发布清单外观的示例,请参阅 上游 文档。请注意,这仅是一个示例,并非旨在创建为有效的 ReleaseManifest 资源。
19.7 跟踪升级过程 #
本节旨在跟踪和调试用户创建 UpgradePlan 资源后由升级控制器启动的升级过程。
19.7.1 通用 #
有关升级过程状态的一般信息可以在升级计划的状态条件中查看。
可以通过以下方式查看升级计划资源的状态:
kubectl get upgradeplan <upgradeplan_name> -n upgrade-controller-system -o yamlapiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
name: upgrade-plan-mgmt
namespace: upgrade-controller-system
spec:
releaseVersion: 3.6
status:
conditions:
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: Control plane nodes are being upgraded
reason: InProgress
status: "False"
type: OSUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: Kubernetes upgrade is not yet started
reason: Pending
status: Unknown
type: KubernetesUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: Rancher upgrade is not yet started
reason: Pending
status: Unknown
type: RancherUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: Longhorn upgrade is not yet started
reason: Pending
status: Unknown
type: LonghornUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: MetalLB upgrade is not yet started
reason: Pending
status: Unknown
type: MetalLBUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: CDI upgrade is not yet started
reason: Pending
status: Unknown
type: CDIUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: KubeVirt upgrade is not yet started
reason: Pending
status: Unknown
type: KubeVirtUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: NeuVector upgrade is not yet started
reason: Pending
status: Unknown
type: NeuVectorUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: EndpointCopierOperator upgrade is not yet started
reason: Pending
status: Unknown
type: EndpointCopierOperatorUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: Elemental upgrade is not yet started
reason: Pending
status: Unknown
type: ElementalUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: SRIOV upgrade is not yet started
reason: Pending
status: Unknown
type: SRIOVUpgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: Metal3 upgrade is not yet started
reason: Pending
status: Unknown
type: Metal3Upgraded
- lastTransitionTime: "2024-10-01T06:26:27Z"
message: RancherTurtles upgrade is not yet started
reason: Pending
status: Unknown
type: RancherTurtlesUpgraded
observedGeneration: 1
sucNameSuffix: 90315a2b6d在这里,您可以查看升级控制器将尝试为其安排升级的每个组件。每个条件都遵循以下模板:
lastTransitionTime- 此组件条件上一次从一种状态转换为另一种状态的时间。message- 指示特定组件条件的当前升级状态的消息。reason- 特定组件条件的当前升级状态。可能的reasons包括:Succeeded- 特定组件升级成功。Failed- 特定组件升级失败。InProgress- 特定组件升级正在进行中。Pending- 特定组件升级尚未安排。Skipped- 在集群上未找到特定组件,因此将跳过其升级。Error- 特定组件遇到瞬态错误。
status- 当前条件type的状态,属于True、False、Unknown之一。type- 当前升级组件的指示器。
升级控制器为类型为 OSUpgraded 和 KubernetesUpgraded 的组件条件创建 SUC 计划。要进一步跟踪为这些组件创建的 SUC 计划,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
所有其他组件条件类型可以通过查看由 helm-controller 为其创建的资源来进一步跟踪。有关详细信息,请参见 第 19.7.2 节 “Helm Controller”。
由升级控制器调度的升级计划可以在满足以下条件时标记为 successful:
不存在
Pending或InProgress组件条件。lastSuccessfulReleaseVersion属性指向升级计划配置中指定的releaseVersion。一旦升级过程成功,此属性将由升级控制器添加到升级计划的状态中。
UpgradePlan 示例: #apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
name: upgrade-plan-mgmt
namespace: upgrade-controller-system
spec:
releaseVersion: 3.6
status:
conditions:
- lastTransitionTime: "2024-10-01T06:26:48Z"
message: All cluster nodes are upgraded
reason: Succeeded
status: "True"
type: OSUpgraded
- lastTransitionTime: "2024-10-01T06:26:59Z"
message: All cluster nodes are upgraded
reason: Succeeded
status: "True"
type: KubernetesUpgraded
- lastTransitionTime: "2024-10-01T06:27:13Z"
message: Chart rancher upgrade succeeded
reason: Succeeded
status: "True"
type: RancherUpgraded
- lastTransitionTime: "2024-10-01T06:27:13Z"
message: Chart longhorn is not installed
reason: Skipped
status: "False"
type: LonghornUpgraded
- lastTransitionTime: "2024-10-01T06:27:13Z"
message: Specified version of chart metallb is already installed
reason: Skipped
status: "False"
type: MetalLBUpgraded
- lastTransitionTime: "2024-10-01T06:27:13Z"
message: Chart cdi is not installed
reason: Skipped
status: "False"
type: CDIUpgraded
- lastTransitionTime: "2024-10-01T06:27:13Z"
message: Chart kubevirt is not installed
reason: Skipped
status: "False"
type: KubeVirtUpgraded
- lastTransitionTime: "2024-10-01T06:27:13Z"
message: Chart neuvector-crd is not installed
reason: Skipped
status: "False"
type: NeuVectorUpgraded
- lastTransitionTime: "2024-10-01T06:27:14Z"
message: Specified version of chart endpoint-copier-operator is already installed
reason: Skipped
status: "False"
type: EndpointCopierOperatorUpgraded
- lastTransitionTime: "2024-10-01T06:27:14Z"
message: Chart elemental-operator upgrade succeeded
reason: Succeeded
status: "True"
type: ElementalUpgraded
- lastTransitionTime: "2024-10-01T06:27:15Z"
message: Chart sriov-crd is not installed
reason: Skipped
status: "False"
type: SRIOVUpgraded
- lastTransitionTime: "2024-10-01T06:27:19Z"
message: Chart metal3 is not installed
reason: Skipped
status: "False"
type: Metal3Upgraded
- lastTransitionTime: "2024-10-01T06:27:27Z"
message: Chart rancher-turtles is not installed
reason: Skipped
status: "False"
type: RancherTurtlesUpgraded
lastSuccessfulReleaseVersion: 3.6
observedGeneration: 1
sucNameSuffix: 90315a2b6d19.7.2 Helm Controller #
本节介绍如何跟踪由 helm-controller 创建的资源。
以下步骤假设 kubectl 已配置为连接到部署了升级控制器的集群。
找到特定组件的
HelmChart资源:kubectl get helmcharts -n kube-system使用
HelmChart资源的名称,找到由helm-controller创建的升级 Pod:kubectl get pods -l helmcharts.helm.cattle.io/chart=<helmchart_name> -n kube-system # Example for Rancher kubectl get pods -l helmcharts.helm.cattle.io/chart=rancher -n kube-system NAME READY STATUS RESTARTS AGE helm-install-rancher-tv9wn 0/1 Completed 0 16m查看组件特定 Pod 的日志:
kubectl logs <pod_name> -n kube-system
19.8 已知限制 #
下游集群升级尚不由升级控制器管理。有关如何升级下游集群的信息,请参阅 第 33 章 “下游集群”。
升级控制器要求通过 EIB (第 8 章 “Edge Image Builder”) 部署的任何额外 SUSE Edge Helm chart 必须将其 HelmChart CR 部署在
kube-system名称空间中.为此,请在您的 EIB 定义文件中配置installationNamespace属性。有关详细信息,请参见 上游 文档。目前,升级控制器无法确定管理集群上当前运行的 Edge 发行版本。请确保提供的 Edge 发行版本高于集群上当前运行的 Edge 发行版本.
目前,升级控制器仅支持 非隔离的 环境升级。隔离的 升级尚不可行。
20 SUSE Multi-Linux Manager #
SUSE Multi-Linux Manager 包含在 SUSE Edge 中,旨在提供自动化和控制功能,以确保边缘部署中所有节点的 SUSE Linux Micro 作为底层操作系统始终保持最新状态。
有关更多信息,请参阅 第 3 章 “SUSE Multi-Linux Manager” 和 SUSE Multi-Linux Manager 文档。
第 III 部分 How-to 指南 #
How-to 指南和最佳实践
- 21 K3s 上的 MetalLB(使用层 2 模式)
MetalLB 是一种用于裸机 Kubernetes 集群的负载平衡器实现,它使用标准路由协议。
- 22 K3s 上的 MetalLB(使用层 3 模式)
MetalLB 是一个用于裸机 Kubernetes 集群的负载均衡器实现,它使用标准路由协议。
- 23 K3s 上的 MetalLB(使用 FRR-K8s 模式)
MetalLB 是一种用于裸机 Kubernetes 集群的负载均衡器实现,它使用标准路由协议。
- 24 Kubernetes API 服务器前的 MetalLB
本指南演示了如何使用 MetalLB 服务在具有三个控制平面节点的高可用集群上向外部暴露 RKE2/K3s API。 为实现此目的,将手动创建一个 LoadBalancer 类型的 Kubernetes 服务。然后将自动创建一个 EndpointSlices 对象,该对象使集群中所有控制平面节点的 IP 保持可用。 为了使 EndpointSlices 与集群中发生的事件(添加/删除节点或节点离线)持续同步,将部署 Endpoint Copier Operator (第 16 章 “端点复制器操作员”)。该 Operator 会监控默认 kubernetes EndpointSlices 中发…
- 25 使用 Edge Image Builder 进行隔离的部署
本指南将展示如何利用 Edge Image Builder(EIB) (第 8 章 “Edge Image Builder”) 在 SUSE Linux Micro 6.2 上完全隔离地部署 SUSE Edge 的多个组件。通过此操作,您将能够引导至由 EIB 创建的定制化、可启动 (CRB) 镜像,并在没有互联网连接且无需任何手动操作的情况下,在 RKE2 或 K3s 集群上部署指定的组件。对于希望将部署所需的所有工件预先构建到其操作系统镜像中,以便在引导时立即可用的客户,此配置非常理想。
- 26 使用 Kiwi 构建更新的 SUSE Linux Micro 镜像
本节介绍了如何生成更新的 SUSE Linux Micro 镜像,以供 Edge Image Builder、Cluster API (CAPI) + Metal3 使用,或直接将磁盘镜像写入块设备。此过程在以下情况下非常有用:需要在初始系统引导镜像中包含最新补丁(以最大限度地减少安装后的补丁传输),或者在使用 CAPI 的场景中,首选使用新镜像重新安装操作系统,而不是就地升级主机。
21 K3s 上的 MetalLB(使用层 2 模式) #
MetalLB 是一种用于裸机 Kubernetes 集群的负载平衡器实现,它使用标准路由协议。
在本指南中,我们将演示如何以层 2 (L2) 模式部署 MetalLB。
21.1 为什么要使用 MetalLB #
MetalLB 是裸机 Kubernetes 集群中负载平衡的理想选择,原因如下:
与 Kubernetes 的原生集成:MetalLB 与 Kubernetes 无缝集成,使用熟悉的 Kubernetes 工具和实践即可轻松部署和管理。
裸机兼容性:与基于云的负载平衡器不同,MetalLB 专为本地部署而设计,在这些环境中,传统的负载平衡器可能无法使用或不可行。
支持多个协议:MetalLB 支持层 2 和 BGP(边界网关协议)模式,为不同的网络架构和需求提供了灵活性。
高可用性:通过在多个节点之间分配负载平衡职责,MetalLB 可确保服务的高可用性和可靠性。
可伸缩性:MetalLB 可以处理大规模部署,并随着 Kubernetes 集群的伸缩而伸缩,以满足不断增长的需求。
在层 2 模式下,一个节点负责向本地网络通告服务。从网络的角度来看,这看起来就像该机器的网络接口分配了多个IP地址。
层 2 模式的主要优势在于其通用性:它适用于任何以太网,无需特殊硬件,甚至不需要高级路由器。
21.2 K3s 上的 MetalLB(使用层 2) #
在本快速入门中,将使用层 2 模式。 这意味着我们不需要任何特殊的网络设备,只需要网络范围内三个空闲的IP地址。
21.3 先决条件 #
一个即将部署 MetalLB 的 K3s 集群。
Helm
网络范围内三个空闲的IP地址。在此示例中为
192.168.122.10-192.168.122.12
您必须确保这些 IP 地址未被分配。 在 DHCP 环境中,这些地址不得属于 DHCP 地址池,以避免双重分配。
21.4 部署 #
我们将使用作为 SUSE Edge 解决方案一部分发布的 MetalLB Helm chart:
helm install \
metallb oci://registry.suse.com/edge/charts/metallb \
--namespace metallb-system \
--create-namespace
while ! kubectl wait --for condition=ready -n metallb-system $(kubectl get\
pods -n metallb-system -l app.kubernetes.io/component=controller -o name)\
--timeout=10s; do
sleep 2
done21.5 配置 #
此时,安装已完成。现在是时候使用我们的示例值进行 配置 了:
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.122.10/32
- 192.168.122.11/32
- 192.168.122.12/32
EOFcat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: ip-pool-l2-adv
namespace: metallb-system
spec:
ipAddressPools:
- ip-pool
EOF现在,它已准备好可以使用。您可以为 L2 模式自定义许多内容,例如:
以及更多关于 BGP的内容。
21.5.1 Traefik 和 MetalLB #
Traefik 默认随 K3s 部署( 可以禁用 使用 --disable=traefik),并且默认作为 LoadBalancer 暴露(供 Klipper 使用)。然而,由于需要禁用 Klipper,用于 Ingress 的 Traefik 服务仍然是 LoadBalancer 类型。因此,在部署 MetalLB 时,第一个 IP 将自动分配给 Traefik Ingress。
# Before deploying MetalLB
kubectl get svc -n kube-system traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.43.44.113 <pending> 80:31093/TCP,443:32095/TCP 28s
# After deploying MetalLB
kubectl get svc -n kube-system traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.43.44.113 192.168.122.10 80:31093/TCP,443:32095/TCP 3m10s这将在流程的 稍后 (第 21.6.1 节 “使用 MetalLB 的 Ingress”) 阶段应用。
21.6 用法 #
让我们创建一个示例部署:
cat <<- EOF | kubectl apply -f -
---
apiVersion: v1
kind: Namespace
metadata:
name: hello-kubernetes
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: hello-kubernetes
namespace: hello-kubernetes
labels:
app.kubernetes.io/name: hello-kubernetes
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes
namespace: hello-kubernetes
labels:
app.kubernetes.io/name: hello-kubernetes
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: hello-kubernetes
template:
metadata:
labels:
app.kubernetes.io/name: hello-kubernetes
spec:
serviceAccountName: hello-kubernetes
containers:
- name: hello-kubernetes
image: "paulbouwer/hello-kubernetes:1.10"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
env:
- name: HANDLER_PATH_PREFIX
value: ""
- name: RENDER_PATH_PREFIX
value: ""
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: KUBERNETES_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KUBERNETES_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: CONTAINER_IMAGE
value: "paulbouwer/hello-kubernetes:1.10"
EOF最后是服务:
cat <<- EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes
namespace: hello-kubernetes
labels:
app.kubernetes.io/name: hello-kubernetes
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: hello-kubernetes
EOF让我们看看它的实际运行效果:
kubectl get svc -n hello-kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes LoadBalancer 10.43.127.75 192.168.122.11 80:31461/TCP 8s
curl http://192.168.122.11
<!DOCTYPE html>
<html>
<head>
<title>Hello Kubernetes!</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300" >
</head>
<body>
<div class="main">
<img src="/images/kubernetes.png"/>
<div class="content">
<div id="message">
Hello world!
</div>
<div id="info">
<table>
<tr>
<th>namespace:</th>
<td>hello-kubernetes</td>
</tr>
<tr>
<th>pod:</th>
<td>hello-kubernetes-7c8575c848-2c6ps</td>
</tr>
<tr>
<th>node:</th>
<td>allinone (Linux 5.14.21-150400.24.46-default)</td>
</tr>
</table>
</div>
<div id="footer">
paulbouwer/hello-kubernetes:1.10 (linux/amd64)
</div>
</div>
</div>
</body>
</html>21.6.1 使用 MetalLB 的 Ingress #
由于 Traefik 已经作为 Ingress 控制器运行,我们可以通过 Ingress 对象来暴露任何 HTTP/HTTPS 流量,例如:
IP=$(kubectl get svc -n kube-system traefik -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
cat <<- EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
namespace: hello-kubernetes
spec:
rules:
- host: hellok3s.${IP}.sslip.io
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: hello-kubernetes
port:
name: http
EOF然后:
curl http://hellok3s.${IP}.sslip.io
<!DOCTYPE html>
<html>
<head>
<title>Hello Kubernetes!</title>
<link rel="stylesheet" type="text/css" href="/css/main.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300" >
</head>
<body>
<div class="main">
<img src="/images/kubernetes.png"/>
<div class="content">
<div id="message">
Hello world!
</div>
<div id="info">
<table>
<tr>
<th>namespace:</th>
<td>hello-kubernetes</td>
</tr>
<tr>
<th>pod:</th>
<td>hello-kubernetes-7c8575c848-fvqm2</td>
</tr>
<tr>
<th>node:</th>
<td>allinone (Linux 5.14.21-150400.24.46-default)</td>
</tr>
</table>
</div>
<div id="footer">
paulbouwer/hello-kubernetes:1.10 (linux/amd64)
</div>
</div>
</div>
</body>
</html>验证 MetalLB 是否正常工作:
% arping hellok3s.${IP}.sslip.io
ARPING 192.168.64.210
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=0 time=1.169 msec
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=1 time=2.992 msec
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=2 time=2.884 msec在上面的示例中,流量流向如下:
hellok3s.${IP}.sslip.io被解析为实际 IP。然后流量由
metallb-speakerPod 处理。metallb-speaker将流量重定向到traefik控制器。最后,Traefik 将请求转发到
hello-kubernetes服务。
22 K3s 上的 MetalLB(使用层 3 模式) #
MetalLB 是一个用于裸机 Kubernetes 集群的负载均衡器实现,它使用标准路由协议。
在本指南中,我们将演示如何以第 3 层 (L3) BGP 模式部署 MetalLB。
22.1 为什么要使用 MetalLB #
MetalLB 是裸机 Kubernetes 集群中负载均衡的理想选择,原因如下:
与 Kubernetes 的原生集成:MetalLB 与 Kubernetes 无缝集成,使用户能够轻松地利用熟悉的 Kubernetes 工具和实践进行部署和管理。
裸机兼容性:与基于云的负载均衡器不同,MetalLB 专为无法使用或不适合使用传统负载均衡器的本地部署而设计。
支持多个协议:MetalLB 支持第 2 层和第 3 层 BGP(边界网关协议)模式,为不同的网络架构和需求提供了灵活性。
高可用性:通过在多个节点间分配负载平衡职责,MetalLB 可确保服务的高可用性和可靠性。
可伸缩性:MetalLB 可以处理大规模部署,并随 Kubernetes 集群一起扩展以满足不断增长的需求。
在第 2 层模式下,一个节点承担向本地网络通告服务的职责。从网络的角度来看,这看起来就像该机器的网络接口分配了多个 IP 地址。
第 2 层模式的主要优势在于其通用性:它适用于任何以太网,无需特殊硬件,甚至不需要花哨的路由器。
22.2 K3s 上的 MetalLB(使用 L3) #
在本快速入门中,使用了 L3 模式。 这意味着我们需要在网络范围内拥有具备 BGP 功能的相邻路由器。
22.3 先决条件 #
一个将要部署 MetalLB 的 K3s 集群。
网络中支持 BGP 协议的路由器。
网络范围内用于该服务的空闲 IP 地址。在此示例中\n
192.168.10.100
您必须确保此 IP 地址未被分配。 在 DHCP 环境中,此地址不得属于 DHCP 地址池,以避免双重分配。
22.4 通告服务 IP 地址的配置 #
开箱即用,BGP 会将服务 IP 地址通告给所有已配置的对等体。这些通常为路由器的对等体将接收每个带有 32 位网络掩码的服务 IP 地址的路由。在此示例中,我们将使用基于 FRR 的路由器,它与我们的集群位于同一网络上。然后,我们将使用 MetalLB 的 BGP 功能向该基于 FRR 的路由器通告服务。
22.5 部署 #
我们将使用作为 SUSE Edge 解决方案一部分发布的 MetalLB Helm chart:
helm install \
metallb oci://registry.suse.com/edge/charts/metallb \
--namespace metallb-system \
--create-namespace
while ! kubectl wait --for condition=ready -n metallb-system $(kubectl get\
pods -n metallb-system -l app.kubernetes.io/component=controller -o name)\
--timeout=10s; do
sleep 2
done22.6 配置 #
此时,安装已完成。创建一个
IPAddressPool:
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: bgp-pool
namespace: metallb-system
labels:
app: httpd
spec:
addresses:
- 192.168.10.100/32
autoAssign: true
avoidBuggyIPs: false
serviceAllocation:
namespaces:
- metallb-system
priority: 100
serviceSelectors:
- matchExpressions:
- key: serviceType
operator: In
values:
- httpd
EOF配置一个
BGPPeer。
FRR 路由器的 ASN 为 1000,而我们的 BGPPeer 将为 1001。我们还可以看到 FRR 路由器的 IP 地址为 192.168.3.140。
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
namespace: metallb-system
name: mypeertest
spec:
peerAddress: 192.168.3.140
peerASN: 1000
myASN: 1001
routerID: 4.4.4.4
EOF创建 BGPAdvertisement (L3):
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: bgpadvertisement-test
namespace: metallb-system
spec:
ipAddressPools:
- bgp-pool
EOF22.7 用法 #
创建一个带有服务的示例应用程序。在此情况下,该服务的
IPAddressPool中的 IP 地址为192.168.10.100。
cat <<- EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
namespace: metallb-system
labels:
app: httpd
spec:
replicas: 3
selector:
matchLabels:
pod-label: httpd
template:
metadata:
labels:
pod-label: httpd
spec:
containers:
- name: httpdcontainer
image: image: docker.io/library/httpd:2.4
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: http-service
namespace: metallb-system
labels:
serviceType: httpd
spec:
selector:
pod-label: httpd
type: LoadBalancer
ports:
- protocol: TCP
port: 8080
name: 8080-tcp
targetPort: 80
EOF若要验证,请登录 FRR 路由器以查看通过 BGP 通告创建的路由。
42178089cba5# show ip bgp all
For address family: IPv4 Unicast
BGP table version is 3, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 1000
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
* i172.16.0.0/24 1.1.1.1 0 100 0 i
*> 0.0.0.0 0 32768 i
* i172.17.0.0/24 3.3.3.3 0 100 0 i
*> 0.0.0.0 0 32768 i
*= 192.168.10.100/32
192.168.3.162 0 1001 i
*= 192.168.3.163 0 1001 i
*> 192.168.3.161 0 1001 i
Displayed 3 routes and 7 total paths
kubectl get svc -n hello-kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes LoadBalancer 10.43.127.75 192.168.122.11 80:31461/TCP 8s如果此路由器是您网络的默认网关,您可以从该网络上的主机运行
curl命令,以验证它们是否可以访问 httpd 示例应用程序。
# curl http://192.168.10.100:8080
<html><body><h1>It works!</h1></body></html>
#23 K3s 上的 MetalLB(使用 FRR-K8s 模式) #
MetalLB 是一种用于裸机 Kubernetes 集群的负载均衡器实现,它使用标准路由协议。
在本指南中,我们将演示如何在第3层 FRR-K8s BGP 模式下部署 MetalLB。
23.1 K3s 上的 MetalLB(使用 FRR-K8s) #
在本快速入门中,使用了 FRR-K8s 模式。
23.2 先决条件 #
FRR-K8s 的所有先决条件与 第 22 章 “K3s 上的 MetalLB(使用层 3 模式)” 相同,除了需要一个空闲的 IP 地址。
注意此处的示例不包含服务设置,因此不需要 IP 地址。
一个即将部署 MetalLB 的 K3s 集群。
网络中支持 BGP 协议的路由器。
23.3 接收传入路由的配置 #
开箱即用的 MetalLB BGP 会向所有已配置的 BGP 对等体通告服务 IP 地址。这些对等体通常为路由器,会接收到每个服务 IP 地址及其 32 位网络掩码对应的路由。当将 FRR-K8s 与 FRRConfiguration CR 一起使用时,也可以从外部路由器接收路由。这些外部路由将显示在每个节点的路由表中。这样做有多种好处,但主要好处是消除了在外部网络发生变化时手动更新节点上 Linux 路由表的需要,特别是在希望避免通过默认网关发送流量的情况下。
23.4 部署 #
我们将使用作为 SUSE Edge 解决方案一部分发布的 MetalLB Helm chart。请注意,FRR-K8s 是 MetalLB 的子 chart,要启用它,请将 frrk8s.enabled 设置为 true。FRR-K8s 还需要命名空间上的一些提升权限。
kubectl create namespace metallb-system
kubectl label namespace metallb-system pod-security.kubernetes.io/enforce=privileged
kubectl label namespace metallb-system pod-security.kubernetes.io/audit=privileged
kubectl label namespace metallb-system pod-security.kubernetes.io/warn=privileged
helm install metallb \
oci://registry.suse.com/edge/charts/metallb \
--namespace metallb-system \
--set frrk8s.enabled=true --set frrk8s.external=false
while ! kubectl wait --for condition=ready -n metallb-system $(kubectl get\
pods -n metallb-system -l app.kubernetes.io/component=controller -o name)\
--timeout=10s; do
sleep 2
done验证您在 metallb-system 命名空间中是否有 4 个 pod,并且它们都运行正常:
k get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
metallb-controller-7fbfd8977d-m2q9t 1/1 Running 0 46s
metallb-metallb-frr-k8s-9w7wl 6/6 Running 0 46s
metallb-metallb-frr-k8s-webhook-server-5d9d67ffd6-8jqnc 1/1 Running 1 (6s ago) 46s
metallb-speaker-qx8bl 1/1 Running 0 46s至此,MetalLB 和 FRR-K8s 的安装已完成。
23.5 配置 #
为 FRR-K8s 创建一个
FRRConfiguration:cat <<-EOF | kubectl apply -f - apiVersion: frrk8s.metallb.io/v1beta1 kind: FRRConfiguration metadata: name: frrdemo namespace: metallb-system spec: bgp: routers: - asn: 64513 neighbors: - address: 192.168.20.154 asn: 64512 port: 179 toAdvertise: allowed: mode: all toReceive: allowed: mode: all EOF外部 BGP 路由器具有 ASN 64512,而我们的
BGPPeer将具有 64513。我们还可以看到外部 BGP 路由器的 IP 地址为 192.168.20.154。验证 FRRConfiguration 是否已部署:
k get FRRConfiguration -A NAMESPACE NAME AGE metallb-system frrdemo 4s注意上面的
toReceive设置将使您的集群接受所有传入路由。这在生产环境中可能不可取,因为根据您的外部路由器,它可能会导致您的节点路由表被填满。请参阅 https://github.com/metallb/frr-k8s/ 中的文档,以了解如何进一步过滤接收的路由。
对于 FRR-K8s,这些就是所需的全部设置。您的外部 BGP 路由器接收到的任何路由都将与您的集群共享,并且所有节点都将更新其路由表。
可以使用 第 22 章 “K3s 上的 MetalLB(使用层 3 模式)” 中描述的内容来测试此设置。为了结合这些设置,需要满足一些要求。
FRR-K8s 配置是在单独的集群上完成的。这是为了避免集群内部路由所必需的。
需要更改 ASN ID 和路由器 IP 地址以匹配这两种设置。
在部署了这两种设置后,可以观察到以下情况:
一旦在 第 22 章 “K3s 上的 MetalLB(使用层 3 模式)” 中描述的集群上应用了部署和 Service,该服务的路由将在外部 FRR 路由器上可见。
该路由将被添加到 FRR-K8s 集群上的所有节点。
在 FRR 路由的标准配置中,路由会与下一跳共享,并设置为 FRR 路由器的 IP 地址。若要实现不包含 FRR 路由器 IP 地址的下一跳,可以在 FRR 路由器上的 /etc/frr/frr.conf 文件中添加一行“neighbor BGPPG next-hop-unchanged”和一行“neighbor BGPPG as-override”。完成此设置后,FRR-K8s 集群上的节点将获得一条通往该服务的直接路由。
24 Kubernetes API 服务器前的 MetalLB #
本指南演示了如何使用 MetalLB 服务在具有三个控制平面节点的高可用集群上向外部暴露 RKE2/K3s API。
为实现此目的,将手动创建一个 LoadBalancer 类型的 Kubernetes 服务。然后将自动创建一个 EndpointSlices 对象,该对象使集群中所有控制平面节点的 IP 保持可用。
为了使 EndpointSlices 与集群中发生的事件(添加/删除节点或节点离线)持续同步,将部署 Endpoint Copier Operator (第 16 章 “端点复制器操作员”)。该 Operator 会监控默认 kubernetes EndpointSlices 中发生的事件,并自动更新受管的 EndpointSlices 以保持同步。
由于受管服务类型为 LoadBalancer,MetalLB 会为其分配一个静态 ExternalIP。此 ExternalIP 将用于与 API 服务器通信。
24.1 先决条件 #
用于部署 RKE2/K3s 的三台主机。
确保主机具有不同的主机名。
对于测试,这些可以是虚拟机。
网络中至少有 2 个可用 IP(一个用于 Traefik 入口控制器暴露的服务,另一个用于受管服务)。
Helm
24.2 安装 RKE2/K3s #
如果您不想使用全新的集群,而是想使用现有的集群,请跳过此步骤并继续下一步。
首先,必须在网络中预留一个空闲 IP,稍后将用于受管服务的 ExternalIP。
通过 SSH 连接到第一台主机,并以集群模式安装所需的发行版。
对于 RKE2:
# As a root user, create the /etc/rancher/rke2/config.yaml config file with the following content:
mkdir -p /etc/rancher/rke2/
cat <<EOF > /etc/rancher/rke2/config.yaml
# An example of the config.yaml file for a server node:
write-kubeconfig-mode: "0644"
ingress-controller: traefik
tls-san:
- "${VIP_SERVICE_IP}"
- "https://${VIP_SERVICE_IP}.sslip.io"
EOF
# Install RKE2
curl -sfL https://get.rke2.io | INSTALL_RKE2_EXEC="server" sh -
# Enable and start the RKE2 service with the configuration specified in the config.yaml file
systemctl enable rke2-server.service
systemctl start rke2-server.service
# Fetch the cluster token to be used later:
RKE2_TOKEN=$(tr -d '\n' < /var/lib/rancher/rke2/server/node-token)对于 K3s:
# Export the free IP mentioned above
export VIP_SERVICE_IP=<ip>
export INSTALL_K3S_SKIP_START=false
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --cluster-init \
--disable=servicelb --write-kubeconfig-mode=644 --tls-san=${VIP_SERVICE_IP} \
--tls-san=https://${VIP_SERVICE_IP}.sslip.io" K3S_TOKEN=foobar sh -确保在 --disable=servicelb 命令中提供了 k3s server 标志。
从现在起,应在本地机器上运行命令。
要从外部访问 API 服务器,将使用 RKE2/K3s 虚拟机的 IP。
# Replace <node-ip> with the actual IP of the machine
export NODE_IP=<node-ip>
export KUBE_DISTRIBUTION=<k3s/rke2>
scp ${NODE_IP}:/etc/rancher/${KUBE_DISTRIBUTION}/${KUBE_DISTRIBUTION}.yaml ~/.kube/config && sed \
-i '' "s/127.0.0.1/${NODE_IP}/g" ~/.kube/config && chmod 600 ~/.kube/config24.3 配置现有的集群 #
此步骤仅在您打算使用现有的 RKE2/K3s 集群时有效。
要使用现有集群,应修改 tls-san 标志。此外,对于 K3s,应禁用 servicelb LB。
要更改 RKE2 或 K3s 服务器的标志,您需要根据发行版修改集群中所有虚拟机上的 /etc/systemd/system/rke2.service 或 /etc/systemd/system/k3s.service 文件。
标志应插入到 ExecStart 中。例如:
对于 RKE2:
# Replace the <vip-service-ip> with the actual ip
ExecStart=/usr/local/bin/rke2 \
server \
'--write-kubeconfig-mode=644' \
'--tls-san=<vip-service-ip>' \
'--tls-san=https://<vip-service-ip>.sslip.io' \对于 K3s:
# Replace the <vip-service-ip> with the actual ip
ExecStart=/usr/local/bin/k3s \
server \
'--cluster-init' \
'--write-kubeconfig-mode=644' \
'--disable=servicelb' \
'--tls-san=<vip-service-ip>' \
'--tls-san=https://<vip-service-ip>.sslip.io' \然后应执行以下命令以加载新配置:
systemctl daemon-reload
systemctl restart ${KUBE_DISTRIBUTION}24.4 安装 MetalLB #
要部署 MetalLB,可以使用 MetalLB on K3s (第 21 章 “K3s 上的 MetalLB(使用层 2 模式)”) 指南。
*注意:*确保 VIP_SERVICE_IP IP 地址不会与集群中现有的 IPAddressPools 重叠。
创建一个仅用于受管服务的独立 IpAddressPool 和 L2Advertisement。
*注意:*下方的 IPAddressPool 将被分配给 LoadBalancer 名称空间中类型为 default 的服务。如果那里存在多个 LoadBalancer 服务,则可以配置额外的 ServiceSelectors 以明确匹配此 VIP 服务。
# Export the VIP_SERVICE_IP on the local machine
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: kubernetes-vip-ip-pool
namespace: metallb-system
spec:
addresses:
- ${VIP_SERVICE_IP}/32
serviceAllocation:
priority: 100
namespaces:
- default
EOFcat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: kubernetes-vip-l2-adv
namespace: metallb-system
spec:
ipAddressPools:
- kubernetes-vip-ip-pool
EOF24.5 安装 Endpoint Copier Operator #
helm install \
endpoint-copier-operator oci://registry.suse.com/edge/charts/endpoint-copier-operator \
--namespace endpoint-copier-operator \
--create-namespace上述命令将部署具有两个副本的 endpoint-copier-operator Operator 部署。其中一个将作为领导者,如果需要,另一个将接管领导者角色。
现在,应该部署 kubernetes-vip 服务,该服务将由 Operator 协调,并创建一个具有已配置端口和 IP 的 EndpointSlices。
对于 RKE2:
cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: kubernetes-vip
namespace: default
spec:
ports:
- name: rke2-api
port: 9345
protocol: TCP
targetPort: 9345
- name: k8s-api
port: 6443
protocol: TCP
targetPort: 6443
type: LoadBalancer
EOF对于 K3s:
cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: kubernetes-vip
namespace: default
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: https
port: 6443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: LoadBalancer
EOF验证 kubernetes-vip 服务是否具有正确的 IP 地址:
kubectl get service kubernetes-vip -n default \
-o=jsonpath='{.status.loadBalancer.ingress[0].ip}'确保 default 名称空间中的 kubernetes-vip-* 和 kubernetes EndpointSlices 资源指向相同的 IP。
kubectl get endpointslices | grep kubernetes如果一切正确,最后剩下的就是使用我们 VIP_SERVICE_IP 中的 Kubeconfig。
sed -i '' "s/${NODE_IP}/${VIP_SERVICE_IP}/g" ~/.kube/config从现在开始,所有的 kubectl 都将通过 kubernetes-vip 服务。
24.6 添加控制平面节点 #
为了监控整个过程,可以再打开两个终端选项卡。
第一个终端:
watch kubectl get nodes第二个终端:
watch kubectl get endpointslices现在在第二个和第三个节点上执行以下命令。
对于 RKE2:
# As a root user, create the /etc/rancher/rke2/config.yaml config file with the following content:
mkdir -p /etc/rancher/rke2/
cat <<EOF > /etc/rancher/rke2/config.yaml
# An example of the config.yaml file for an additional server node:
server: https://${VIP_SERVICE_IP}:9345
write-kubeconfig-mode: "0644"
ingress-controller: traefik
tls-san:
- "${VIP_SERVICE_IP}"
- "https://${VIP_SERVICE_IP}.sslip.io"
# The one from above
token: ${RKE2_TOKEN}
EOF
# Install RKE2
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="server" sh -
# Enable the RKE2 service with the configuration specified in the config.yaml file
systemctl enable --now rke2-server.service
# Fetch the cluster token to be used later:
RKE2_TOKEN=$(tr -d '\n' < /var/lib/rancher/rke2/server/node-token)对于 K3s:
# Export the VIP_SERVICE_IP in the VM
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>
export INSTALL_K3S_SKIP_START=false
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
--server https://${VIP_SERVICE_IP}:6443 --disable=servicelb \
--write-kubeconfig-mode=644" K3S_TOKEN=foobar sh -25 使用 Edge Image Builder 进行隔离的部署 #
25.1 简介 #
本指南将展示如何利用 Edge Image Builder(EIB) (第 8 章 “Edge Image Builder”) 在 SUSE Linux Micro 6.2 上完全隔离地部署 SUSE Edge 的多个组件。通过此操作,您将能够引导至由 EIB 创建的定制化、可启动 (CRB) 镜像,并在没有互联网连接且无需任何手动操作的情况下,在 RKE2 或 K3s 集群上部署指定的组件。对于希望将部署所需的所有工件预先构建到其操作系统镜像中,以便在引导时立即可用的客户,此配置非常理想。
我们将涵盖以下内容的隔离安装:
SUSE Private Registry
EIB 将解析并预先下载所提供的 Helm chart 和 Kubernetes 清单中引用的所有镜像。然而,其中一些可能试图在运行时拉取容器镜像并基于这些镜像创建 Kubernetes 资源。在这些情况下,如果我们想要建立一个完全隔离的环境,就必须在定义文件中手动指定必要的镜像。
25.2 先决条件 #
如果您正在阅读本指南,则假定您已经熟悉 EIB (第 8 章 “Edge Image Builder”)。如果不是,请遵循 快速入门指南 (第 2 章 “使用 Edge Image Builder 的独立集群”) 以更好地理解下面实践中展示的概念。
25.3 Libvirt 网络配置 #
为了演示隔离的部署,本指南将使用模拟的隔离 libvirt 网络完成,以下配置将针对该网络进行调整。对于您自己的部署,您可能需要修改下一步中将介绍的 host1.local.yaml 配置。
如果您想使用相同的 libvirt 网络配置,请跟随操作。如果不想,请跳至第 25.4 节 “基础目录配置”。
让我们创建一个具有 DHCP IP 地址范围 192.168.100.2/24 的隔离网络配置:
cat << EOF > isolatednetwork.xml
<network>
<name>isolatednetwork</name>
<bridge name='virbr1' stp='on' delay='0'/>
<ip address='192.168.100.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.100.2' end='192.168.100.254'/>
</dhcp>
</ip>
</network>
EOF现在,剩下的唯一事情就是创建网络并启动它:
virsh net-define isolatednetwork.xml
virsh net-start isolatednetwork25.4 基础目录配置 #
基础目录配置在所有不同组件中都是相同的,因此我们将在此处进行设置。
我们将首先创建必要的子目录:
export CONFIG_DIR=$HOME/config
mkdir -p $CONFIG_DIR/base-images
mkdir -p $CONFIG_DIR/network
mkdir -p $CONFIG_DIR/kubernetes/helm/values请务必将您计划使用的任何基础镜像添加到 base-images 目录中。本指南将重点介绍 此处 提供的自安装 ISO。
让我们复制下载的镜像:
cp SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.isoEIB 绝不会修改基础镜像输入。
让我们创建一个包含所需网络配置的文件:
cat << EOF > $CONFIG_DIR/network/host1.local.yaml
routes:
config:
- destination: 0.0.0.0/0
metric: 100
next-hop-address: 192.168.100.1
next-hop-interface: eth0
table-id: 254
- destination: 192.168.100.0/24
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: eth0
table-id: 254
dns-resolver:
config:
server:
- 192.168.100.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.100.50
prefix-length: 24
dhcp: false
enabled: true
ipv6:
enabled: false
EOF此配置确保在置备的系统上存在以下内容(使用指定的 MAC 地址):
具有静态 IP 地址的以太网接口
路由选择
DNS
主机名 (
host1.local)
生成的文件结构现在应如下所示:
├── kubernetes/
│ └── helm/
│ └── values/
├── base-images/
│ └── slemicro.iso
└── network/
└── host1.local.yaml25.5 基础定义文件 #
Edge Image Builder 使用 定义文件 来修改 SUSE Linux Micro 镜像。这些文件包含了大部分可配置选项。 其中许多选项会在不同的组件部分中重复出现,因此我们将在此处列出并解释它们。
我们将查看所有定义文件中都会出现的以下字段:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
embeddedArtifactRegistry:
images:
- ...image 部分是必需的,它指定了输入镜像、其架构和类型,以及输出镜像的名称。
operatingSystem 部分是可选的,包含用于通过 root/eib 用户名/密码在置备系统上启用登录的配置。
kubernetes 部分是可选的,它定义了 Kubernetes 的类型和版本。我们将使用 RKE2 发行版。如果需要 K3s,请使用 kubernetes.version: v1.35.4+k3s1。除非通过 kubernetes.nodes 字段明确配置,否则我们在本指南中引导的所有集群都将是单节点集群。
embeddedArtifactRegistry 部分将包含所有仅在运行时为特定组件引用和拉取的镜像。
25.6 Rancher 安装 #
Rancher 2.14.2 发布资产包含一个 rancher-images.txt 文件,其中列出了隔离的安装所需的所有镜像。
总共有超过 600 个容器镜像,这意味着生成的 CRB 镜像大约为 30GB。对于我们的 Rancher 安装,我们将把该列表精简为最小的工作配置。在此基础上,您可以添加部署可能需要的任何镜像。
我们将创建定义文件并包含精简后的镜像列表:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
manifests:
urls:
- https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.crds.yaml
helm:
charts:
- name: rancher
version: 2.14.2
repositoryName: rancher-prime
valuesFile: rancher-values.yaml
targetNamespace: cattle-system
createNamespace: true
installationNamespace: kube-system
- name: cert-manager
installationNamespace: kube-system
createNamespace: true
repositoryName: jetstack
targetNamespace: cert-manager
version: 1.20.1
repositories:
- name: jetstack
url: https://charts.jetstack.io
- name: rancher-prime
url: https://charts.rancher.com/server-charts/prime
embeddedArtifactRegistry:
images:
- name: registry.rancher.com/rancher/backup-restore-operator:v10.0.2
- name: registry.rancher.com/rancher/compliance-operator:v1.4.1
- name: registry.rancher.com/rancher/fleet-agent:v0.15.2
- name: registry.rancher.com/rancher/fleet:v0.15.2
- name: registry.rancher.com/rancher/hardened-addon-resizer:1.8.23-build20260413
- name: registry.rancher.com/rancher/hardened-calico:v3.31.5-build20260415
- name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.10.3-build20260414
- name: registry.rancher.com/rancher/hardened-cni-plugins:v1.9.1-build20260415
- name: registry.rancher.com/rancher/hardened-coredns:v1.14.2-build20260416
- name: registry.rancher.com/rancher/hardened-dns-node-cache:1.26.8-build20260416
- name: registry.rancher.com/rancher/hardened-etcd:v3.6.7-k3s1-build20260415
- name: registry.rancher.com/rancher/hardened-flannel:v0.28.4-build20260415
- name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.8.1-build20260413
- name: registry.rancher.com/rancher/hardened-kubernetes:v1.35.4-rke2r1-build20260416
- name: registry.rancher.com/rancher/hardened-multus-cni:v4.2.4-build20260310
- name: registry.rancher.com/rancher/hardened-multus-dynamic-networks-controller:v0.3.7-build20260310
- name: registry.rancher.com/rancher/hardened-multus-thick:v4.2.4-build20260310
- name: registry.rancher.com/rancher/hardened-traefik:v3.6.13-build20260416
- name: registry.rancher.com/rancher/hardened-whereabouts:v0.9.3-build20260408
- name: registry.rancher.com/rancher/k3s-upgrade:v1.35.4-k3s1
- name: registry.rancher.com/rancher/klipper-helm:v0.9.17-build20260422
- name: registry.rancher.com/rancher/klipper-lb:v0.4.16
- name: registry.rancher.com/rancher/kubectl:v1.35.2
- name: registry.rancher.com/rancher/kuberlr-kubectl:v7.0.3
- name: registry.rancher.com/rancher/local-path-provisioner:v0.0.35
- name: registry.rancher.com/rancher/machine:v0.15.0-rancher142
- name: registry.rancher.com/rancher/nginx-ingress-controller:v1.14.5-hardened2
- name: registry.rancher.com/rancher/prom-prometheus:v3.8.1
- name: registry.rancher.com/rancher/prometheus-federator:v6.0.0
- name: registry.rancher.com/rancher/pushprox:v0.1.10
- name: registry.rancher.com/rancher/rancher-agent:v2.14.2
- name: registry.rancher.com/rancher/rancher-csp-adapter:v9.0.0
- name: registry.rancher.com/rancher/rancher-webhook:v0.10.6
- name: registry.rancher.com/rancher/rancher:v2.14.2
- name: registry.rancher.com/rancher/remotedialer-proxy:v0.7.2
- name: registry.rancher.com/rancher/rke2-cloud-provider:v1.35.4-0.20260415195656-e51c0636351d-build20260415
- name: registry.rancher.com/rancher/rke2-runtime:v1.35.4-rke2r1
- name: registry.rancher.com/rancher/rke2-upgrade:v1.35.4-rke2r1
- name: registry.rancher.com/rancher/scc-operator:v0.4.1
- name: registry.rancher.com/rancher/security-scan:v0.9.1
- name: registry.rancher.com/rancher/shell:v0.1.24
- name: registry.rancher.com/rancher/supportability-review-app-frontend:v0.19.0
- name: registry.rancher.com/rancher/supportability-review-internal:latest
- name: registry.rancher.com/rancher/supportability-review-operator:v0.19.0
- name: registry.rancher.com/rancher/supportability-review:latest
- name: registry.rancher.com/rancher/system-agent-installer-k3s:v1.35.4-k3s1
- name: registry.rancher.com/rancher/system-agent-installer-rke2:v1.35.4-rke2r1
- name: registry.rancher.com/rancher/system-agent:v0.3.16-suc
- name: registry.rancher.com/rancher/system-upgrade-controller:v0.19.1
- name: registry.rancher.com/rancher/turtles:v0.26.2
- name: registry.rancher.com/rancher/ui-plugin-catalog:4.15.0
- name: registry.rancher.com/rancher/kubectl:v1.20.2
- name: registry.rancher.com/rancher/mirrored-ingress-nginx-kube-webhook-certgen:v1.6.7与包含 600 多个容器镜像的完整列表相比,此精简版本仅包含约 60 个镜像,这使得新的 CRB 镜像仅约 7GB。
我们还需要为 Rancher 创建一个 Helm values 文件:
cat << EOF > $CONFIG_DIR/kubernetes/helm/values/rancher-values.yaml
hostname: 192.168.100.50.sslip.io
replicas: 1
bootstrapPassword: "adminadminadmin"
systemDefaultRegistry: registry.rancher.com
useBundledSystemChart: true
EOF将 systemDefaultRegistry 设置为 registry.rancher.com 允许 Rancher 在启动时自动在 CRB 镜像内启动的嵌入式工件仓库中查找镜像。省略此字段可能会导致无法在节点上找到容器镜像。
让我们构建镜像:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yaml输出应该与以下内容相似:
Downloading file: dl-manifest-1.yaml 100% |██████████████████████████████████████████████████████████████████████████████| (583/583 kB, 12 MB/s)
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████| (56/56, 8 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% |███████████████████████████████████████████████████████████| (644/644 MB, 29 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% |█████████████████████████████████████████████████████████| (400/400 MB, 29 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% |███████████████████████████████████████████████████████████████████████████| (36/36 MB, 30 MB/s)
Downloading file: sha256sum-amd64.txt 100% |█████████████████████████████████████████████████████████████████████████████| (4.3/4.3 kB, 29 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso一旦配置了使用所构建镜像的节点,我们就可以验证 Rancher 的安装:
/var/lib/rancher/rke2/bin/kubectl get all -n cattle-system --kubeconfig /etc/rancher/rke2/rke2.yaml输出应该与以下内容相似,显示所有内容已成功部署:
NAME READY STATUS RESTARTS AGE
pod/helm-operation-6l6ld 0/2 Completed 0 107s
pod/helm-operation-8tk2v 0/2 Completed 0 2m2s
pod/helm-operation-blnrr 0/2 Completed 0 2m49s
pod/helm-operation-hdcmt 0/2 Completed 0 3m19s
pod/helm-operation-m74c7 0/2 Completed 0 97s
pod/helm-operation-qzzr4 0/2 Completed 0 2m30s
pod/helm-operation-s9jh5 0/2 Completed 0 3m
pod/helm-operation-tq7ts 0/2 Completed 0 2m41s
pod/rancher-99d599967-ftjkk 1/1 Running 0 4m15s
pod/rancher-webhook-79798674c5-6w28t 1/1 Running 0 2m27s
pod/system-upgrade-controller-56696956b-trq5c 1/1 Running 0 104s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/rancher ClusterIP 10.43.255.80 <none> 80/TCP,443/TCP 4m15s
service/rancher-webhook ClusterIP 10.43.7.238 <none> 443/TCP 2m27s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/rancher 1/1 1 1 4m15s
deployment.apps/rancher-webhook 1/1 1 1 2m27s
deployment.apps/system-upgrade-controller 1/1 1 1 104s
NAME DESIRED CURRENT READY AGE
replicaset.apps/rancher-99d599967 1 1 1 4m15s
replicaset.apps/rancher-webhook-79798674c5 1 1 1 2m27s
replicaset.apps/system-upgrade-controller-56696956b 1 1 1 104s当我们转到 https://192.168.100.50.sslip.io 并使用我们之前设置的 adminadminadmin 密码登录时,我们会看到 Rancher 仪表板:
25.7 SUSE Security 安装 #
与 Rancher 安装不同,SUSE Security 安装在 EIB 中不需要任何特殊处理。EIB 将自动为底层组件 NeuVector 所需的每个镜像进行隔离处理。
我们将创建定义文件:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: neuvector-crd
version: 109.0.2+up2.10.2
repositoryName: rancher-charts
targetNamespace: neuvector
createNamespace: true
installationNamespace: kube-system
valuesFile: neuvector-values.yaml
- name: neuvector
version: 109.0.2+up2.10.2
repositoryName: rancher-charts
targetNamespace: neuvector
createNamespace: true
installationNamespace: kube-system
valuesFile: neuvector-values.yaml
repositories:
- name: rancher-charts
url: https://charts.rancher.io/我们还将为 NeuVector 创建一个 Helm values 文件:
cat << EOF > $CONFIG_DIR/kubernetes/helm/values/neuvector-values.yaml
controller:
replicas: 1
manager:
enabled: false
cve:
scanner:
enabled: false
replicas: 1
k3s:
enabled: true
crdwebhook:
enabled: false
EOF让我们构建镜像:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yaml输出应该与以下内容相似:
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 4 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████| (5/5, 13 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
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso一旦配置了使用构建镜像的节点,我们就可以验证 SUSE Security 安装:
/var/lib/rancher/rke2/bin/kubectl get all -n neuvector --kubeconfig /etc/rancher/rke2/rke2.yaml输出应该与以下内容相似,显示所有内容已成功部署:
NAME READY STATUS RESTARTS AGE
pod/neuvector-cert-upgrader-job-bxbnz 0/1 Completed 0 3m39s
pod/neuvector-controller-pod-7d854bfdc7-nhxjf 1/1 Running 0 3m44s
pod/neuvector-enforcer-pod-ct8jm 1/1 Running 0 3m44s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/neuvector-svc-admission-webhook ClusterIP 10.43.234.241 <none> 443/TCP 3m44s
service/neuvector-svc-controller ClusterIP None <none> 18300/TCP,18301/TCP,18301/UDP 3m44s
service/neuvector-svc-crd-webhook ClusterIP 10.43.50.190 <none> 443/TCP 3m44s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/neuvector-enforcer-pod 1 1 1 1 1 <none> 3m44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/neuvector-controller-pod 1/1 1 1 3m44s
NAME DESIRED CURRENT READY AGE
replicaset.apps/neuvector-controller-pod-7d854bfdc7 1 1 1 3m44s
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/neuvector-cert-upgrader-pod 0 0 1 1 * <none> True 0 <none> 3m44s
cronjob.batch/neuvector-updater-pod 0 0 * * * <none> False 0 <none> 3m44s
NAME STATUS COMPLETIONS DURATION AGE
job.batch/neuvector-cert-upgrader-job Complete 1/1 7s 3m39s25.8 SUSE Storage 安装 #
Longhorn 的 官方文档 包含一个 longhorn-images.txt 文件,其中列出了隔离安装所需的所有镜像。
我们将在定义文件中包含来自 Rancher 容器镜像仓库的镜像对应项。
让我们创建它:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
packages:
sccRegistrationCode: [reg-code]
packageList:
- open-iscsi
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: suse-storage
releaseName: longhorn
repositoryName: rancher-application-collection
targetNamespace: longhorn-system
createNamespace: true
version: 1.11.2
repositories:
- name: rancher-application-collection
url: oci://dp.apps.rancher.io/charts
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
registries:
- uri: dp.apps.rancher.io
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.11.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-14.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.1.0-6.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.5.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.18.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.16.0-13.2
- name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.11.2-4.1
- name: dp.apps.rancher.io/containers/longhorn-engine:1.11.2-4.2
- name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.11.2-4.3
- name: dp.apps.rancher.io/containers/longhorn-manager:1.11.2-4.2
- name: dp.apps.rancher.io/containers/longhorn-share-manager:1.11.2-4.1
- name: dp.apps.rancher.io/containers/longhorn-ui:1.11.2-4.1
- name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.84-9.4您会注意到定义文件列出了 open-iscsi 软件包。这是必要的,因为 Longhorn 依赖于在不同节点上运行的 iscsiadm 守护程序,以便为 Kubernetes 提供持久卷。
让我们构建镜像:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yaml输出应该与以下内容相似:
Setting up Podman API listener...
Pulling selected Helm charts... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 20956 it/s)
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, 108 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (367/367 MB, 104 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (34/34 MB, 108 MB/s)
Downloading file: sha256sum-amd64.txt 100% (3.9/3.9 kB, 7.5 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso一旦配置了使用构建镜像的节点,我们就可以验证 Longhorn 安装:
/var/lib/rancher/rke2/bin/kubectl get all -n longhorn-system --kubeconfig /etc/rancher/rke2/rke2.yaml输出应该与以下内容相似,显示所有内容已成功部署:
NAME READY STATUS RESTARTS AGE
pod/csi-attacher-787fd9c6c8-sf42d 1/1 Running 0 2m28s
pod/csi-attacher-787fd9c6c8-tb82p 1/1 Running 0 2m28s
pod/csi-attacher-787fd9c6c8-zhc6s 1/1 Running 0 2m28s
pod/csi-provisioner-74486b95c6-b2v9s 1/1 Running 0 2m28s
pod/csi-provisioner-74486b95c6-hwllt 1/1 Running 0 2m28s
pod/csi-provisioner-74486b95c6-mlrpk 1/1 Running 0 2m28s
pod/csi-resizer-859d4557fd-t54zk 1/1 Running 0 2m28s
pod/csi-resizer-859d4557fd-vdt5d 1/1 Running 0 2m28s
pod/csi-resizer-859d4557fd-x9kh4 1/1 Running 0 2m28s
pod/csi-snapshotter-6f69c6c8cc-r62gr 1/1 Running 0 2m28s
pod/csi-snapshotter-6f69c6c8cc-vrwjn 1/1 Running 0 2m28s
pod/csi-snapshotter-6f69c6c8cc-z65nb 1/1 Running 0 2m28s
pod/engine-image-ei-4623b511-9vhkb 1/1 Running 0 3m13s
pod/instance-manager-6f95fd57d4a4cd0459e469d75a300552 1/1 Running 0 2m43s
pod/longhorn-csi-plugin-gx98x 3/3 Running 0 2m28s
pod/longhorn-driver-deployer-55f9c88499-fbm6q 1/1 Running 0 3m28s
pod/longhorn-manager-dpdp7 2/2 Running 0 3m28s
pod/longhorn-ui-59c85fcf94-gg5hq 1/1 Running 0 3m28s
pod/longhorn-ui-59c85fcf94-s49jc 1/1 Running 0 3m28s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/longhorn-admission-webhook ClusterIP 10.43.77.89 <none> 9502/TCP 3m28s
service/longhorn-backend ClusterIP 10.43.56.17 <none> 9500/TCP 3m28s
service/longhorn-conversion-webhook ClusterIP 10.43.54.73 <none> 9501/TCP 3m28s
service/longhorn-frontend ClusterIP 10.43.22.82 <none> 80/TCP 3m28s
service/longhorn-recovery-backend ClusterIP 10.43.45.143 <none> 9503/TCP 3m28s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/engine-image-ei-4623b511 1 1 1 1 1 <none> 3m13s
daemonset.apps/longhorn-csi-plugin 1 1 1 1 1 <none> 2m28s
daemonset.apps/longhorn-manager 1 1 1 1 1 <none> 3m28s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-attacher 3/3 3 3 2m28s
deployment.apps/csi-provisioner 3/3 3 3 2m28s
deployment.apps/csi-resizer 3/3 3 3 2m28s
deployment.apps/csi-snapshotter 3/3 3 3 2m28s
deployment.apps/longhorn-driver-deployer 1/1 1 1 3m28s
deployment.apps/longhorn-ui 2/2 2 2 3m28s
NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-attacher-787fd9c6c8 3 3 3 2m28s
replicaset.apps/csi-provisioner-74486b95c6 3 3 3 2m28s
replicaset.apps/csi-resizer-859d4557fd 3 3 3 2m28s
replicaset.apps/csi-snapshotter-6f69c6c8cc 3 3 3 2m28s
replicaset.apps/longhorn-driver-deployer-55f9c88499 1 1 1 3m28s
replicaset.apps/longhorn-ui-59c85fcf94 2 2 2 3m28s25.9 KubeVirt 和 CDI 安装 #
KubeVirt 和 CDI 的 Helm chart 仅安装它们各自的 operator。 部署其余系统取决于 operator,这意味着我们必须在定义文件中包含所有必要的容器镜像。让我们创建它:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: kubevirt
repositoryName: suse-edge
version: 306.0.2+up0.7.0
targetNamespace: kubevirt-system
createNamespace: true
installationNamespace: kube-system
- name: cdi
repositoryName: suse-edge
version: 306.0.2+up0.7.0
targetNamespace: cdi-system
createNamespace: true
installationNamespace: kube-system
repositories:
- name: suse-edge
url: oci://registry.suse.com/edge/charts
embeddedArtifactRegistry:
images:
- name: registry.suse.com/suse/sles/15.7/cdi-apiserver:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/cdi-controller:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/cdi-operator:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/cdi-uploadproxy:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/virt-api:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-controller:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-handler:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-launcher:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-operator:1.7.0-150700.3.16.2让我们构建镜像:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yaml输出应该与以下内容相似:
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 48 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 4 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
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso一旦配置了使用构建镜像的节点,我们就可以验证 KubeVirt 和 CDI 的安装。
验证 KubeVirt:
/var/lib/rancher/rke2/bin/kubectl get all -n kubevirt-system --kubeconfig /etc/rancher/rke2/rke2.yaml输出应该与以下内容相似,显示所有内容已成功部署:
NAME READY STATUS RESTARTS AGE
pod/virt-api-59cb997648-mmt67 1/1 Running 0 2m34s
pod/virt-controller-69786b785-7cc96 1/1 Running 0 2m8s
pod/virt-controller-69786b785-wq2dz 1/1 Running 0 2m8s
pod/virt-handler-2l4dm 1/1 Running 0 2m8s
pod/virt-operator-7c444cff46-nps4l 1/1 Running 0 3m1s
pod/virt-operator-7c444cff46-r25xq 1/1 Running 0 3m1s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubevirt-operator-webhook ClusterIP 10.43.167.109 <none> 443/TCP 2m36s
service/kubevirt-prometheus-metrics ClusterIP None <none> 443/TCP 2m36s
service/virt-api ClusterIP 10.43.18.202 <none> 443/TCP 2m36s
service/virt-exportproxy ClusterIP 10.43.142.188 <none> 443/TCP 2m36s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/virt-handler 1 1 1 1 1 kubernetes.io/os=linux 2m8s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/virt-api 1/1 1 1 2m34s
deployment.apps/virt-controller 2/2 2 2 2m8s
deployment.apps/virt-operator 2/2 2 2 3m1s
NAME DESIRED CURRENT READY AGE
replicaset.apps/virt-api-59cb997648 1 1 1 2m34s
replicaset.apps/virt-controller-69786b785 2 2 2 2m8s
replicaset.apps/virt-operator-7c444cff46 2 2 2 3m1s
NAME AGE PHASE
kubevirt.kubevirt.io/kubevirt 3m1s Deployed验证 CDI:
/var/lib/rancher/rke2/bin/kubectl get all -n cdi-system --kubeconfig /etc/rancher/rke2/rke2.yaml输出应该与以下内容相似,显示所有内容已成功部署:
NAME READY STATUS RESTARTS AGE
pod/cdi-apiserver-5598c9bf47-pqfxw 1/1 Running 0 3m44s
pod/cdi-deployment-7cbc5db7f8-g46z7 1/1 Running 0 3m44s
pod/cdi-operator-777c865745-2qcnj 1/1 Running 0 3m48s
pod/cdi-uploadproxy-646f4cd7f7-fzkv7 1/1 Running 0 3m44s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cdi-api ClusterIP 10.43.2.224 <none> 443/TCP 3m44s
service/cdi-prometheus-metrics ClusterIP 10.43.237.13 <none> 8080/TCP 3m44s
service/cdi-uploadproxy ClusterIP 10.43.114.91 <none> 443/TCP 3m44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/cdi-apiserver 1/1 1 1 3m44s
deployment.apps/cdi-deployment 1/1 1 1 3m44s
deployment.apps/cdi-operator 1/1 1 1 3m48s
deployment.apps/cdi-uploadproxy 1/1 1 1 3m44s
NAME DESIRED CURRENT READY AGE
replicaset.apps/cdi-apiserver-5598c9bf47 1 1 1 3m44s
replicaset.apps/cdi-deployment-7cbc5db7f8 1 1 1 3m44s
replicaset.apps/cdi-operator-777c865745 1 1 1 3m48s
replicaset.apps/cdi-uploadproxy-646f4cd7f7 1 1 1 3m44s25.10 SUSE Private Registry 安装 #
为了在隔离的部署中包含 SUSE Private Registry,我们必须更新定义文件,以包含所需的 helm chart 以及新镜像的嵌入式工件。
让我们更新定义文件:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: metallb
version: 306.0.2+up0.15.3
targetNamespace: metallb-system
createNamespace: true
repositoryName: suse-edge-charts
installationNamespace: kube-system
- name: suse-storage
releaseName: longhorn
repositoryName: rancher-application-collection
targetNamespace: longhorn-system
createNamespace: true
version: 1.11.2
- name: private-registry-helm
createNamespace: true
installationNamespace: kube-system
repositoryName: privateregistry
targetNamespace: suse-private-registry
valuesFile: privateregistry.yaml
version: 1.1.1
repositories:
- name: privateregistry
authentication:
username: ${PRIVATE_REGISTRY_USERNAME}
password: ${PRIVATE_REGISTRY_PASSWORD}
plainHTTP: false
skipTLSVerify: false
url: oci://registry.suse.com/private-registry
- name: rancher-application-collection
url: oci://dp.apps.rancher.io/charts
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
registries:
- uri: registry.suse.com
authentication:
username: ${PRIVATE_REGISTRY_USERNAME}
password: ${PRIVATE_REGISTRY_PASSWORD}
- uri: dp.apps.rancher.io
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
images:
- name: registry.suse.com/private-registry/harbor-core:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-jobservice:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-portal:1.1.1-1.20
- name: registry.suse.com/private-registry/harbor-registry:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-registryctl:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-trivy-adapter:1.1.1-1.24您将需要某些凭据,可以通过遵循官方 SUSE Private Registry 文档 来获取这些凭据。
您还必须修改 ${PRIVATE_REGISTRY_USERNAME} 和 ${PRIVATE_REGISTRY_PASSWORD} 变量。请确保列出包含您所需组件版本的镜像。
现在,我们需要添加所需的 Kubernetes 清单,以正确配置 SUSE Private Registry。
您需要在以下文件中修改 ${MGMT_CLUSTER_REGISTRY_IP},为 SUSE Private Registry 保留一个静态 IP:
kubernetes/manifests/metallb-registry.yamlapiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: private-registry namespace: metallb-system spec: ipAddressPools: - private-registry-pool --- apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: private-registry-pool namespace: metallb-system spec: addresses: - ${MGMT_CLUSTER_REGISTRY_IP}/32 serviceAllocation: namespaces: - suse-private-registrykubernetes/helm/values/privateregistry.yamlcore: secretName: suse-registry-tls expose: tls: certSource: secret enabled: true secret: secretName: suse-registry-tls type: loadBalancer externalURL: https://${MGMT_CLUSTER_REGISTRY_IP} persistence: persistentVolumeClaim: registry: size: 20Gi
最后,必须使用以下内容创建 kubernetes/manifests/suse-private-registry-creds.yaml:
apiVersion: v1
kind: Secret
metadata:
name: suse-registry
namespace: suse-private-registry
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ${DOCKER_CONFIG_JSON_BASE64}
---
apiVersion: v1
kind: Secret
metadata:
name: suse-registry-tls
namespace: suse-private-registry
type: kubernetes.io/tls
data:
tls.crt: ${TLS_CRT_BASE64}
tls.key: ${TLS_KEY_BASE64}要为 ${DOCKER_CONFIG_JSON_BASE64} 正确配置 docker config json (base64),请运行:
# ${DOCKER_CONFIG_JSON_BASE64} CONTENT
echo -n '{"auths": {"<MGMT_CLUSTER_REGISTRY_IP>": {"username": "<USERNAME>", "password": "<PASSWORD>", "auth": "<AUTH>"}}}' | base64其中 IP 与之前配置的 ${MGMT_CLUSTER_REGISTRY_IP} 相同,username、password 和 auth 可以从 SUSE Private Registry 官方文档 中获取。
要为 ${TLS_CRT_BASE64} 和 ${TLS_KEY_BASE64} 生成 base64 编码的 TLS 证书和密钥(tls.crt 和 tls.key),您可以运行以下命令来创建自己的证书和密钥:
# Generate a self-signed certificate and key
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
# Convert them to base64 for the suse-private-registry-creds.yaml file
cat cert.pem | base64 -w 0
cat key.pem | base64 -w 0验证 SUSE Private Registry:
/var/lib/rancher/rke2/bin/kubectl get pods -n suse-private-registry --kubeconfig /etc/rancher/rke2/rke2.yaml输出应该与以下内容相似,显示所有内容已成功部署:
NAME READY STATUS RESTARTS AGE
pod/private-registry-harbor-core-588fd4876f-8tqnv 1/1 Running 0 4m30s
pod/private-registry-harbor-database-0 1/1 Running 0 4m30s
pod/private-registry-harbor-jobservice-7658f97fbc-4vq6n 1/1 Running 0 4m30s
pod/private-registry-harbor-portal-5455ccc4bc-jpmt5 1/1 Running 0 4m30s
pod/private-registry-harbor-redis-0 1/1 Running 0 4m30s
pod/private-registry-harbor-registry-5648b9d89-wdswz 2/2 Running 0 4m30s
pod/private-registry-harbor-trivy-0 1/1 Running 0 4m30s25.11 查错 #
如果您在构建镜像时遇到任何问题,或者希望进一步测试和调试该过程,请参阅 上游文档。
26 使用 Kiwi 构建更新的 SUSE Linux Micro 镜像 #
本节介绍了如何生成更新的 SUSE Linux Micro 镜像,以供 Edge Image Builder、Cluster API (CAPI) + Metal3 使用,或直接将磁盘镜像写入块设备。此过程在以下情况下非常有用:需要在初始系统引导镜像中包含最新补丁(以最大限度地减少安装后的补丁传输),或者在使用 CAPI 的场景中,首选使用新镜像重新安装操作系统,而不是就地升级主机。
此过程利用 Kiwi 来运行镜像构建。SUSE Edge 附带了一个容器化版本,通过内置的辅助工具简化了整个过程,允许指定所需的 控制文件。控制文件定义了所需的输出镜像类型,常见类型如下:
“Base” - 包含精简软件包集(包含 podman)的 SUSE Linux Micro 磁盘镜像。
“Base-SelfInstall” - 基于上述“Base”的 SelfInstall 镜像。
“Base-RT” - 与上述“Base”相同,但改用实时 (rt) 内核。
“Base-RT-SelfInstall” - 基于上述“Base-RT”的 SelfInstall 镜像
“Default” - 基于上述“Base”的 SUSE Linux Micro 磁盘镜像,但包含更多工具,包括虚拟化堆栈、Cockpit 和 salt-minion。
“Default-SelfInstall” - 基于上述“Default”的 SelfInstall 镜像
有关更多详细信息,请参阅 SUSE Linux Micro 6.2 文档。
此过程适用于 AMD64/Intel 64 和 AArch64 架构,但必须使用与所构建镜像架构相同的构建主机。换句话说,要构建 AArch64 镜像,需要使用 AArch64 构建主机,反之亦然(对于 AMD64/Intel 64),目前不支持交叉构建。
26.1 先决条件 #
Kiwi 镜像构建器需要满足以下条件:
一台与所构建镜像架构相同的 SUSE Linux Micro 6.2 主机(“构建系统”)。
构建系统需要已通过
SUSEConnect注册(该注册用于从 SUSE 储存库拉取最新的软件包)可用于拉取所需软件包的互联网连接。如果通过代理连接,则需要预先配置构建主机。
构建主机上需要禁用 SELinux(因为 SELinux 标记是在容器中进行的,它可能会与主机策略冲突)
至少 10GB 的可用磁盘空间,以容纳容器镜像、构建根目录以及生成的输出镜像。
26.2 入门 #
由于某些限制,目前需要禁用 SELinux。连接到 SUSE Linux Micro 6.2 镜像构建主机并确保已禁用 SELinux:
# setenforce 0创建一个与 Kiwi 构建容器共享的输出目录,以保存生成的镜像:
# mkdir ~/output从 SUSE 注册中心拉取最新的 Kiwi 构建器镜像:
# podman pull registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1
(...)26.3 构建默认镜像 #
如果在运行容器镜像时未提供任何参数,这是 Kiwi 镜像容器的默认行为。以下命令运行 podman,并将两个目录映射到容器:
来自底层主机的
/etc/zypp/repos.dSUSE Linux Micro 软件包储存库目录。上面创建的输出
~/output目录。
Kiwi 镜像容器需要按如下方式运行 build-image 辅助脚本:
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
-it registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 build-image
(...)如果您是第一次运行此脚本,预计它会在启动后不久 失败,并显示“错误:早期循环设备测试失败,请重试容器运行。”,这是底层主机系统上创建的循环设备在容器镜像内无法立即识别的症状。只需重新运行该命令即可顺利进行。
几分钟后,可以在本地输出目录中找到这些镜像:
(...)
INFO: Image build successful, generated images are available in the 'output' directory.
# ls -1 output/
SLE-Micro.x86_64-6.2.changes
SLE-Micro.x86_64-6.2.packages
SLE-Micro.x86_64-6.2.raw
SLE-Micro.x86_64-6.2.verified
build
kiwi.result
kiwi.result.json26.4 使用其他控制文件构建镜像 #
为了构建不同的控制文件,使用了 Kiwi 容器镜像辅助脚本中的“-p”命令选项。例如,要构建“Default-SelfInstall”ISO 映像:
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
-it registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 build-image -p Default-SelfInstall
(...)为避免数据丢失,如果 output 目录中有镜像,Kiwi 将拒绝运行。在继续 rm -f output/* 之前,必须删除输出目录的内容。
或者,要使用实时内核(“kernel-rt”)构建 SelfInstall ISO 映像:
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
-it registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 build-image -p Base-RT-SelfInstall
(...)26.5 构建具有大扇区大小的镜像 #
某些硬件需要具有大扇区大小的镜像,即 4096 bytes 而不是标准的 512 字节。容器化 Kiwi 构建器支持通过指定“-b”参数来生成具有大块大小的镜像。例如,要构建具有大扇区大小的“Default-SelfInstall”镜像:
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
-it registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 build-image -p Default-SelfInstall -b
(...)26.6 使用自定义 Kiwi 镜像定义文件 #
对于高级用例,可以使用自定义 Kiwi 镜像定义文件 (SL-Micro.kiwi) 以及任何必要的构建后脚本。这需要覆盖由 SUSE Edge 团队预打包的默认定义。
创建一个新的目录,并将其映射到辅助脚本正在查找的容器镜像中 (/micro-sdk/defs):
# mkdir ~/mydefs/
# cp /path/to/SL-Micro.kiwi ~/mydefs/
# cp /path/to/config.sh ~/mydefs/
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output -v ~/mydefs/:/micro-sdk/defs/ \
-it registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 build-image
(...)这仅适用于高级用例,并可能导致可支持性问题。请联系您的 SUSE 代表以获取进一步的建议和指导。
要获取容器中包含的默认 Kiwi 镜像定义文件,可以使用以下命令:
$ podman create --name kiwi-builder registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1
$ podman cp kiwi-builder:/micro-sdk/defs/SL-Micro.kiwi .
$ podman cp kiwi-builder:/micro-sdk/defs/SL-Micro.kiwi.4096 .
$ podman rm kiwi-builder
$ ls ./SL-Micro.*
(...)第 IV 部分 提示和技巧 #
Edge 组件的提示和技巧
- 27 Edge Image Builder
如果您处于非 Linux 环境中并按照这些说明构建镜像,那么您很可能正在通过虚拟机运行
Podman。默认情况下,此虚拟机配置为仅分配少量系统资源,这可能会导致Edge Image Builder在资源密集型操作(例如 RPM 解析过程)期间出现不稳定。您需要调整 podman 机器的资源,可以通过 Podman Desktop(设置齿轮 → podman 机器编辑图标)或直接通过podman-machine-set命令进行调整。- 28 Elemental
使用 RKE2 或 K3s 时,我们需要从管理集群暴露服务(在此上下文中为 Rancher),因为它们默认不会被暴露。 在 RKE2 和 k3s 中都有一个 Traefik Ingress 控制器。 当前工作流程建议使用 MetalLB 来发布服务(通过 L2 或 BGP 广播),并使用相应的 Ingress 控制器通过
HelmChartConfig创建 Ingress,因为创建新的 Ingress 对象会覆盖现有设置。
27 Edge Image Builder #
27.1 常用 #
如果您处于非 Linux 环境中并按照这些说明构建镜像,那么您很可能正在通过虚拟机运行
Podman。默认情况下,此虚拟机配置为仅分配少量系统资源,这可能会导致Edge Image Builder在资源密集型操作(例如 RPM 解析过程)期间出现不稳定。您需要调整 podman 机器的资源,可以通过 Podman Desktop(设置齿轮 → podman 机器编辑图标)或直接通过podman-machine-set命令进行调整。目前,
Edge Image Builder无法在跨架构设置中构建镜像,即您必须在以下系统上运行它:AArch64 系统(例如 Apple Silicon)以构建 SL Micro
aarch64镜像AMD64/Intel 64 系统以构建 SL Micro
x86_64镜像。
27.2 SUSE Linux Micro #
可以使用相应的
/etc/modprobe.d/module.conf文件在启动时加载内核模块。使用 Edge Image Builder 创建相应的os-files文件夹:
.
├── definition.yaml
└── os-files
└── etc
└── modprobe.d
└── module.conf有关更多信息,请参阅 SUSE Linux Enterprise Server 文档中的“管理内核模块”部分。
27.3 Kubernetes #
创建多节点 Kubernetes 集群需要将定义文件中的
kubernetes部分调整为:在
kubernetes.nodes下列出所有服务器和代理节点在
kubernetes.network.apiVIP下设置一个虚拟 IP 地址,供所有非初始化节点加入集群时使用(可选)在
kubernetes.network.apiHost下设置 API 主机以指定用于访问集群的域名地址。要了解有关此配置的更多信息,请参阅 Kubernetes 文档部分。
Edge Image Builder依赖于不同节点的主机名来确定其 Kubernetes 类型(server或agent)。虽然此配置是在定义文件中管理的,但对于机器的常规网络设置,我们可以使用 第 9 章 “边缘网络” 中所述的DHCP配置。
28 Elemental #
28.1 常用 #
28.1.1 暴露 Rancher 服务 #
使用 RKE2 或 K3s 时,我们需要从管理集群暴露服务(在此上下文中为 Rancher),因为它们默认不会被暴露。
在 RKE2 和 k3s 中都有一个 Traefik Ingress 控制器。
当前工作流程建议使用 MetalLB 来发布服务(通过 L2 或 BGP 广播),并使用相应的 Ingress 控制器通过 HelmChartConfig 创建 Ingress,因为创建新的 Ingress 对象会覆盖现有设置。
安装 Rancher Prime(通过 Helm)并配置必要的值
hostname: rancher-192.168.64.101.sslip.io replicas: 1 bootstrapPassword: Admin global.cattle.psp.enabled: "false"创建 LoadBalancer 服务以暴露 Rancher
kubectl apply -f - <<EOF apiVersion: helm.cattle.io/v1 kind: HelmChartConfig metadata: name: rke2-traefik namespace: kube-system spec: valuesContent: |- ingressClass: isDefaultClass: true ports: web: hostPort: null # disallow hostPort exposedPort: 80 websecure: hostPort: null # disallow hostPort exposedPort: 443 service: enabled: true type: LoadBalancer spec: externalTrafficPolicy: Local allocateLoadBalancerNodePorts: false # k8s GA from 1.24; supported by MetalLB EOF使用我们之前在 Helm 值中设置的 IP 地址为该服务创建 IP 地址池
kubectl apply -f - <<EOF apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: ingress-ippool namespace: metallb-system spec: addresses: - 192.168.64.101/32 serviceAllocation: priority: 100 serviceSelectors: - matchExpressions: - {key: app.kubernetes.io/name, operator: In, values: [rke2-traefik]} EOF为 IP 地址池创建 L2 广播
kubectl apply -f - <<EOF apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: ingress-l2-adv namespace: metallb-system spec: ipAddressPools: - ingress-ippool EOF确保正确安装 Elemental
在管理节点上安装 Elemental Operator 和 Elemental UI
在下游节点上添加 Elemental 配置以及注册代码,因为这将提示 Edge Image Builder 为该机器包含远程注册选项。
28.2 硬件特定 #
28.2.1 可信平台模块 (TPM) #
必须正确处理 可信平台模块 (TPM) 配置。 否则将导致类似于以下的错误:
Nov 25 18:17:06 eled elemental-register[4038]: Error: registering machine: cannot generate authentication token: opening tpm for getting attestation data: TPM device not available可以通过以下方法之一来缓解此问题:
在虚拟机设置中启用 TPM
在 MacOS 上使用 UTM 的示例
通过在
MachineRegistration资源中为 TPM 种子使用负值来模拟 TPM
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
name: ...
namespace: ...
spec:
...
elemental:
...
registration:
emulate-tpm: true
emulated-tpm-seed: -1在
MachineRegistration资源中禁用 TPM
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
name: ...
namespace: ...
spec:
...
elemental:
...
registration:
emulate-tpm: false第 V 部分 第三方集成 #
如何集成第三方工具
- 29 NATS
NATS 是一种为日益超连接的世界而构建的连接技术。它是一种单一技术,使应用程序能够跨云供应商、本地、边缘、Web 和移动设备的任意组合进行安全通信。NATS 由一系列开源产品组成,这些产品集成紧密,但可以轻松且独立地部署。NATS 在全球范围内被数千家公司使用,涵盖微服务、边缘计算、移动和物联网等用例,并可用于增强或替代传统消息传递。
- 30 SUSE Linux Micro 上的 NVIDIA GPU
本指南演示了如何通过 SUSE Linux Micro 6.2 上的预构建 开源驱动程序来实现主机级 NVIDIA GPU 支持。这些驱动程序是内置于操作系统中的,而不是由 NVIDIA 的 GPU Operator 动态加载的。对于希望将部署所需的所有工件预先构建到映像中,且不需要通过 Kubernetes 动态选择驱动程序版本的客户而言,此配置非常理想。本指南首先介绍了如何将其他组件部署到已预先部署的系统上,随后介绍如何通过 Edge Image Builder 将此配置嵌入到初始部署中。如果您不想了解基础知识并手动进行设置,请直接跳至该部分。
29 NATS #
NATS 是一种为日益超连接的世界而构建的连接技术。它是一种单一技术,使应用程序能够跨云供应商、本地、边缘、Web 和移动设备的任意组合进行安全通信。NATS 由一系列开源产品组成,这些产品集成紧密,但可以轻松且独立地部署。NATS 在全球范围内被数千家公司使用,涵盖微服务、边缘计算、移动和物联网等用例,并可用于增强或替代传统消息传递。
29.1 体系结构 #
NATS 是一种允许应用程序以消息形式交换数据的基础设施。
29.1.1 NATS 客户端应用程序 #
NATS 客户端库可用于允许应用程序在不同实例之间进行发布、订阅、请求和回复。
这些应用程序通常被称为 client applications。
29.1.2 NATS 服务基础设施 #
NATS 服务由一个或多个 NATS 服务器进程提供,这些进程配置为相互连接并提供 NATS 服务基础设施。NATS 服务基础设施可以从运行在终端设备上的单个 NATS 服务器进程扩展到跨越所有主要云提供商和全球所有区域的公共全球超级集群。
29.1.3 简单的消息传递设计 #
NATS 使应用程序能够通过发送和接收消息轻松进行通信。这些消息通过主题字符串进行寻址和标识,并且不依赖于网络位置。 数据被编码并封装为消息,由发布者发送。消息由一个或多个订阅者接收、解码和处理。
29.1.4 NATS JetStream #
NATS 有一个内置的分布式持久化系统,称为 JetStream。 JetStream 的创建旨在解决当今技术中流处理所面临的问题——复杂性、脆弱性和缺乏可扩展性。JetStream 还解决了发布者和订阅者耦合的问题(订阅者需要在消息发布时处于运行状态才能接收消息)。 有关 NATS JetStream 的更多信息,请参见 此处。
29.2 安装 #
29.2.1 在 K3s 上安装 NATS #
NATS 专为多种架构而构建,因此可以轻松安装在 K3s (第 11 章 “K3s”) 上。
让我们创建一个 values 文件来覆盖 NATS 的默认值。
cat > values.yaml <<EOF
cluster:
# Enable the HA setup of the NATS
enabled: true
replicas: 3
nats:
jetstream:
# Enable JetStream
enabled: true
memStorage:
enabled: true
size: 2Gi
fileStorage:
enabled: true
size: 1Gi
storageDirectory: /data/
EOF现在让我们通过 Helm 安装 NATS:
helm repo add nats https://nats-io.github.io/k8s/helm/charts/
helm install nats nats/nats --namespace nats --values values.yaml \
--create-namespace使用上面的 values.yaml 文件,以下组件将位于 nats 名称空间中:
包含三个容器的 NATS Statefulset 高可用版本:NATS 服务器 + 配置重载程序和指标边车容器。
NATS box 容器,它附带了一组可用于验证设置的
NATS工具。JetStream 还利用了其键值后端,该后端附带了绑定到 Pod 的
PVCs。
29.2.1.1 测试设置 #
kubectl exec -n nats -it deployment/nats-box -- /bin/sh -l为测试主题创建订阅:
nats sub test &向测试主题发送消息:
nats pub test hi
29.2.1.2 清理 #
helm -n nats uninstall nats
rm values.yaml29.2.2 NATS 作为 K3s 的后端 #
K3s 利用的一个组件是 KINE,它是一个垫片,支持将 etcd 替换为原本针对关系型数据库的其他存储后端。 由于 JetStream 提供了键值 API,这使得 NATS 能够作为 K3s 集群的后端。
有一个已经合并的 PR,使 K3s 的内置 NATS 功能变得易于使用,但该更改仍 未包含 在 K3s 版本中。
因此,需要手动构建 K3s 二进制文件。
29.2.2.1 构建 K3s #
git clone --depth 1 https://github.com/k3s-io/k3s.git && cd k3s以下命令在构建标签中添加 nats,以启用 K3s 中的 NATS 内置功能:
sed -i '' 's/TAGS="ctrd/TAGS="nats ctrd/g' scripts/build
make local将 <node-ip> 替换为将要启动 K3s 的节点的实际 IP:
export NODE_IP=<node-ip>
sudo scp dist/artifacts/k3s-arm64 ${NODE_IP}:/usr/local/bin/k3s29.2.2.2 安装 NATS CLI #
TMPDIR=$(mktemp -d)
nats_version="nats-0.0.35-linux-arm64"
curl -o "${TMPDIR}/nats.zip" -sfL https://github.com/nats-io/natscli/releases/download/v0.0.35/${nats_version}.zip
unzip "${TMPDIR}/nats.zip" -d "${TMPDIR}"
sudo scp ${TMPDIR}/${nats_version}/nats ${NODE_IP}:/usr/local/bin/nats
rm -rf ${TMPDIR}29.2.2.3 将 NATS 作为 K3s 的后端运行 #
让我们在节点上 ssh,并使用指向 nats 的 --datastore-endpoint 标志运行 K3s。
下面的命令将 K3s 作为前台进程启动,因此可以轻松跟踪日志以查看是否存在任何问题。
为了不阻塞当前终端,可以在命令前添加 & 标志,将其作为后台进程启动。
k3s server --datastore-endpoint=nats://若要使带有 NATS 后端的 K3s 服务器在您的 slemicro 虚拟机上永久运行,可以运行下面的脚本,它会创建一个带有所需配置的 systemd 服务。
export INSTALL_K3S_SKIP_START=false
export INSTALL_K3S_SKIP_DOWNLOAD=true
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
--datastore-endpoint=nats://" sh -29.2.2.4 查错 #
可以在节点上运行以下命令,以验证流的所有功能是否正常工作:
nats str report -a
nats str view -a30 SUSE Linux Micro 上的 NVIDIA GPU #
30.1 简介 #
本指南演示了如何通过 SUSE Linux Micro 6.2 上的预构建 开源驱动程序来实现主机级 NVIDIA GPU 支持。这些驱动程序是内置于操作系统中的,而不是由 NVIDIA 的 GPU Operator 动态加载的。对于希望将部署所需的所有工件预先构建到映像中,且不需要通过 Kubernetes 动态选择驱动程序版本的客户而言,此配置非常理想。本指南首先介绍了如何将其他组件部署到已预先部署的系统上,随后介绍如何通过 Edge Image Builder 将此配置嵌入到初始部署中。如果您不想了解基础知识并手动进行设置,请直接跳至该部分。
需要指出的是,SUSE 和 NVIDIA 在这些驱动程序的支持方面进行了紧密合作,驱动程序由 SUSE 构建并作为软件包储存库的一部分提供。但是,如果您对所使用的驱动程序组合有任何疑虑或问题,请咨询您的 SUSE 或 NVIDIA 客户经理以获取进一步帮助。如果您计划使用 NVIDIA AI Enterprise (NVAIE),请确保您使用的是 NVAIE 认证的 GPU,这_可能_需要使用 NVIDIA 专有驱动程序。如果您不确定,请咨询您的 NVIDIA 代表。
本指南_不_涵盖有关 NVIDIA GPU Operator 集成的更多信息。虽然此处未涵盖如何集成用于 Kubernetes 的 NVIDIA GPU Operator,但您仍然可以按照本指南中的大多数步骤来设置底层操作系统,并只需在 NVIDIA GPU Operator Helm chart 中启用 driver.enabled=false 标志,即可让 GPU Operator 使用 预安装的 驱动程序,它将直接使用主机上已安装的驱动程序。有关 NVIDIA 的更全面的说明,请参阅 此处。
30.2 先决条件 #
如果您正在阅读本指南,则假定您已具备以下条件:
至少安装有一台运行 SUSE Linux Micro 6.2 的主机;可以是物理机或虚拟机。
您的主机已关联订阅,因为这是访问软件包所必需的 — 您可以 在此 获取评估版。
安装有 兼容的 NVIDIA GPU(或 完全 直通给运行 SUSE Linux Micro 的虚拟机)。
拥有 root 用户访问权限 — 这些说明假设您是 root 用户,并且 没有 通过
sudo提升您的权限。
30.3 手动安装 #
在本节中,您将直接在 SUSE Linux Micro 操作系统上安装 NVIDIA 驱动程序,因为 NVIDIA 开源驱动程序现在已包含在核心 SUSE Linux Micro 软件包储存库中,这使得安装过程就像安装所需的 RPM 软件包一样简单。无需编译或下载可执行软件包。下面我们将介绍如何部署“G06”代系的驱动程序,它支持最新的 GPU(有关更多信息,请参阅 此处),因此请为您的系统所配备的 NVIDIA GPU 选择合适的驱动程序代系。对于现代 GPU,“G06”驱动程序是最常见的选择。
在开始之前,必须认识到,除了 SUSE 作为 SUSE Linux Micro 一部分提供的 NVIDIA 开源驱动程序外,您的设置可能还需要额外的 NVIDIA 组件。这些组件可能包括 OpenGL 库、CUDA 工具包、命令行实用程序(例如 nvidia-smi)以及容器集成组件(例如 nvidia-container-toolkit)。其中许多组件并非由 SUSE 提供,因为它们属于 NVIDIA 专有软件,或者由我们而非 NVIDIA 提供这些组件并不合理。因此,作为说明的一部分,我们将配置额外的储存库以获取这些组件,并演示如何使用这些工具的某些示例,从而构建一个功能完备的系统。区分 SUSE 储存库和 NVIDIA 储存库非常重要,因为 NVIDIA 提供的软件包版本与 SUSE 构建的版本之间有时可能会不匹配。这种情况通常发生在 SUSE 发布新版本的开源驱动程序时,而 NVIDIA 储存库中对应的软件包需要几天时间才能同步更新。
我们建议您通过检查以下内容,确保所选的驱动程序版本与您的 GPU 兼容,并满足您可能有的任何 CUDA 要求:
您计划部署的驱动程序版本在 NVIDIA 储存库 中有匹配的版本,并确保您拥有支持组件的等效软件包版本
要查找 NVIDIA 开源驱动程序版本,请在目标机器上运行 zypper se -s nvidia-open-driver,或者 在 SUSE 客户中心搜索 SUSE Linux Micro 6.2 for AMD64/Intel 64 中的“nvidia-open-driver”。
当您确认 NVIDIA 储存库中有等效版本可用时,即可准备在主机操作系统上安装这些软件包。为此,我们需要打开一个 transactional-update 会话,它会为底层操作系统创建一个新的读/写快照,以便我们能够对不可变平台进行更改(有关 transactional-update 的进一步说明,请参阅 https://documentation.suse.com/sle-micro/6.2/html/Micro-transactional-updates/index.html此处):
transactional-update shell当您处于 transactional-update shell 中时,请从 NVIDIA 添加一个额外的软件包储存库。这允许我们引入额外的实用程序,例如 nvidia-smi:
zypper ar https://download.nvidia.com/suse/sle15sp6/ nvidia-suse-main
zypper --gpg-auto-import-keys refresh然后,您可以安装驱动程序和 nvidia-compute-utils 以获取额外的实用程序。如果您不需要这些实用程序,可以省略它,但出于测试目的,在此阶段安装它是值得的:
zypper install -y --auto-agree-with-licenses nvidia-open-driver-G06-signed-kmp nvidia-compute-utils-G06如果安装失败,这可能表明所选驱动程序版本与 NVIDIA 在其储存库中提供的版本之间存在依赖关系不匹配。请参阅上一节以验证您的版本是否匹配。尝试安装不同的驱动程序版本。例如,如果 NVIDIA 储存库中有较早的版本,您可以尝试在安装命令中指定 nvidia-open-driver-G06-signed-kmp=550.54.14 以指定一个相匹配的版本。
接下来,如果您 不 使用受支持的 GPU(请记住可以在 此处 找到该列表),您可以尝试通过在模块级别启用支持来查看驱动程序是否有效,但结果可能会有所不同——如果您使用的是 受支持 的 GPU,请跳过此步骤:
sed -i '/NVreg_OpenRmEnableUnsupportedGpus/s/^#//g' /etc/modprobe.d/50-nvidia-default.conf现在您已经安装了这些软件包,是时候退出 transactional-update 会话了:
exit在继续之前,请确保您已退出 transactional-update 会话。
现在您已经安装了驱动程序,是时候重新启动了。由于 SUSE Linux Micro 是一个不可变操作系统,它需要重新启动进入您在之前步骤中创建的新快照。驱动程序仅安装到此新快照中,因此如果不重新启动进入此新快照(会自动发生),则无法加载驱动程序。准备好后,请发出重启命令:
reboot系统成功重启后,重新登录并使用 nvidia-smi 工具来验证驱动程序是否已成功加载,以及它是否能够访问并枚举您的 GPU:
nvidia-smi此命令的输出应显示类似于以下输出的内容,请注意在下面的示例中,我们有两个 GPU:
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.29.06 Driver Version: 545.29.06 CUDA Version: 12.3 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA A100-PCIE-40GB Off | 00000000:17:00.0 Off | 0 |
| N/A 29C P0 35W / 250W | 4MiB / 40960MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+----------------------+----------------------+
| 1 NVIDIA A100-PCIE-40GB Off | 00000000:CA:00.0 Off | 0 |
| N/A 30C P0 33W / 250W | 4MiB / 40960MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| No running processes found |
+---------------------------------------------------------------------------------------+至此,SUSE Linux Micro 系统上 NVIDIA 驱动程序的安装和验证过程结束。
30.4 手动安装的进一步验证 #
在此阶段,我们仅能验证在主机层面可以访问 NVIDIA 设备,且驱动程序已成功加载。然而,如果我们想确定它是否正常工作,一个简单的测试是验证 GPU 是否可以接收来自用户空间应用程序的指令,理想情况下是通过容器并经由 CUDA 库,因为这通常是实际工作负载所使用的。为此,我们可以通过安装 nvidia-container-toolkit (NVIDIA Container Toolkit) 对主机操作系统进行进一步修改。首先,打开另一个 transactional-update 外壳,请注意我们本可以在上一步中通过单个事务完成此操作,稍后章节将介绍如何完全自动化执行此操作:
transactional-update shell接下来,从 NVIDIA Container Toolkit 储存库安装 nvidia-container-toolkit 软件包:
下方的
nvidia-container-toolkit.repo包含一个稳定版 (nvidia-container-toolkit) 和一个实验版 (nvidia-container-toolkit-experimental) 储存库。建议在生产环境中使用稳定版储存库。实验版储存库默认处于禁用状态。
zypper ar https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo
zypper --gpg-auto-import-keys install -y nvidia-container-toolkit准备就绪后,您可以退出 transactional-update 外壳:
exit…并重启机器进入新的快照:
reboot与之前一样,您需要确保已退出 transactional-shell 外壳并重启机器,以便使更改生效。
机器重启后,您可以验证系统是否能够使用 NVIDIA Container Toolkit 成功枚举设备。输出应包含详细信息,其中有 INFO 和 WARN 消息,但不应有 ERROR 消息:
nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml这可确保在机器上启动的任何容器都能使用已发现的 NVIDIA GPU 设备。准备就绪后,您即可运行基于 podman 的容器。通过 podman 执行此操作为我们提供了一种验证从容器内访问 NVIDIA 设备的有效方法,这应能为后续在 Kubernetes 中执行相同操作提供信心。根据 SLE BCI,授予 podman 对之前命令所处理的已标记 NVIDIA 设备的访问权限,并直接运行 Bash 命令:
podman run --rm --device nvidia.com/gpu=all --security-opt=label=disable -it registry.suse.com/bci/bci-base:latest bash您现在将在临时 podman 容器内执行命令。它无法访问您的底层系统且是临时的,因此我们在此处执行的任何操作都不会持久保存,并且您不应能够破坏底层主机上的任何内容。由于我们现在处于容器中,我们可以安装所需的 CUDA 库,并再次检查驱动程序 此处 对应的正确 CUDA 版本,尽管 nvidia-smi 的先前输出应已显示所需的 CUDA 版本。在下面的示例中,我们正在安装 CUDA 12.3 并拉取许多示例、演示和开发套件,以便您可以全面验证 GPU:
zypper ar https://developer.download.nvidia.com/compute/cuda/repos/sles15/x86_64/ cuda-suse
zypper in -y cuda-libraries-devel-12-3 cuda-minimal-build-12-3 cuda-demo-suite-12-3安装成功后,请勿退出容器。我们将运行 deviceQuery CUDA 示例,它将全面验证通过 CUDA 进行的 GPU 访问,并从容器内部运行:
/usr/local/cuda-12/extras/demo_suite/deviceQuery如果成功,您应该会看到类似于以下内容的输出,注意命令末尾的 Result = PASS 消息,并注意在下面的输出中,系统正确识别了两个 GPU,而您的环境可能只有一个:
/usr/local/cuda-12/extras/demo_suite/deviceQuery Starting...
CUDA Device Query (Runtime API) version (CUDART static linking)
Detected 2 CUDA Capable device(s)
Device 0: "NVIDIA A100-PCIE-40GB"
CUDA Driver Version / Runtime Version 12.2 / 12.1
CUDA Capability Major/Minor version number: 8.0
Total amount of global memory: 40339 MBytes (42298834944 bytes)
(108) Multiprocessors, ( 64) CUDA Cores/MP: 6912 CUDA Cores
GPU Max Clock rate: 1410 MHz (1.41 GHz)
Memory Clock rate: 1215 Mhz
Memory Bus Width: 5120-bit
L2 Cache Size: 41943040 bytes
Maximum Texture Dimension Size (x,y,z) 1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)
Maximum Layered 1D Texture Size, (num) layers 1D=(32768), 2048 layers
Maximum Layered 2D Texture Size, (num) layers 2D=(32768, 32768), 2048 layers
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 49152 bytes
Total number of registers available per block: 65536
Warp size: 32
Maximum number of threads per multiprocessor: 2048
Maximum number of threads per block: 1024
Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535)
Maximum memory pitch: 2147483647 bytes
Texture alignment: 512 bytes
Concurrent copy and kernel execution: Yes with 3 copy engine(s)
Run time limit on kernels: No
Integrated GPU sharing Host Memory: No
Support host page-locked memory mapping: Yes
Alignment requirement for Surfaces: Yes
Device has ECC support: Enabled
Device supports Unified Addressing (UVA): Yes
Device supports Compute Preemption: Yes
Supports Cooperative Kernel Launch: Yes
Supports MultiDevice Co-op Kernel Launch: Yes
Device PCI Domain ID / Bus ID / location ID: 0 / 23 / 0
Compute Mode:
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
Device 1: <snip to reduce output for multiple devices>
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
> Peer access from NVIDIA A100-PCIE-40GB (GPU0) -> NVIDIA A100-PCIE-40GB (GPU1) : Yes
> Peer access from NVIDIA A100-PCIE-40GB (GPU1) -> NVIDIA A100-PCIE-40GB (GPU0) : Yes
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 12.3, CUDA Runtime Version = 12.3, NumDevs = 2, Device0 = NVIDIA A100-PCIE-40GB, Device1 = NVIDIA A100-PCIE-40GB
Result = PASS从这里,您可以继续运行任何其他 CUDA 工作负载——使用编译器和 CUDA 生态系统的任何其他方面来运行进一步的测试。完成后,您可以退出容器,请注意您在其中安装的任何内容都是临时的(因此会丢失!),并且不会影响底层操作系统:
exit30.5 使用 Kubernetes 实现 #
既然我们已经证明了在 SUSE Linux Micro 上安装和使用 NVIDIA 开源驱动程序,让我们探索在同一台机器上配置 Kubernetes。本指南不会引导您部署 Kubernetes,但它假设您已经安装了 K3s 或 RKE2,并且您的 kubeconfig 已相应配置,以便可以以超级用户身份执行标准 kubectl 命令。我们假设您的节点构成一个单节点集群,尽管核心步骤对于多节点集群应该是相似的。首先,确保您的 kubectl 访问正常工作:
kubectl get nodes这应该显示类似于以下内容:
NAME STATUS ROLES AGE VERSION
node0001 Ready control-plane,etcd,master 13d v1.35.4+rke2r1您应该会发现您的 k3s/rke2 安装已检测到主机上的 NVIDIA Container Toolkit,并自动将 NVIDIA 运行时集成配置到 containerd(k3s/rke2 使用的容器运行时接口)中。通过检查 containerd config.toml 文件来确认这一点:
tail -n8 /var/lib/rancher/rke2/agent/etc/containerd/config.toml这必须显示类似于以下内容。等效的 K3s 位置是 /var/lib/rancher/k3s/agent/etc/containerd/config.toml:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."nvidia"]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."nvidia".options]
BinaryName = "/usr/bin/nvidia-container-runtime"如果这些条目不存在,则检测可能已失败。这可能是由于机器或 Kubernetes 服务未重启所致。如果需要,请按上述方法手动添加这些内容。
接下来,我们需要将 NVIDIA RuntimeClass 配置为除默认运行时之外的额外 Kubernetes 运行时,确保任何需要访问 GPU 的 Pod 用户请求都可以通过 nvidia-container-runtime 使用 NVIDIA Container Toolkit 来实现,正如在 containerd 配置中所配置的那样:
kubectl apply -f - <<EOF
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: nvidia
handler: nvidia
EOF下一步是配置 NVIDIA Device Plugin,它将 Kubernetes 配置为利用集群内的 NVIDIA GPU 作为可使用的资源,并与 NVIDIA Container Toolkit 配合工作。该工具首先检测底层主机上的所有功能,包括 GPU、驱动程序和其他功能(如 GL),然后允许您请求 GPU 资源并将其作为应用程序的一部分进行使用。
首先,您需要添加并更新 NVIDIA Device Plugin 的 Helm 存储库:
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update现在您可以安装 NVIDIA Device Plugin:
helm upgrade -i nvdp nvdp/nvidia-device-plugin --namespace nvidia-device-plugin --create-namespace --version 0.14.5 --set runtimeClassName=nvidia几分钟后,您会看到一个新的 pod 正在运行,它将完成对可用节点的检测,并用已检测到的 GPU 数量对其进行标记。
kubectl get pods -n nvidia-device-plugin
NAME READY STATUS RESTARTS AGE
nvdp-nvidia-device-plugin-jp697 1/1 Running 2 (12h ago) 6d3h
kubectl get node node0001 -o json | jq .status.capacity
{
"cpu": "128",
"ephemeral-storage": "466889732Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "32545636Ki",
"nvidia.com/gpu": "1", <----
"pods": "110"
}现在您已准备好创建一个尝试使用此 GPU 的 NVIDIA pod。让我们尝试使用 CUDA Benchmark 容器:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: nbody-gpu-benchmark
namespace: default
spec:
restartPolicy: OnFailure
runtimeClassName: nvidia
containers:
- name: cuda-container
image: nvcr.io/nvidia/k8s/cuda-sample:nbody
args: ["nbody", "-gpu", "-benchmark"]
resources:
limits:
nvidia.com/gpu: 1
env:
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: all
EOF如果一切顺利,您可以查看日志并查看基准测试信息:
kubectl logs nbody-gpu-benchmark
Run "nbody -benchmark [-numbodies=<numBodies>]" to measure performance.
-fullscreen (run n-body simulation in fullscreen mode)
-fp64 (use double precision floating point values for simulation)
-hostmem (stores simulation data in host memory)
-benchmark (run benchmark to measure performance)
-numbodies=<N> (number of bodies (>= 1) to run in simulation)
-device=<d> (where d=0,1,2.... for the CUDA device to use)
-numdevices=<i> (where i=(number of CUDA devices > 0) to use for simulation)
-compare (compares simulation results running once on the default GPU and once on the CPU)
-cpu (run n-body simulation on the CPU)
-tipsy=<file.bin> (load a tipsy model file for simulation)
NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
> Windowed mode
> Simulation data stored in video memory
> Single precision floating point simulation
> 1 Devices used for simulation
GPU Device 0: "Turing" with compute capability 7.5
> Compute 7.5 CUDA device: [Tesla T4]
40960 bodies, total time for 10 iterations: 101.677 ms
= 165.005 billion interactions per second
= 3300.103 single-precision GFLOP/s at 20 flops per interaction最后,如果您的应用程序需要 OpenGL,您可以在主机级别安装所需的 NVIDIA OpenGL 库,NVIDIA Device Plugin 和 NVIDIA Container Toolkit 可以使它们对容器可用。按如下所示安装该软件包:
transactional-update pkg install nvidia-gl-G06您需要重启以使该软件包对您的应用程序可用。NVIDIA Device Plugin 应通过 NVIDIA Container Toolkit 自动重新检测此项。
30.6 通过 Edge Image Builder 将其整合在一起 #
好了,您已经演示了您的应用程序和 GPU 在 SUSE Linux Micro 上的全部功能,现在您希望使用 第 8 章 “Edge Image Builder” 通过可部署/可使用的 ISO 或 RAW 磁盘映像将所有内容整合在一起。本指南不解释如何使用 Edge Image Builder,但它提供了构建此类镜像所需的配置。您可以在下方找到镜像定义的示例,以及必要的 Kubernetes 配置文件,以确保所有必需的组件能够开箱即用。以下是下方所示示例的 Edge Image Builder 目录结构:
.
├── base-images
│ └── SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
├── eib-config-iso.yaml
├── kubernetes
│ ├── config
│ │ └── server.yaml
│ ├── helm
│ │ └── values
│ │ └── nvidia-device-plugin.yaml
│ └── manifests
│ └── nvidia-runtime-class.yaml
└── rpms
└── gpg-keys
└── nvidia-container-toolkit.key让我们探索这些文件。首先,这是一个运行 K3s 的单节点集群的示例镜像定义,并部署了实用程序和 OpenGL 软件包 (eib-config-iso.yaml):
apiVersion: 1.3
image:
arch: x86_64
imageType: iso
baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
outputImageName: deployimage.iso
operatingSystem:
time:
timezone: Europe/London
ntp:
pools:
- 2.suse.pool.ntp.org
isoConfiguration:
installDevice: /dev/sda
users:
- username: root
encryptedPassword: $6$XcQN1xkuQKjWEtQG$WbhV80rbveDLJDz1c93K5Ga9JDjt3mF.ZUnhYtsS7uE52FR8mmT8Cnii/JPeFk9jzQO6eapESYZesZHO9EslD1
packages:
packageList:
- nvidia-open-driver-G06-signed-kmp-default
- nvidia-compute-utils-G06
- nvidia-gl-G06
- nvidia-container-toolkit
additionalRepos:
- url: https://download.nvidia.com/suse/sle15sp6/
- url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
sccRegistrationCode: [snip]
kubernetes:
version: v1.35.4+k3s1
helm:
charts:
- name: nvidia-device-plugin
version: v0.14.5
installationNamespace: kube-system
targetNamespace: nvidia-device-plugin
createNamespace: true
valuesFile: nvidia-device-plugin.yaml
repositoryName: nvidia
repositories:
- name: nvidia
url: https://nvidia.github.io/k8s-device-plugin这仅是一个镜像示例。您可能需要对其进行定制,以符合您的要求和预期。此外,如果使用 SUSE Linux Micro,您需要提供自己的 sccRegistrationCode 来解析软件包依赖关系并拉取 NVIDIA 驱动程序。
除此之外,我们需要添加额外的组件,以便它们在启动时由 Kubernetes 加载。EIB 目录首先需要一个 kubernetes 目录,其中包含用于配置、Helm chart 值以及所需的任何其他清单的子目录:
mkdir -p kubernetes/config kubernetes/helm/values kubernetes/manifests现在,让我们通过选择 CNI(如果未选择,则默认为 Cilium)并启用 SELinux 来设置(可选的)Kubernetes 配置:
cat << EOF > kubernetes/config/server.yaml
cni: cilium
ingress-controller: traefik
selinux: true
EOF现在,确保在 Kubernetes 集群上创建了 NVIDIA RuntimeClass:
cat << EOF > kubernetes/manifests/nvidia-runtime-class.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: nvidia
handler: nvidia
EOF我们使用内置的 Helm Controller 通过 Kubernetes 本身部署 NVIDIA Device Plugin。 让我们在 chart 的 values 文件中提供运行时类:
cat << EOF > kubernetes/helm/values/nvidia-device-plugin.yaml
runtimeClassName: nvidia
EOF在继续之前,我们需要获取 NVIDIA Container Toolkit RPM 公钥:
mkdir -p rpms/gpg-keys
curl -o rpms/gpg-keys/nvidia-container-toolkit.key https://nvidia.github.io/libnvidia-container/gpgkey所有必需的工件,包括 Kubernetes 二进制文件、容器镜像、Helm chart(以及任何引用的镜像),都将自动隔离,这意味着部署时的系统默认情况下不需要互联网连接。现在,您只需要从 SUSE 下载页面 获取 SUSE Linux Micro .iso 映像(并将其放置在 base-images 目录中),然后就可以调用 Edge Image Builder 工具为您生成 .iso 映像。为了完成此示例,以下是用于构建镜像的命令:
podman run --rm --privileged -it -v /path/to/eib-files/:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-config-iso.yaml有关更多说明,请参阅 Edge Image Builder 的 文档。
30.7 解决问题 #
30.7.1 nvidia-smi 找不到 GPU #
使用 dmesg 检查内核消息。如果这表明它无法分配 NvKMSKapDevice,请应用不受支持的 GPU 变通方法:
sed -i '/NVreg_OpenRmEnableUnsupportedGpus/s/^#//g' /etc/modprobe.d/50-nvidia-default.conf注意:如果您在上述步骤中更改了内核模块配置,则需要重新加载内核模块或重新启动,以使其生效。
第 VI 部分 第2天操作 #
本节介绍了管理员如何处理管理集群和下游集群上的不同“第2天”操作任务。
- 31 边缘 3.6 迁移
本节介绍了如何将您的
management和downstream集群从SUSE Edge 3.5迁移到SUSE Edge 3.6.0。- 32 管理群集
目前,有两种方法可以对您的
management集群执行“第2天”操作:- 33 下游集群
本节介绍了对您的
downstream集群的不同部分执行“第 2 天”操作的可能方法。
31 边缘 3.6 迁移 #
本节介绍了如何将您的 management 和 downstream 集群从 SUSE Edge 3.5 迁移到 SUSE Edge 3.6.0。
请务必从 latest Z-stream 的 SUSE Edge 3.5 版本执行集群迁移。
请务必迁移到 SUSE Edge 3.6.0 版本。有关后续迁移后的升级,请参阅 管理 (第 32 章 “管理群集”)
和 下游 (第 33 章 “下游集群”) 集群
中的各个部分。
下表列出了不同类型的集群以及升级集群的方法:
| 集群类型 | 方法 |
|---|---|
EIB 配置的集群 | 有关详细信息,请参见第 31.1.3 节 “Fleet”。 |
Phone-home 配置的集群 | 有关 Kubernetes 版本升级,请参阅 升级 Kubernetes 版本;有关 SUC、操作系统和其他组件,请参阅 下游集群 (第 33 章 “下游集群”)。 |
31.1 管理群集 #
本节包含下列主题:
第 31.1.1 节 “先决条件” - 开始迁移前需要完成的先决条件步骤。
第 31.1.2 节 “升级控制器” - 如何使用 management 执行 第 19 章 “升级控制器” 集群迁移。
第 31.1.3 节 “Fleet” - 如何使用 management 执行 第 6 章 “Fleet” 集群迁移。
31.1.1 先决条件 #
31.1.1.1 迁移 Metal3 CA 证书配置 #
仅适用于使用额外的受信任 CA 来处理带有 TLS 的外部媒体服务器的 Metal3 部署。
Metal3 Helm chart 更改了受信任 CA 证书的配置方式。以前,额外的 CA 是通过带有 additionalTrustedCAs 布尔标志的 Secret (tls-ca-additional) 提供的。新版本使用包含由 global.trustedCAs 值引用的完整 CA 捆绑包的 ConfigMap。
如果您已为 Metal3 配置了额外的受信任 CA,则需要从基于 Secret 的方法迁移到基于 ConfigMap 的方法:
从现有的 Secret 创建包含您的 CA 捆绑包的 ConfigMap:
从旧的 Secret 中提取证书:
kubectl get secret tls-ca-additional -n metal3-system -o jsonpath='{.data}' | \ jq -r 'to_entries[] | .value' | base64 -d > ca-bundle.pem可选 - 包含系统 CA 捆绑包: 如果您的 Metal3 部署还需要信任公共 CA(例如,通过 HTTPS 访问外部资源时),则除了自定义 CA 之外,还需要包含系统 CA 捆绑包。从容器镜像中提取系统 CA 捆绑包,并将其添加到您的自定义 CA 之前:
# Extract system CAs from a container image (using podman or docker) podman run --rm registry.suse.com/bci/bci-base:latest cat /etc/ssl/certs/ca-certificates.crt > system-cas.pem # Combine system CAs with your custom CAs cat system-cas.pem ca-bundle.pem > combined-ca-bundle.pem mv combined-ca-bundle.pem ca-bundle.pem重要如果您包含系统 CA 捆绑包,则您有责任使其保持最新。容器镜像中的系统 CA 可能会随着 CA 证书过期或被吊销而逐渐过时。您应该通过从更新的容器镜像中重新提取系统 CA 捆绑包来定期刷新它。
使用最终的 CA 捆绑包创建 ConfigMap:
kubectl create configmap tls-ca-bundle -n metal3-system --from-file=ca-bundle.pem=ca-bundle.pem更新您的 Metal3 Helm 值以使用新的 ConfigMap 引用:
更改自:
global: additionalTrustedCAs: true至:
global: trustedCAs: tls-ca-bundle使用新配置升级 Metal3 Helm chart 后,您可以删除旧的 Secret:
kubectl delete secret tls-ca-additional -n metal3-system
31.1.2 升级控制器 #
Upgrade Controller 目前仅支持 SUSE Edge 版本迁移,仅适用于 非隔离的管理 集群。
本节涵盖以下主题:
第 31.1.2.1 节 “先决条件” - Upgrade Controller 的特定先决条件。
第 31.1.2.2 节 “迁移步骤” - 使用 Upgrade Controller 将 management 集群迁移到新 SUSE Edge 版本的步骤。
31.1.2.1 先决条件 #
31.1.2.1.1 SUSE Edge 3.6 升级控制器 #
在使用 Upgrade Controller 之前,您必须首先确保其运行的版本能够迁移到所需的 SUSE Edge 版本。
要执行这一操作:
如果您已经从之前的
Upgrade Controller版本部署了SUSE Edge,请升级其 chart:helm upgrade upgrade-controller -n upgrade-controller-system oci://registry.suse.com/edge/charts/upgrade-controller --version 306.0.4+up0.1.3如果您 没有 部署
Upgrade Controller,请遵循 第 19.3 节 “安装升级控制器”。
31.1.2.2 迁移步骤 #
使用 management 执行 Upgrade Controller 集群迁移与执行升级基本相似。
唯一的区别是您的 UpgradePlan 必须 指定 3.6.0 发布版本:
apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
name: upgrade-plan-mgmt
# Change to the namespace of your Upgrade Controller
namespace: CHANGE_ME
spec:
releaseVersion: 3.6.0有关如何使用上述 UpgradePlan 进行迁移的信息,请参阅 Upgrade Controller 升级流程 (第 32.1 节 “Upgrade Controller”)。
31.1.3 Fleet #
使用 management 执行 Fleet 集群迁移与执行升级基本相似。
*关键*区别在于:
必须使用
suse-edge/fleet-examples储存库的 release-3.6.0 版本中的 Fleet。计划升级的 Chart *必须*升级到与
SUSE Edge 3.6.0版本兼容的版本。有关SUSE Edge 3.6.0组件的列表,请参阅 第 41.4 节 “3.6.0 版本”。
为确保 SUSE Edge 3.6.0 迁移成功,用户务必遵守上述要点。
考虑到上述几点,用户可以遵循 management 集群 Fleet (第 32.2 节 “Fleet”) 文档,获取执行迁移所需步骤的综合指南。
31.2 下游集群 #
第 31.2.1 节 “Fleet” - 如何使用 downstream 执行 第 6 章 “Fleet” 集群迁移。
31.2.1 Fleet #
使用 downstream 执行 Fleet 集群迁移与执行升级基本相似。
*关键*区别在于:
必须使用
suse-edge/fleet-examples储存库的 release-3.6.0 版本中的 Fleet。计划升级的 Chart *必须*升级到与
SUSE Edge 3.6.0版本兼容的版本。有关SUSE Edge 3.6.0组件的列表,请参阅 第 41.4 节 “3.6.0 版本”。
为确保 SUSE Edge 3.6.0 迁移成功,用户务必遵守上述要点。
考虑到上述几点,用户可以遵循 downstream 集群 Fleet (第 33.1 节 “Fleet”) 文档,获取执行迁移所需步骤的综合指南。
32 管理群集 #
目前,有两种方法可以对您的 management 集群执行“第2天”操作:
32.1 Upgrade Controller #
Upgrade Controller 目前仅支持 非隔离的管理 集群的 Day 2 操作。
本节介绍了如何执行与将 management 集群从一个 SUSE Edge 平台版本升级到另一个版本相关的各种 Day 2 操作。
Day 2 操作由 升级控制器 (第 19 章 “升级控制器”) 自动执行,包括:
SUSE Linux Micro (第 7 章 “SUSE Linux Micro”) 操作系统升级
第 12 章 “RKE2” 或 第 11 章 “K3s” Kubernetes 升级
SUSE 附加组件(SUSE Rancher Prime、SUSE Security 等)升级
32.1.1 先决条件 #
在升级您的 management 集群之前,必须满足以下先决条件:
SCC registered nodes- 确保您的集群节点操作系统已使用支持您打算升级到的SUSE Edge版本 (第 41 章 “发行说明”) 中指定的操作系统版本的订阅密钥进行注册。Upgrade Controller- 确保Upgrade Controller已部署在您的management集群上。有关安装步骤,请参阅 第 19.3 节 “安装升级控制器”。
32.1.2 升级 #
确定您希望将
management集群升级到的SUSE Edge版本 (第 41 章 “发行说明”)。在
management集群中,部署一个指定所需UpgradePlan的release version。UpgradePlan必须部署在Upgrade Controller的名称空间中。kubectl apply -n <upgrade_controller_namespace> -f - <<EOF apiVersion: lifecycle.suse.com/v1alpha1 kind: UpgradePlan metadata: name: upgrade-plan-mgmt spec: # Version retrieved from release notes releaseVersion: 3.X.Y EOF将
UpgradePlan部署到Upgrade Controller’s名称空间将开始upgrade process。注意有关实际
upgrade process的详细信息,请参考 第 19.5 节 “升级控制器如何工作?”。有关如何跟踪
upgrade process的信息,请参考 第 19.7 节 “跟踪升级过程”。
32.1.3 升级后步骤 #
从最新的 SUSE Edge z-stream 升级到 3.5 的 3.6.0 升级可能需要在 Upgrade Controller 完成升级过程后执行一些最终的手动步骤。这些步骤与从 SUSE Edge 版本开始将 Ingress-NGINX 替换为 Traefik 作为 3.6 中唯一受支持的入口控制器有关。
集成到 RKE2/K3s 中的 Traefik 入口提供程序是 SUSE Edge 3.6 版本中唯一受支持的入口控制器,虽然仍然可以暂时将 Ingress-NGINX 与 Traefik 一起运行以支持复杂的入口迁移场景,但这仅能在 SUSE Edge 管理集群和/或下游集群升级到版本 3.6 之后,且仅在执行该迁移所需的时间内进行。
RKE2 从 Ingress NGINX 迁移到 Traefik 指南提供了有关 Traefik 入口控制器取代已停用的 Ingress-NGINX 后可用入口迁移路径的详细信息。
如果刚升级的管理集群在触发升级之前未运行 Traefik ingress 控制器(而是运行默认的 Ingress-NGINX 控制器),则现在需要手动部署 Traefik。
首先,我们将确保已部署的 ingress-NGINX 实例配置正确(例如,避免两个 ingress 控制器的 Pod 之间出现不必要的 hostPort 冲突):
kubectl apply -f - <<- EOF
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-ingress-nginx
namespace: kube-system
spec:
valuesContent: |-
controller:
hostPort:
enabled: false # not needed when exposing through a type:LoadBalancer service
config:
use-forwarded-headers: "true"
enable-real-ip: "true"
publishService:
enabled: true
service:
enabled: true
type: LoadBalancer
externalTrafficPolicy: Local
EOF现在,我们可以通过安装 Traefik 和 rke2-traefik-crd Helm charts 来继续部署 rke2-traefik。
通过 HelmChart 清单部署这些 Helm chart(如下所示),以确保 Upgrade Controller 在未来的管理集群升级中也会负责升级这些 Helm chart。
kubectl apply -f - <<- EOF
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: rke2-traefik-crd
namespace: kube-system
spec:
chart: rke2-traefik-crd
version: {rke2-traefik-crd Helm chart version}
repo: https://rke2-charts.rancher.io
bootstrap: false
failurePolicy: reinstall
backOffLimit: 20
targetNamespace: kube-system
set:
global.cattle.systemDefaultRegistry: registry.rancher.com
global.rke2DataDir: /var/lib/rancher/rke2
global.systemDefaultRegistry: registry.rancher.com
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: rke2-traefik
namespace: kube-system
spec:
chart: rke2-traefik
version: {rke2-traefik Helm chart version}
repo: https://rke2-charts.rancher.io
bootstrap: false
failurePolicy: reinstall
backOffLimit: 20
targetNamespace: kube-system
set:
global.cattle.systemDefaultRegistry: registry.rancher.com
global.rke2DataDir: /var/lib/rancher/rke2
global.systemDefaultRegistry: registry.rancher.com
valuesContent: |-
ingressClass:
isDefaultClass: false # if traefik deployed alongside ingress-nginx
ports:
web:
hostPort: null # disallow hostPort
exposedPort: 80
websecure:
hostPort: null # disallow hostPort
exposedPort: 443
service:
enabled: true
type: LoadBalancer
spec:
externalTrafficPolicy: Local
allocateLoadBalancerNodePorts: false # k8s GA from 1.24; supported by MetalLB
providers:
kubernetesIngressNginx: # this provider allows traefik to "understand" most of the ingress-nginx annotations
enabled: true
ingressClass: "rke2-ingress-nginx-migration"
controllerClass: "rke2.cattle.io/ingress-nginx-migration"
EOF{rke2-traefik-crd Helm chart version} 和 {rke2-traefik-crd Helm chart version} 由我们已升级到的 RKE2/K3s 版本决定。
在最后一步中,我们最终创建 MetalLB 所需的对象,以通过 LoadBalancer 类型服务公开 Traefik 服务:
kubectl apply -f - <<- EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ingress-ippool-traefik
namespace: metallb-system
spec:
addresses:
- {EXTERNAL_IP_FOR_TRAEFIK_SERVICE}/32
serviceAllocation:
priority: 100
serviceSelectors:
- matchExpressions:
- {key: app.kubernetes.io/name, operator: In, values: [rke2-traefik]}
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: ingress-l2-adv-traefik
namespace: metallb-system
spec:
ipAddressPools:
- ingress-ippool-traefik
EOF现在 Traefik 和 Ingress-NGINX 可以并排运行,使您可以安全地将 ingress 从一个迁移到另一个。
一旦所有 ingress 都已迁移且您不再需要 Ingress-NGINX,请务必卸载它并清理所有相关资源,以避免集群上出现不必要的资源消耗。
32.2 Fleet #
本节提供有关如何使用 Fleet (第 6 章 “Fleet”) 组件执行“第 2 天”操作的信息。
本节涵盖以下主题:
第 32.2.1 节 “组件” - 用于所有“第 2 天”操作的默认组件。
第 32.2.2 节 “确定您的用例” - 提供将要使用的 Fleet 自定义资源概述,以及它们对不同“第 2 天”操作用例的适用性。
第 32.2.3 节 “Day 2 工作流” - 提供使用 Fleet 执行“第 2 天”操作的工作流程指南。
第 32.2.4 节 “操作系统升级” - 描述如何使用 Fleet 进行操作系统升级。
第 32.2.5 节 “Kubernetes 版本升级” - 描述如何使用 Fleet 进行 Kubernetes 版本升级。
第 32.2.6 节 “Helm chart 升级” - 描述如何使用 Fleet 进行 Helm chart 升级。
32.2.1 组件 #
您可以在下方找到应在您的 management 集群上设置的默认组件说明,以便您能够使用 Fleet 成功执行“第 2 天”操作。
32.2.1.1 Rancher #
可选;负责管理 downstream clusters 并在您的 System Upgrade Controller 上部署 management cluster。
有关详细信息,请访问 第 4 章 “Rancher”。
32.2.1.2 系统升级控制器 (SUC) #
*系统升级控制器*负责根据通过名为 Plan 的自定义资源提供配置数据,在指定节点上执行任务。
*SUC*被主动用于升级操作系统和 Kubernetes 发行版。
有关 SUC 组件及其如何适配 Edge 堆栈的更多信息,请参阅 第 18 章 “系统升级控制器”。
32.2.2 确定您的用例 #
Fleet 使用两种类型的 自定义资源 来实现 Kubernetes 和 Helm 资源的管理。
您可以在下方找到有关这些资源的目的以及它们在“第 2 天”操作背景下最适合的用例的信息。
32.2.2.1 GitRepo #
GitRepo 是一个 Fleet (第 6 章 “Fleet”) 资源,它代表一个 Fleet 可以从中创建 Bundles 的 Git 储存库。每个 Bundle 都是基于 GitRepo 资源内定义的配置路径创建的。有关详细信息,请参见 GitRepo 文档。
在“Day 2”操作的背景下,GitRepo 资源通常用于在利用 Fleet GitOps 方法的 非隔离的 环境中部署 SUC 或 SUC Plans。
或者,GitRepo 资源也可用于在 隔离的 环境中部署 SUC 或 SUC Plans,前提是您通过本地 git 服务器镜像您的储存库设置。
32.2.2.2 捆绑包 #
Bundles 包含将部署在目标集群上的 原始 Kubernetes 资源。通常它们是从 GitRepo 资源创建的,但在某些用例中也可以手动部署它们。有关详细信息,请参考 Bundle 文档。
在“Day 2”操作的背景下,Bundle 资源通常用于在不使用某种 本地 GitOps 流程(例如 本地 git 服务器)的 隔离的 环境中部署 SUC 或 SUC Plans。
或者,如果您的用例不允许 GitOps 工作流(例如使用 Git 储存库),则 Bundle 资源也可用于在 非隔离的 环境中部署 SUC 或 SUC Plans。
32.2.3 Day 2 工作流 #
以下是升级 management 集群到特定 Edge 版本时应遵循的“Day 2”工作流。
操作系统升级 (第 32.2.4 节 “操作系统升级”)
Kubernetes 版本升级 (第 32.2.5 节 “Kubernetes 版本升级”)
Helm chart 升级 (第 32.2.6 节 “Helm chart 升级”)
32.2.4 操作系统升级 #
本节介绍如何使用 第 6 章 “Fleet” 和 第 18 章 “系统升级控制器” 执行操作系统升级。
本节涵盖以下主题:
第 32.2.4.1 节 “组件” - 升级过程中使用的附加组件。
第 32.2.4.2 节 “概述” - 升级过程概述。
第 32.2.4.3 节 “要求” - 升级过程的要求。
第 32.2.4.4 节 “操作系统升级 - SUC 计划部署” - 有关如何部署负责触发升级过程的
SUC plans的信息。
32.2.4.1 组件 #
本节涵盖 OS upgrade 过程在默认“第 2 天”组件 (第 32.2.1 节 “组件”) 之外使用的自定义组件。
32.2.4.1.1 systemd.service #
特定节点上的操作系统升级由 systemd.service 处理。
根据操作系统从一个 Edge 版本升级到另一个版本所需的升级类型,会创建不同的服务:
上述服务通过 SUC plan 在每个节点上部署,该服务必须位于需要操作系统升级的 management 集群上。
32.2.4.2 概述 #
management 集群节点的操作系统升级是通过利用 Fleet 和 System Upgrade Controller (SUC) 完成的。
Fleet 用于在目标集群上部署和管理 SUC plans。
OS SUC plans 通过将 GitRepo 或 Bundle 资源部署到特定的 Fleet 工作区 来分发到每个集群。Fleet 会检索已部署的 GitRepo/Bundle 并将其内容(即 OS SUC plans)部署到目标集群。
GitRepo/Bundle 资源始终部署在 management cluster 上。是否使用 GitRepo 或 Bundle 资源取决于您的用例,请查看 第 32.2.2 节 “确定您的用例” 以获取更多信息。
OS SUC plans 描述了以下工作流程:
在操作系统升级之前,请务必 隔离 节点。
请务必先升级
control-plane节点,然后再升级worker节点。请务必一次只升级一个 one 节点。
一旦部署了 OS SUC plans,工作流程如下所示:
SUC 会协调已部署的
OS SUC plans并在 每个节点 上创建一个Kubernetes Job。Kubernetes Job会为软件包升级或操作系统迁移创建一个 systemd.service (第 32.2.4.1.1 节 “systemd.service”)。所创建的
systemd.service会触发特定节点上的操作系统升级过程。重要一旦操作系统升级过程完成,相应的节点将被
rebooted以应用系统更新。
您可以在下方找到上述描述的图示:
32.2.4.3 要求 #
常规:
SCC 注册机器 - 所有 management 集群节点都应注册到
https://scc.suse.com/,这是使相应的systemd.service能够成功连接到所需 RPM 储存库所必需的。重要对于需要操作系统版本迁移的 Edge 版本(例如
6.1→6.2),请确保您的 SCC 密钥支持迁移到新版本。确保 SUC Plan 容忍度与节点容忍度匹配 - 如果您的 Kubernetes 集群节点具有自定义 污点,请确保在 SUC Plans 中为这些污点添加 容忍度。默认情况下,SUC Plans 仅具有针对 控制平面 节点的容忍度。默认容忍度包括:
CriticalAddonsOnly=true:NoExecute
node-role.kubernetes.io/control-plane:NoSchedule
node-role.kubernetes.io/etcd:NoExecute
注意任何额外的容忍度必须添加到每个计划的
.spec.tolerations部分下。与操作系统升级相关的*SUC 计划*可以在`fleets/day2/system-upgrade-controller-plans/os-upgrade`下的suse-edge/fleet-examples储存库中找到。确保您使用来自有效存储库发布标签的计划。为*控制平面* SUC 计划定义自定义容忍度的示例如下:
apiVersion: upgrade.cattle.io/v1 kind: Plan metadata: name: os-upgrade-control-plane spec: ... tolerations: # default tolerations - key: "CriticalAddonsOnly" operator: "Equal" value: "true" effect: "NoExecute" - key: "node-role.kubernetes.io/control-plane" operator: "Equal" effect: "NoSchedule" - key: "node-role.kubernetes.io/etcd" operator: "Equal" effect: "NoExecute" # custom toleration - key: "foo" operator: "Equal" value: "bar" effect: "NoSchedule" ...
隔离的:
32.2.4.4 操作系统升级 - SUC 计划部署 #
对于之前使用此过程升级过的环境,用户应确保完成以下其中*一*步骤:
这样做是为了避免旧版 Edge 发行版本之间的`SUC Plans`冲突。
如果用户在 management 集群上存在现有的 SUC Plans 时尝试升级,他们将看到以下 fleet 错误:
Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..如 第 32.2.4.2 节 “概述” 中所述,操作系统升级是通过以下方式之一将 SUC plans 部署到目标集群来完成的:
Fleet
GitRepo资源 - 第 32.2.4.4.1 节 “SUC 计划部署 - GitRepo 资源”。Fleet
Bundle资源 - 第 32.2.4.4.2 节 “SUC 计划部署 - Bundle 资源”。
要确定应使用哪种资源,请参阅第 32.2.2 节 “确定您的用例”。
对于希望从第三方 GitOps 工具部署`OS SUC plans`的用例,请参阅第 32.2.4.4.3 节 “SUC 计划部署 - 第三方 GitOps 工作流”
32.2.4.4.1 SUC 计划部署 - GitRepo 资源 #
可以采用以下方式之一部署包含所需`OS SUC plans`的*GitRepo*资源:
通过
Rancher UI- 第 32.2.4.4.1.1 节 “GitRepo 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 32.2.4.4.1.2 节 “GitRepo 创建 - 手动”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的操作系统升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
32.2.4.4.1.1 GitRepo 创建 - Rancher UI #
要通过 Rancher UI 创建 GitRepo 资源,请遵循其官方 文档。
Edge 团队维护着一个可直接使用的 Fleet。根据您的环境,此 Fleet 可以直接使用或作为模板使用。
对于不需要对 Fleet 附带的 SUC plans 进行任何自定义更改的用例,用户可以直接引用来自 suse-edge/fleet-examples 储存库的 os-upgrade Fleet。
如果需要自定义更改(例如添加自定义容忍度),用户应引用来自单独储存库的 os-upgrade Fleet,以便根据需要将更改添加到 SUC 计划中。
关于如何配置 GitRepo 以使用来自 suse-edge/fleet-examples 储存库的 Fleet 的示例,可以在 此处 查看。
32.2.4.4.1.2 GitRepo 创建 - 手动 #
拉取 GitRepo 资源:
curl -o os-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/gitrepos/day2/os-upgrade-gitrepo.yaml编辑 GitRepo 配置:
删除
spec.targets部分 - 仅下游集群需要。# Example using sed sed -i.bak '/^ targets:/,$d' os-upgrade-gitrepo.yaml && rm -f os-upgrade-gitrepo.yaml.bak # Example using yq (v4+) yq eval 'del(.spec.targets)' -i os-upgrade-gitrepo.yaml将
GitRepo的命名空间指向fleet-local命名空间 - 这样做是为了在管理集群上部署资源。# Example using sed sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' os-upgrade-gitrepo.yaml && rm -f os-upgrade-gitrepo.yaml.bak # Example using yq (v4+) yq eval '.metadata.namespace = "fleet-local"' -i os-upgrade-gitrepo.yaml
应用 GitRepo 资源到您的
management cluster:kubectl apply -f os-upgrade-gitrepo.yaml在
fleet-local名称空间下查看已创建的 GitRepo 资源:kubectl get gitrepo os-upgrade -n fleet-local # Example output NAME REPO COMMIT BUNDLEDEPLOYMENTS-READY STATUS os-upgrade https://github.com/suse-edge/fleet-examples.git release-3.6.1 0/0
32.2.4.4.2 SUC 计划部署 - Bundle 资源 #
一个 Bundle 资源(用于交付所需的 OS SUC Plans)可以通过以下方式之一进行部署:
通过
Rancher UI- 第 32.2.4.4.2.1 节 “Bundle 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 32.2.4.4.2.2 节 “Bundle 创建 - 手动”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的操作系统升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
32.2.4.4.2.1 Bundle 创建 - Rancher UI #
Edge 团队维护了一个可直接使用的 bundle,可用于以下步骤。
通过 Rancher UI 创建 bundle:
在左上角,点击 ☰ → 持续交付
转到 高级 > Bundles
选择 从 YAML 创建
在此处,您可以通过以下方式之一创建 Bundle:
注意在某些用例中,您可能需要将自定义更改包含到 bundle 所交付的
SUC plans中(例如,添加自定义容忍度)。请确保将这些更改包含在通过以下步骤生成的 bundle 中。通过手动将 bundle 内容 从
suse-edge/fleet-examples复制到 从 YAML 创建 页面。通过从所需的 发布 标签克隆 suse-edge/fleet-examples 储存库,并在 从 YAML 创建 页面中选择 从文件读取 选项。从那里,导航到 bundle 位置 (
bundles/day2/system-upgrade-controller-plans/os-upgrade) 并选择 bundle 文件。这将自动填充 从 YAML 创建 页面中的 bundle 内容。
在 Rancher UI 中编辑 Bundle:
将
Bundle的 名称空间 更改为指向fleet-local的名称空间。# Example kind: Bundle apiVersion: fleet.cattle.io/v1alpha1 metadata: name: os-upgrade namespace: fleet-local ...将
Bundle的 目标 集群更改为指向您的local(管理)集群:spec: targets: - clusterName: local注意在某些用例中,您的
local集群可能具有不同的名称。要检索您的
local集群名称,请执行以下命令:kubectl get clusters.fleet.cattle.io -n fleet-local
选择 创建
32.2.4.4.2.2 Bundle 创建 - 手动 #
拉取 Bundle 资源:
curl -o os-upgrade-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/bundles/day2/system-upgrade-controller-plans/os-upgrade/os-upgrade-bundle.yaml编辑
Bundle配置:将
Bundle的 目标 集群更改为指向您的local(管理)集群:spec: targets: - clusterName: local注意在某些用例中,您的
local集群可能具有不同的名称。要检索您的
local集群名称,请执行以下命令:kubectl get clusters.fleet.cattle.io -n fleet-local将
Bundle的 名称空间 更改为指向fleet-local的名称空间。# Example kind: Bundle apiVersion: fleet.cattle.io/v1alpha1 metadata: name: os-upgrade namespace: fleet-local ...
将 Bundle 资源应用到您的
management cluster:kubectl apply -f os-upgrade-bundle.yaml在
fleet-local名称空间下查看已创建的 Bundle 资源:kubectl get bundles -n fleet-local
32.2.4.4.3 SUC 计划部署 - 第三方 GitOps 工作流 #
在某些用例中,用户可能希望将 OS SUC plans 集成到他们自己的第三方 GitOps 工作流(例如 Flux)中。
要获取所需的操作系统升级资源,请首先确定您想要使用的 suse-edge/fleet-examples 储存库的 Edge 发布 标签。
之后,可以在 fleets/day2/system-upgrade-controller-plans/os-upgrade 处找到资源,其中:
plan-control-plane.yaml是用于 控制平面 节点的 SUC 计划资源。plan-worker.yaml是用于 工作节点 的 SUC 计划资源。secret.yaml是一个包含upgrade.sh脚本的 Secret,该脚本负责创建 systemd.service (第 32.2.4.1.1 节 “systemd.service”)。config-map.yaml是一个 ConfigMap,其中保存了供upgrade.sh脚本使用的配置。
这些 Plan 资源由 System Upgrade Controller 进行解释,并应部署在您希望升级的每个下游集群上。有关 SUC 部署信息,请参见 第 18.2 节 “安装系统升级控制器”。
为了更好地了解如何使用 GitOps 工作流来部署用于操作系统升级的 SUC Plans,查看 overview (第 32.2.4.2 节 “概述”) 会有所帮助。
32.2.5 Kubernetes 版本升级 #
本节介绍了如何使用 第 6 章 “Fleet” 和 第 18 章 “系统升级控制器” 执行 Kubernetes 升级。
本节涵盖以下主题:
第 32.2.5.1 节 “组件” - 升级过程中使用的其他组件。
第 32.2.5.2 节 “概述” - 升级过程概述。
第 32.2.5.3 节 “要求” - 升级过程的要求。
第 32.2.5.4 节 “K8s 升级 - SUC 计划部署” - 有关如何部署
SUC plans的信息,它负责触发升级过程。
32.2.5.1 组件 #
本节涵盖了 K8s upgrade 过程在默认“Day 2”组件 (第 32.2.1 节 “组件”)之外使用的自定义组件。
32.2.5.1.1 rke2-upgrade #
负责升级特定节点 RKE2 版本的容器镜像。
通过 SUC 基于 SUC 计划 创建的 Pod 进行分发。该计划应位于每个需要 RKE2 升级的 集群 上。
有关 rke2-upgrade 镜像如何执行升级的更多信息,请参阅 上游 文档。
32.2.5.1.2 k3s-upgrade #
负责升级特定节点 K3s 版本的容器镜像。
通过 SUC 基于 SUC 计划 创建的 Pod 进行分发。该计划应位于每个需要 K3s 升级的 集群 上。
有关 k3s-upgrade 镜像如何执行升级的更多信息,请参阅 上游 文档。
32.2.5.2 概述 #
management 集群节点的 Kubernetes 发行版升级是通过利用 Fleet 和 System Upgrade Controller (SUC) 完成的。
Fleet 用于将 SUC plans 部署并管理到目标集群上。
K8s SUC plans 通过将 GitRepo 或 Bundle 资源部署到特定的 Fleet 工作区,从而在每个集群上进行交付。Fleet 获取已部署的 GitRepo/Bundle 并将其内容(即 K8s SUC plans)部署到一个或多个目标集群。
GitRepo/Bundle 资源始终部署在 management cluster 上。是使用 GitRepo 还是 Bundle 资源取决于您的用例,请查看 第 32.2.2 节 “确定您的用例” 以获取更多信息。
K8s SUC plans 描述了以下工作流程:
在 K8s 升级之前,请务必 隔离 节点。
请务必先升级
control-plane节点,然后再升级worker节点。请务必每次升级
control-plane节点中的 一个 节点,以及worker节点中的 两个 节点。
一旦部署了 K8s SUC plans,工作流程如下所示:
SUC 会协调已部署的
K8s SUC plans并在 每个节点 上创建一个Kubernetes Job。根据 Kubernetes 发行版的不同,该 Job 将创建一个运行 rke2-upgrade (第 32.2.5.1.1 节 “rke2-upgrade”) 或 k3s-upgrade (第 32.2.5.1.2 节 “k3s-upgrade”) 容器镜像的 Pod。
创建的 Pod 将经历以下工作流程:
将节点上现有的
rke2/k3s二进制文件替换为来自rke2-upgrade/k3s-upgrade镜像的文件。终止正在运行的
rke2/k3s进程。
终止
rke2/k3s进程会触发重启,启动一个运行更新后二进制文件的新进程,从而实现 Kubernetes 发行版版本的升级。
您可以在下方找到上述描述的图示:
32.2.5.3 要求 #
备份您的 Kubernetes 发行版:
对于 RKE2 集群,请参阅 RKE2 备份与恢复 文档。
对于 K3s 集群,请参阅 K3s 备份与恢复 文档。
确保 SUC Plan 容忍度与节点容忍度匹配 - 如果您的 Kubernetes 集群节点具有自定义 污点,请确保在 SUC Plans 中为这些污点添加 容忍度。默认情况下,SUC Plans 仅包含针对 控制平面 节点的容忍度。默认容忍度包括:
CriticalAddonsOnly=true:NoExecute
node-role.kubernetes.io/control-plane:NoSchedule
node-role.kubernetes.io/etcd:NoExecute
注意任何额外的容忍度必须添加到每个 Plan 的
.spec.tolerations部分下。与 Kubernetes 版本升级相关的 SUC Plans 可以在 suse-edge/fleet-examples 储存库的以下位置找到:对于 RKE2 -
fleets/day2/system-upgrade-controller-plans/rke2-upgrade对于 K3s -
fleets/day2/system-upgrade-controller-plans/k3s-upgrade
请确保您使用的是来自有效储存库 发布 标签的 Plans。
为 RKE2 控制平面 SUC Plan 定义自定义容忍度的示例如下:
apiVersion: upgrade.cattle.io/v1 kind: Plan metadata: name: rke2-upgrade-control-plane spec: ... tolerations: # default tolerations - key: "CriticalAddonsOnly" operator: "Equal" value: "true" effect: "NoExecute" - key: "node-role.kubernetes.io/control-plane" operator: "Equal" effect: "NoSchedule" - key: "node-role.kubernetes.io/etcd" operator: "Equal" effect: "NoExecute" # custom toleration - key: "foo" operator: "Equal" value: "bar" effect: "NoSchedule" ...
32.2.5.4 K8s 升级 - SUC 计划部署 #
对于之前使用此过程升级过的环境,用户应确保完成以下 一项 步骤:
这样做是为了避免旧版 Edge 发行版本之间的 SUC Plans 冲突。
如果用户在 management 集群上存在现有 SUC Plans 的情况下尝试升级,他们将看到以下 fleet 错误:
Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..如 第 32.2.5.2 节 “概述” 中所述,Kubernetes 升级是通过以下方式之一将 SUC plans 发送到目标集群来完成的:
Fleet GitRepo 资源 (第 32.2.5.4.1 节 “SUC 计划部署 - GitRepo 资源”)
Fleet Bundle 资源 (第 32.2.5.4.2 节 “SUC 计划部署 - Bundle 资源”)
要确定应使用哪种资源,请参阅 第 32.2.2 节 “确定您的用例”。
对于希望从第三方 GitOps 工具部署 K8s SUC plans 的用例,请参阅 第 32.2.5.4.3 节 “SUC 计划部署 - 第三方 GitOps 工作流”
32.2.5.4.1 SUC 计划部署 - GitRepo 资源 #
所需 K8s SUC plans 的 GitRepo 资源可通过以下方式之一进行部署:
通过
Rancher UI- 第 32.2.5.4.1.1 节 “GitRepo 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 32.2.5.4.1.2 节 “GitRepo 创建 - 手动”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的 Kubernetes 升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
32.2.5.4.1.1 GitRepo 创建 - Rancher UI #
要通过 Rancher UI 创建 GitRepo 资源,请遵循其官方 文档。
Edge 团队维护着适用于 rke2 和 k3s Kubernetes 发行版的现成 fleet。根据您的环境,此 fleet 可以直接使用或作为模板使用。
对于不需要对这些 fleet 所发送的 SUC plans 进行任何自定义更改的用例,用户可以直接引用 suse-edge/fleet-examples 储存库中的 fleet。
如果需要自定义更改(例如添加自定义容忍度),用户应引用单独储存库中的 fleet,以便根据需要将更改添加到 SUC 计划中。
使用来自 GitRepo 储存库的 fleet 的 suse-edge/fleet-examples 资源配置示例:
32.2.5.4.1.2 GitRepo 创建 - 手动 #
拉取 GitRepo 资源:
对于 RKE2 集群:
curl -o rke2-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/gitrepos/day2/rke2-upgrade-gitrepo.yaml对于 K3s 集群:
curl -o k3s-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/gitrepos/day2/k3s-upgrade-gitrepo.yaml
编辑 GitRepo 配置:
删除
spec.targets部分 - 仅下游集群需要。对于 RKE2:
# Example using sed sed -i.bak '/^ targets:/,$d' rke2-upgrade-gitrepo.yaml && rm -f rke2-upgrade-gitrepo.yaml.bak # Example using yq (v4+) yq eval 'del(.spec.targets)' -i rke2-upgrade-gitrepo.yaml对于 K3s:
# Example using sed sed -i.bak '/^ targets:/,$d' k3s-upgrade-gitrepo.yaml && rm -f k3s-upgrade-gitrepo.yaml.bak # Example using yq (v4+) yq eval 'del(.spec.targets)' -i k3s-upgrade-gitrepo.yaml
将
GitRepo的命名空间指向fleet-local命名空间——这样做是为了在管理集群上部署资源。对于 RKE2:
# Example using sed sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' rke2-upgrade-gitrepo.yaml && rm -f rke2-upgrade-gitrepo.yaml.bak # Example using yq (v4+) yq eval '.metadata.namespace = "fleet-local"' -i rke2-upgrade-gitrepo.yaml对于 K3s:
# Example using sed sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' k3s-upgrade-gitrepo.yaml && rm -f k3s-upgrade-gitrepo.yaml.bak # Example using yq (v4+) yq eval '.metadata.namespace = "fleet-local"' -i k3s-upgrade-gitrepo.yaml
将 GitRepo 资源应用到您的
management cluster:# RKE2 kubectl apply -f rke2-upgrade-gitrepo.yaml # K3s kubectl apply -f k3s-upgrade-gitrepo.yaml在
fleet-local命名空间下查看创建的 GitRepo 资源:# RKE2 kubectl get gitrepo rke2-upgrade -n fleet-local # K3s kubectl get gitrepo k3s-upgrade -n fleet-local # Example output NAME REPO COMMIT BUNDLEDEPLOYMENTS-READY STATUS k3s-upgrade https://github.com/suse-edge/fleet-examples.git fleet-local 0/0 rke2-upgrade https://github.com/suse-edge/fleet-examples.git fleet-local 0/0
32.2.5.4.2 SUC 计划部署 - Bundle 资源 #
可以采用以下方式之一部署包含所需 Kubernetes upgrade SUC Plans 的 Bundle 资源:
通过
Rancher UI- 第 32.2.5.4.2.1 节 “Bundle 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 32.2.5.4.2.2 节 “Bundle 创建 - 手动创建”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的 Kubernetes 升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
32.2.5.4.2.1 Bundle 创建 - Rancher UI #
Edge 团队为 rke2 和 k3s Kubernetes 发行版维护了可直接使用的 bundle。根据您的环境,这些 bundle 可以直接使用或作为模板使用。
通过 Rancher UI 创建 bundle:
在左上角,点击 ☰ → 持续交付
转到 高级 > Bundles
选择 从 YAML 创建
在此处,您可以通过以下方式之一创建 Bundle:
注意在某些用例中,您可能需要将自定义更改包含到 Bundle 附带的
SUC plans中(例如,添加自定义容忍度)。请确保在通过以下步骤生成的 Bundle 中包含这些更改。通过手动将 RKE2 或 K3s 的 Bundle 内容从
suse-edge/fleet-examples复制到 从 YAML 创建 页面。通过从所需的 发布 标签克隆 suse-edge/fleet-examples 储存库,并在 从 YAML 创建 页面中选择 从文件读取 选项。从那里,导航到您需要的 Bundle(RKE2 为
bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml,K3s 为bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml)。这将自动填充 从 YAML 创建 页面中的 Bundle 内容。
在 Rancher UI 中编辑 Bundle:
将
Bundle的 名称空间 更改为指向fleet-local名称空间。# Example kind: Bundle apiVersion: fleet.cattle.io/v1alpha1 metadata: name: rke2-upgrade namespace: fleet-local ...将
Bundle的 目标 集群更改为指向您的local(管理)集群:spec: targets: - clusterName: local注意在某些用例中,您的
local集群可能具有不同的名称。要检索您的
local集群名称,请执行以下命令:kubectl get clusters.fleet.cattle.io -n fleet-local
选择 创建
32.2.5.4.2.2 Bundle 创建 - 手动创建 #
拉取 Bundle 资源:
对于 RKE2 集群:
curl -o rke2-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml对于 K3s 集群:
curl -o k3s-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml
编辑
Bundle配置:将
Bundle的 目标 集群更改为指向您的local(管理)集群:spec: targets: - clusterName: local注意在某些用例中,您的
local集群可能具有不同的名称。要检索您的
local集群名称,请执行以下命令:kubectl get clusters.fleet.cattle.io -n fleet-local将
Bundle的 名称空间 更改为指向fleet-local名称空间。# Example kind: Bundle apiVersion: fleet.cattle.io/v1alpha1 metadata: name: rke2-upgrade namespace: fleet-local ...
将 Bundle 资源应用到您的
management cluster:# For RKE2 kubectl apply -f rke2-plan-bundle.yaml # For K3s kubectl apply -f k3s-plan-bundle.yaml在
fleet-local命名空间下查看创建的 Bundle 资源:# For RKE2 kubectl get bundles rke2-upgrade -n fleet-local # For K3s kubectl get bundles k3s-upgrade -n fleet-local # Example output NAME BUNDLEDEPLOYMENTS-READY STATUS k3s-upgrade 0/0 rke2-upgrade 0/0
32.2.5.4.3 SUC 计划部署 - 第三方 GitOps 工作流 #
在某些情况下,用户可能希望将 Kubernetes upgrade SUC plans 集成到他们自己的第三方 GitOps 工作流中(例如 Flux)。
要获取所需的 K8s 升级资源,请首先确定您想要使用的 suse-edge/fleet-examples 储存库的 Edge release 标签。
之后,可以在以下位置找到这些资源:
针对 RKE2 集群升级:
针对
control-plane节点 -fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-control-plane.yaml针对
worker节点 -fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-worker.yaml
针对 K3s 集群升级:
针对
control-plane节点 -fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-control-plane.yaml针对
worker节点 -fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-worker.yaml
为了更好地了解如何使用您的 GitOps 工作流来部署用于 Kubernetes 版本升级的 SUC Plans,建议查看使用 Fleet 的更新流程的 概览 (第 32.2.5.2 节 “概述”)。
32.2.6 Helm chart 升级 #
本节包含以下部分:
第 32.2.6.1 节 “针对隔离环境的准备工作” - 包含有关如何将 Edge 相关的 OCI chart 和镜像传输到您的私有镜像仓库的信息。
第 32.2.6.2 节 “升级过程” - 包含有关不同 Helm chart 升级用例及其升级过程的信息。
32.2.6.1 针对隔离环境的准备工作 #
32.2.6.1.1 确保您可以访问您的 Helm chart Fleet #
根据您的环境支持情况,您可以选择以下选项之一:
将您的 chart Fleet 资源托管在您的
management cluster可访问的本地 Git 服务器上。使用 Fleet 的 CLI 将 Helm chart 转换为 Bundle,这样您就可以直接使用它,而无需将其托管在其他地方。可以从 Fleet 的 发布 页面获取其 CLI,对于 Mac 用户,有一个 fleet-cli Homebrew 公式。
32.2.6.1.2 查找 Edge 发布版本所需的资产 #
转到“Day 2”发布页面,找到您要将 chart 升级到的 Edge 版本,然后点击 资产。
从 “资产” 部分,下载以下文件:
发布文件
说明
edge-save-images.sh
拉取
edge-release-images.txt文件中指定的镜像,并将它们打包到 '.tar.gz' 归档文件中。edge-save-oci-artefacts.sh
拉取与特定 Edge 版本相关的 OCI chart 镜像,并将它们打包到 '.tar.gz' 归档文件中。
edge-load-images.sh
从 '.tar.gz' 归档文件中加载镜像,重新标记并将其推送到私有镜像仓库。
edge-load-oci-artefacts.sh
获取包含 Edge OCI '.tgz' chart 包的目录,并将它们加载到私有镜像仓库。
edge-release-helm-oci-artefacts.txt
包含与特定 Edge 版本相关的 OCI chart 镜像列表。
edge-release-images.txt
包含与特定 Edge 版本相关的镜像列表。
32.2.6.1.3 创建 Edge 版本镜像归档文件 #
在有互联网连接的机器上:
使
edge-save-images.sh成为一个可执行程序:chmod +x edge-save-images.sh生成镜像归档文件:
./edge-save-images.sh --source-registry registry.suse.com这将创建一个名为
edge-images.tar.gz的待加载归档文件。注意如果指定了
-i|--images选项,归档文件的名称可能会有所不同。将此归档文件复制到您的 隔离的 机器:
scp edge-images.tar.gz <user>@<machine_ip>:/path
32.2.6.1.4 创建 Edge OCI chart 镜像归档文件 #
在有互联网连接的机器上:
使
edge-save-oci-artefacts.sh成为一个可执行程序:chmod +x edge-save-oci-artefacts.sh生成 OCI chart 镜像归档文件:
./edge-save-oci-artefacts.sh --source-registry registry.suse.com这将创建一个名为
oci-artefacts.tar.gz的归档文件。注意如果指定了
-a|--archive选项,归档文件的名称可能会有所不同。将此归档文件复制到您的 隔离的 机器:
scp oci-artefacts.tar.gz <user>@<machine_ip>:/path
32.2.6.1.5 将 Edge 版本镜像加载到您的隔离的机器上 #
在您的隔离的机器上:
登录到您的私有镜像仓库(如果需要):
podman login <REGISTRY.YOURDOMAIN.COM:PORT>使
edge-load-images.sh成为一个可执行程序:chmod +x edge-load-images.sh执行脚本,传入之前 复制 的
edge-images.tar.gz归档文件:./edge-load-images.sh --source-registry registry.suse.com --registry <REGISTRY.YOURDOMAIN.COM:PORT> --images edge-images.tar.gz注意这将从
edge-images.tar.gz加载所有镜像,重新打标签并将其推送到--registry选项下指定的镜像仓库。
32.2.6.1.6 将 Edge OCI chart 镜像加载到您的隔离的机器上 #
在您的隔离的机器上:
登录到您的私有镜像仓库(如果需要):
podman login <REGISTRY.YOURDOMAIN.COM:PORT>使
edge-load-oci-artefacts.sh成为一个可执行程序:chmod +x edge-load-oci-artefacts.sh解包已复制的
oci-artefacts.tar.gz归档文件:tar -xvf oci-artefacts.tar.gz这将生成一个带有命名模板
edge-release-oci-tgz-<date>的目录将此目录传递给
edge-load-oci-artefacts.sh脚本,以将 Edge OCI chart 镜像加载到您的私有镜像仓库:./edge-load-oci-artefacts.sh --archive-directory edge-release-oci-tgz-<date> --registry <REGISTRY.YOURDOMAIN.COM:PORT> --source-registry registry.suse.com
32.2.6.1.7 在您的 Kubernetes 发行版中配置您的私有镜像仓库 #
对于 RKE2,请参阅 Private Registry Configuration
对于 K3s,请参阅 Private Registry Configuration
32.2.6.2 升级过程 #
本节重点介绍以下 Helm 升级过程用例:
手动部署的 Helm charts 无法可靠地升级。我们建议使用 第 32.2.6.2.1 节 “我有一个新集群,想要部署和管理 Edge Helm chart” 方法重新部署 Helm chart。
32.2.6.2.1 我有一个新集群,想要部署和管理 Edge Helm chart #
本节介绍如何:
32.2.6.2.1.1 为您的 chart 准备 fleet 资源 #
从您希望使用的 Edge release 标签中获取该 chart 的 Fleet 资源。
导航至 Helm chart fleet (
fleets/day2/chart-templates/<chart>)如果您打算使用 GitOps 工作流,请将 chart Fleet 目录复制到您将执行 GitOps 的 Git 储存库中。
可选,如果 Helm chart 需要对其 values 进行配置,请编辑已复制目录中
.helm.values文件内的fleet.yaml配置。可选,在某些用例中,您可能需要向 chart 的 fleet 添加额外资源,以便使其更好地适应您的环境。有关如何增强 Fleet 目录的信息,请参阅 Git Repository Contents。
在某些情况下,Fleet 用于 Helm 操作的默认超时时间可能不足,从而导致以下错误:
failed pre-install: context deadline exceeded在这种情况下,请在 fleet.yaml 文件的 helm 配置下添加 timeoutSeconds 属性。
*示例*的`longhorn` Helm chart 看起来如下:
用户 Git 储存库结构:
<user_repository_root> ├── longhorn │ └── fleet.yaml └── longhorn-crd └── fleet.yaml填充了用户
fleet.yaml数据的Longhorn内容:defaultNamespace: longhorn-system helm: # timeoutSeconds: 10 releaseName: "longhorn" chart: "longhorn" repo: "https://charts.rancher.io/" version: "1.11.2" takeOwnership: true # custom chart value overrides values: # Example for user provided custom values content defaultSettings: deletingConfirmationFlag: true # https://fleet.rancher.io/bundle-diffs diff: comparePatches: - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition name: engineimages.longhorn.io operations: - {"op":"remove", "path":"/status/conditions"} - {"op":"remove", "path":"/status/storedVersions"} - {"op":"remove", "path":"/status/acceptedNames"} - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition name: nodes.longhorn.io operations: - {"op":"remove", "path":"/status/conditions"} - {"op":"remove", "path":"/status/storedVersions"} - {"op":"remove", "path":"/status/acceptedNames"} - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition name: volumes.longhorn.io operations: - {"op":"remove", "path":"/status/conditions"} - {"op":"remove", "path":"/status/storedVersions"} - {"op":"remove", "path":"/status/acceptedNames"}注意这些仅是用于说明
longhornchart 自定义配置的示例值。它们 *不*应被视为longhornchart 的部署指南。
32.2.6.2.1.2 为您的 chart 部署 Fleet #
您可以通过使用 GitRepo (第 32.2.6.2.1.2.1 节 “GitRepo”) 或 Bundle (第 32.2.6.2.1.2.2 节 “捆绑包”) 为您的 chart 部署 Fleet。
在部署 Fleet 时,如果您收到 Modified 消息,请确保在 Fleet 的 diff 部分中添加相应的 comparePatches 条目。有关更多信息,请参阅 生成忽略已修改 GitRepo 的差异。
32.2.6.2.1.2.1 GitRepo #
Fleet 的 GitRepo 资源包含有关如何访问您的 chart 的 Fleet 资源以及需要将这些资源应用到哪些集群的信息。
GitRepo 资源可以通过 Rancher UI 部署,也可以通过将资源 部署 到 management cluster 来手动部署。
用于 手动 部署的 Longhorn GitRepo 资源示例:
apiVersion: fleet.cattle.io/v1alpha1
kind: GitRepo
metadata:
name: longhorn-git-repo
namespace: fleet-local
spec:
# If using a tag
# revision: user_repository_tag
#
# If using a branch
# branch: user_repository_branch
paths:
# As seen in the 'Prepare your Fleet resources' example
- longhorn
- longhorn-crd
repo: user_repository_url32.2.6.2.1.2.2 捆绑包 #
Bundle 资源包含需要由 Fleet 部署的原始 Kubernetes 资源。通常建议使用 GitRepo 方法,但对于环境处于隔离状态且无法支持本地 Git 服务器的用例,Bundles 可以帮助您将 Helm chart Fleet 传播到目标集群。
Bundle 可以通过 Rancher UI (Continuous Delivery → Advanced → Bundles → Create from YAML) 部署,也可以通过在正确的 Fleet 名称空间中手动部署 Bundle 资源来部署。有关 Fleet 名称空间的信息,请参阅上游 文档。
可以通过利用 Fleet 的 将 Helm Chart 转换为 Bundle 方法来创建用于 Edge Helm chart 的 Bundles。
您可以在下方找到关于如何从 longhorn 和 longhorn-crd Helm chart fleet 模板创建 Bundle 资源,并将此 bundle 手动部署到您的 management cluster 的示例。
导航到 longhorn Chart fleet 模板:
cd fleets/day2/chart-templates/longhorn/longhorn创建一个
targets.yaml文件,用于指示 Fleet 应将 Helm chart 部署到哪些集群:cat > targets.yaml <<EOF targets: # Match your local (management) cluster - clusterName: local EOF注意在某些用例中,您的本地群集可能具有不同的名称。
要检索您的本地群集名称,请执行以下命令:
kubectl get clusters.fleet.cattle.io -n fleet-local使用 fleet-cli 将
LonghornHelm chart Fleet 转换为 Bundle 资源。fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - longhorn-bundle > longhorn-bundle.yaml导航到 longhorn-crd Chart fleet 模板:
cd fleets/day2/chart-templates/longhorn/longhorn-crd创建一个
targets.yaml文件,用于指示 Fleet 应将 Helm chart 部署到哪些集群:cat > targets.yaml <<EOF targets: # Match your local (management) cluster - clusterName: local EOF使用 fleet-cli 将
Longhorn CRDHelm chart Fleet 转换为 Bundle 资源。fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - longhorn-crd-bundle > longhorn-crd-bundle.yaml将
longhorn-bundle.yaml和longhorn-crd-bundle.yaml文件部署到您的management cluster:kubectl apply -f longhorn-crd-bundle.yaml kubectl apply -f longhorn-bundle.yaml
遵循这些步骤将确保 SUSE Storage 被部署到所有指定的 management 集群上。
32.2.6.2.1.3 管理已部署的 Helm chart #
使用 Fleet 部署后,有关 Helm chart 升级的信息,请参阅 第 32.2.6.2.2 节 “我想升级一个由 Fleet 管理的 Helm chart”。
32.2.6.2.2 我想升级一个由 Fleet 管理的 Helm chart #
确定您需要将 chart 升级到的版本,以便其与所需的 Edge 版本兼容。每个 Edge 版本的 Helm chart 版本可以在 发行说明 (第 41 章 “发行说明”) 中查看。
在您由 Fleet 监控的 Git 储存库中,使用 发行说明 (第 41 章 “发行说明”) 中的正确 chart 版本 和 储存库 编辑 Helm chart 的
fleet.yaml文件。提交并推送更改到您的储存库后,这将触发所需 Helm chart 的升级
32.2.6.2.3 我想升级一个通过 EIB 部署的 Helm chart #
第 8 章 “Edge Image Builder” 通过创建 HelmChart 资源并利用 RKE2/K3s Helm 集成功能引入的 helm-controller 来部署 Helm chart。
为确保通过 EIB 部署的 Helm chart 成功升级,用户需要对相应的 HelmChart 资源进行升级。
您可以在下方找到以下信息:
升级过程的常规概述 (第 32.2.6.2.3.1 节 “概述”)。
必要的升级步骤 (第 32.2.6.2.3.2 节 “升级步骤”)。
一个示例 (第 32.2.6.2.3.3 节 “示例”),展示了使用所解释的方法进行Longhorn chart 升级。
如何将升级过程与不同的 GitOps 工具 (第 32.2.6.2.3.4 节 “使用第三方 GitOps 工具进行 Helm chart 升级”)结合使用。
32.2.6.2.3.1 概述 #
通过`EIB`部署的 Helm charts 将通过一个名为eib-charts-upgrader的`fleet`进行升级。
此`fleet`处理*用户提供*的数据,以*更新*特定的一组 HelmChart 资源。
更新这些资源会触发helm-controller,它会*升级*与修改后的`HelmChart`资源相关联的 Helm charts。
用户仅需:
在本地拉取需要升级的每个 Helm chart 的归档文件。
将这些归档文件传递给generate-chart-upgrade-data.sh
generate-chart-upgrade-data.sh`脚本,该脚本会将这些归档文件中的数据包含到`eib-charts-upgraderfleet 中。将`eib-charts-upgrader` fleet 部署到其`management cluster`。这可以通过`GitRepo`或`Bundle`资源来完成。
部署完成后,`eib-charts-upgrader`将在 Fleet 的帮助下,将其资源发送到目标management集群。
这些资源包括:
一组`Secrets`,其中包含*用户提供*的 Helm chart 数据。
一个`Kubernetes Job`,它将部署一个`Pod`,该组件将挂载前面提到的`Secrets`,并据此对相应的 HelmChart 资源应用补丁。
如前所述,这将触发`helm-controller`,它将执行实际的 Helm chart 升级。
您可以在下方找到上述描述的图示:
32.2.6.2.3.2 升级步骤 #
从正确的发布标签克隆`suse-edge/fleet-examples`储存库。
创建一个目录,用于存储拉取的 Helm chart 归档文件。
mkdir archives在新建的归档目录中,拉取您希望升级的 Helm chart 的归档文件:
cd archives helm pull [chart URL | repo/chartname] # Alternatively if you want to pull a specific version: # helm pull [chart URL | repo/chartname] --version 0.0.0从所需 发布标签 的 资产 中,下载
generate-chart-upgrade-data.sh脚本。执行
generate-chart-upgrade-data.sh脚本:chmod +x ./generate-chart-upgrade-data.sh ./generate-chart-upgrade-data.sh --archive-dir /foo/bar/archives/ --fleet-path /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader对于
--archive-dir目录中的每个 chart 归档文件,该脚本都会生成一个包含 chart 升级数据的Kubernetes Secret YAML文件,并将其存储在由--fleet-path指定的 fleet 的base/secrets目录中。generate-chart-upgrade-data.sh脚本还会对 fleet 进行额外的修改,以确保生成的Kubernetes Secret YAML文件能被 fleet 部署的工作负载正确使用。重要用户不应在
generate-chart-upgrade-data.sh脚本生成的内容之上进行任何更改。
以下步骤取决于您运行的环境:
对于支持 GitOps 的环境(例如:非隔离的,或隔离的但允许本地 Git 服务器支持):
将
fleets/day2/eib-charts-upgraderFleet 复制到您将用于 GitOps 的储存库中。注意确保 Fleet 包含由
generate-chart-upgrade-data.sh脚本所做的更改。配置一个
GitRepo资源,该资源将用于交付eib-charts-upgraderFleet 的所有资源。有关通过 Rancher UI 进行
GitRepo配置和部署的信息,请参阅 在 Rancher UI 中访问 Fleet。有关
GitRepo手动配置和部署的信息,请参阅 创建部署。
对于不支持 GitOps 的环境(例如:为隔离的且不允许使用本地 Git 服务器):
从`rancher/fleet`release 页面下载
fleet-cli二进制文件(适用于fleet-linux-amd64的 Linux)。对于 Mac 用户,可以使用 Homebrew 配方 - fleet-cli。导航至
eib-charts-upgraderFleet:cd /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader创建一个
targets.yaml文件,用于指示 Fleet 在何处部署您的资源:cat > targets.yaml <<EOF targets: # To map the local(management) cluster - clusterName: local EOF注意在某些适用场景中,您的
local集群可能具有不同的名称。要检索您的
local集群名称,请执行以下命令:kubectl get clusters.fleet.cattle.io -n fleet-local使用
fleet-cli将 Fleet 转换为Bundle资源:fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - eib-charts-upgrade > bundle.yaml这将创建一个 Bundle (
bundle.yaml),其中将包含来自eib-charts-upgraderFleet 的所有模板化资源。有关
fleet apply命令的更多信息,请参阅 fleet apply。有关将 Fleet 转换为 Bundle 的更多信息,请参阅 将 Helm Chart 转换为 Bundle。
部署
Bundle。可以通过以下两种方式之一完成此操作:通过 Rancher UI - 导航到 持续交付 → 高级 → Bundles → 从 YAML 创建,然后粘贴
bundle.yaml内容,或者点击Read from File选项并传入文件本身。手动 - 在您的
management cluster中手动部署bundle.yaml文件。
执行这些步骤将成功部署 GitRepo/Bundle 资源。该资源将被 Fleet 获取,其内容将部署到用户在先前步骤中指定的目标集群上。有关该过程的概述,请参阅 第 32.2.6.2.3.1 节 “概述”。
有关如何跟踪升级过程的信息,您可以参阅 第 32.2.6.2.3.3 节 “示例”。
一旦成功验证了 Chart 升级,请删除 Bundle/GitRepo 资源。
这将从您的 management 集群中删除不再需要的升级资源,以确保不会发生未来的版本冲突。
32.2.6.2.3.3 示例 #
下面的示例演示了如何在 management 集群上将通过 EIB 部署的 Helm Chart 从一个版本升级到另一个版本。请注意,此示例中使用的版本 不是 建议版本。有关特定于 Edge 版本的版本建议,请参阅 发行说明 (第 41 章 “发行说明”)。
适用场景:
一个
management集群正在运行 Longhorn 的旧版本。该集群已通过 EIB 部署,使用了以下镜像定义 snippet:
kubernetes: helm: charts: - name: longhorn-crd repositoryName: rancher-charts targetNamespace: longhorn-system createNamespace: true version: 104.2.0+up1.7.1 installationNamespace: kube-system - name: longhorn repositoryName: rancher-charts targetNamespace: longhorn-system createNamespace: true version: 104.2.0+up1.7.1 installationNamespace: kube-system repositories: - name: rancher-charts url: https://charts.rancher.io/ ...SUSE Storage需要升级到与 Edge 3.6 版本兼容的版本。这意味着它需要升级到1.11.2。假设
management cluster是 隔离的,不支持本地 Git 服务器,并且拥有正常运行的 Rancher 设置。
遵循 升级步骤 (第 32.2.6.2.3.2 节 “升级步骤”):
从
release-3.6.1标签克隆suse-edge/fleet-example储存库。git clone -b release-3.6.1 https://github.com/suse-edge/fleet-examples.git创建一个目录,用于存储
Longhorn升级归档文件。mkdir archives拉取所需的
Longhornchart 归档版本:# First add the Rancher Helm chart repository helm repo add rancher-charts https://charts.rancher.io/ # Pull the Longhorn 1.11.2 chart archive helm pull oci://dp.apps.rancher.io/charts/suse-storage --version 1.11.2在
archives目录之外,从suse-edge/fleet-examples版本 tag 下载generate-chart-upgrade-data.sh脚本。目录设置应如下所示:
. ├── archives │ └── longhorn-1.11.2.tgz ├── fleet-examples ... │ ├── fleets │ │ ├── day2 | | | ├── ... │ │ │ ├── eib-charts-upgrader │ │ │ │ ├── base │ │ │ │ │ ├── job.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── patches │ │ │ │ │ │ └── job-patch.yaml │ │ │ │ │ ├── rbac │ │ │ │ │ │ ├── cluster-role-binding.yaml │ │ │ │ │ │ ├── cluster-role.yaml │ │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ │ └── sa.yaml │ │ │ │ │ └── secrets │ │ │ │ │ ├── eib-charts-upgrader-script.yaml │ │ │ │ │ └── kustomization.yaml │ │ │ │ ├── fleet.yaml │ │ │ │ └── kustomization.yaml │ │ │ └── ... │ └── ... └── generate-chart-upgrade-data.sh执行
generate-chart-upgrade-data.sh脚本:# First make the script executable chmod +x ./generate-chart-upgrade-data.sh # Then execute the script ./generate-chart-upgrade-data.sh --archive-dir ./archives --fleet-path ./fleet-examples/fleets/day2/eib-charts-upgrader脚本执行后的目录结构应如下所示:
. ├── archives │ └── longhorn-1.11.2.tgz ├── fleet-examples ... │ ├── fleets │ │ ├── day2 │ │ │ ├── ... │ │ │ ├── eib-charts-upgrader │ │ │ │ ├── base │ │ │ │ │ ├── job.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── patches │ │ │ │ │ │ └── job-patch.yaml │ │ │ │ │ ├── rbac │ │ │ │ │ │ ├── cluster-role-binding.yaml │ │ │ │ │ │ ├── cluster-role.yaml │ │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ │ └── sa.yaml │ │ │ │ │ └── secrets │ │ │ │ │ ├── eib-charts-upgrader-script.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── longhorn-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script │ │ │ │ │ └── longhorn-crd-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script │ │ │ │ ├── fleet.yaml │ │ │ │ └── kustomization.yaml │ │ │ └── ... │ └── ... └── generate-chart-upgrade-data.shgit 中更改的文件应如下所示:
Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: fleets/day2/eib-charts-upgrader/base/patches/job-patch.yaml modified: fleets/day2/eib-charts-upgrader/base/secrets/kustomization.yaml Untracked files: (use "git add <file>..." to include in what will be committed) fleets/day2/eib-charts-upgrader/base/secrets/longhorn-VERSION.yaml fleets/day2/eib-charts-upgrader/base/secrets/longhorn-crd-VERSION.yaml为
eib-charts-upgraderFleet 创建一个Bundle:首先,导航到 Fleet 本身:
cd ./fleet-examples/fleets/day2/eib-charts-upgrader然后创建一个
targets.yaml文件:cat > targets.yaml <<EOF targets: - clusterName: local EOF然后使用
fleet-cli二进制文件将 Fleet 转换为 Bundle:fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - eib-charts-upgrade > bundle.yaml
通过 Rancher UI 部署 Bundle:
图 32.1︰ 通过 Rancher UI 部署 Bundle #在此处,选择 从文件读取 并在您的系统上找到
bundle.yaml文件。这将自动填充 Rancher UI 中的
Bundle。选择 创建。
部署成功后,您的 Bundle 应如下所示:
图 32.2︰ Bundle 部署成功 #
Bundle 成功部署后,要监控升级过程:
验证
Upgrade Pod的日志:现在,验证由 helm-controller 为升级创建的 Pod 的日志:
Pod 名称将遵循以下模板 -
helm-install-longhorn-<random-suffix>Pod 将位于部署了
HelmChart资源的名称空间中。在我们的案例中,这是kube-system。图 32.3︰ 成功升级 Longhorn chart 的日志 #
通过导航到 Rancher 的
HelmCharts部分 (More Resources → HelmCharts),验证HelmChart版本是否已更新。选择部署 chart 的名称空间,在此示例中为kube-system。最后,检查 Longhorn Pod 是否正在运行。
完成上述验证后,可以确信 Longhorn Helm chart 已升级到 1.11.2 版本。
32.2.6.2.3.4 使用第三方 GitOps 工具进行 Helm chart 升级 #
在某些用例中,用户可能希望将此升级过程与 Fleet 以外的 GitOps 工作流(例如 Flux)结合使用。
为生成升级过程所需的资源,您可以使用 generate-chart-upgrade-data.sh 脚本将用户提供的数据填充到 eib-charts-upgrader Fleet 中。有关如何操作的详细信息,请参见 第 32.2.6.2.3.2 节 “升级步骤”。
完成完整设置后,您可以使用 kustomize 生成一个可在集群中部署的完整工作解决方案:
cd /foo/bar/fleets/day2/eib-charts-upgrader
kustomize build .如果您希望将该解决方案包含在 GitOps 工作流中,可以去除 fleet.yaml 文件,并将剩余部分用作有效的 Kustomize 设置。请务必先运行 generate-chart-upgrade-data.sh 脚本,以便其使用您希望升级到的 Helm chart 所需的数据来填充 Kustomize 设置。
要了解此工作流的预期用途,查看 第 32.2.6.2.3.1 节 “概述” 和 第 32.2.6.2.3.2 节 “升级步骤” 会有所帮助。
33 下游集群 #
本节介绍了对您的 downstream 集群的不同部分执行“第 2 天”操作的可能方法。
33.1 Fleet #
本节提供有关如何使用 Fleet (第 6 章 “Fleet”) 组件执行“第 2 天”操作的信息。
本节涵盖以下主题:
第 33.1.1 节 “组件” - 用于所有“第 2 天”操作的默认组件。
第 33.1.2 节 “确定您的用例” - 提供将要使用的 Fleet 自定义资源概述,以及它们对不同“第 2 天”操作用例的适用性。
第 33.1.3 节 “Day 2 工作流” - 提供使用 Fleet 执行“第 2 天”操作的工作流程指南。
第 33.1.4 节 “操作系统升级” - 描述如何使用 Fleet 进行操作系统升级。
第 33.1.5 节 “Kubernetes 版本升级” - 描述如何使用 Fleet 进行 Kubernetes 版本升级。
第 33.1.6 节 “Helm chart 升级” - 描述如何使用 Fleet 进行 Helm chart 升级。
33.1.1 组件 #
您可以在下方找到应在您的 downstream 集群上设置的默认组件说明,以便您能够使用 Fleet 成功执行“第 2 天”操作。
33.1.1.1 系统升级控制器 (SUC) #
*必须*部署在每个下游集群上。
*系统升级控制器*负责根据通过名为 Plan 的自定义资源提供配置数据,在指定节点上执行任务。
*SUC*被主动用于升级操作系统和 Kubernetes 发行版。
有关 SUC 组件及其如何适配 Edge 堆栈的更多信息,请参阅 第 18 章 “系统升级控制器”。
有关如何部署 SUC 的信息,请先 确定您的用例 (第 33.1.2 节 “确定您的用例”),然后参考 系统升级控制器安装 - GitRepo (第 18.2.1.1 节 “System Upgrade Controller 安装 - GitRepo”) 或 系统升级控制器安装 - Bundle (第 18.2.1.2 节 “系统升级控制器安装 - Bundle”)。
33.1.2 确定您的用例 #
Fleet 使用两种类型的 自定义资源 来实现 Kubernetes 和 Helm 资源的管理。
您可以在下方找到有关这些资源的目的以及它们在“第 2 天”操作背景下最适合的用例的信息。
33.1.2.1 GitRepo #
GitRepo 是一个 Fleet (第 6 章 “Fleet”) 资源,它代表一个 Fleet 可以从中创建 Bundles 的 Git 储存库。每个 Bundle 都是基于 GitRepo 资源内定义的配置路径创建的。有关详细信息,请参见 GitRepo 文档。
在“Day 2”操作的背景下,GitRepo 资源通常用于在利用 Fleet GitOps 方法的 非隔离的 环境中部署 SUC 或 SUC Plans。
或者,GitRepo 资源也可用于在 隔离的 环境中部署 SUC 或 SUC Plans,前提是您通过本地 git 服务器镜像您的储存库设置。
33.1.2.2 捆绑包 #
Bundles 包含将部署在目标集群上的 原始 Kubernetes 资源。通常它们是从 GitRepo 资源创建的,但在某些用例中也可以手动部署它们。有关详细信息,请参考 Bundle 文档。
在“Day 2”操作的背景下,Bundle 资源通常用于在不使用某种 本地 GitOps 流程(例如 本地 git 服务器)的 隔离的 环境中部署 SUC 或 SUC Plans。
或者,如果您的用例不允许 GitOps 工作流(例如使用 Git 储存库),则 Bundle 资源也可用于在 非隔离的 环境中部署 SUC 或 SUC Plans。
33.1.3 Day 2 工作流 #
以下是升级 downstream 集群到特定 Edge 版本时应遵循的“Day 2”工作流。
操作系统升级 (第 33.1.4 节 “操作系统升级”)
Kubernetes 版本升级 (第 33.1.5 节 “Kubernetes 版本升级”)
Helm chart 升级 (第 33.1.6 节 “Helm chart 升级”)
33.1.4 操作系统升级 #
本节介绍如何使用 第 6 章 “Fleet” 和 第 18 章 “系统升级控制器” 执行操作系统升级。
本节涵盖以下主题:
第 33.1.4.1 节 “组件” - 升级过程中使用的附加组件。
第 33.1.4.2 节 “概述” - 升级过程概述。
第 33.1.4.3 节 “要求” - 升级过程的要求。
第 33.1.4.4 节 “操作系统升级 - SUC 计划部署” - 有关如何部署负责触发升级过程的
SUC plans的信息。
33.1.4.1 组件 #
本节涵盖 OS upgrade 过程在默认“第 2 天”组件 (第 33.1.1 节 “组件”) 之外使用的自定义组件。
33.1.4.1.1 systemd.service #
特定节点上的操作系统升级由 systemd.service 处理。
根据操作系统从一个 Edge 版本升级到另一个版本所需的升级类型,会创建不同的服务:
上述服务通过 SUC plan 在每个节点上部署,该服务必须位于需要操作系统升级的 downstream 集群上。
33.1.4.2 概述 #
downstream 集群节点的操作系统升级是通过利用 Fleet 和 System Upgrade Controller (SUC) 完成的。
Fleet 用于在目标集群上部署和管理 SUC plans。
OS SUC plans 通过将 GitRepo 或 Bundle 资源部署到特定的 Fleet 工作区 来分发到每个集群。Fleet 会检索已部署的 GitRepo/Bundle 并将其内容(即 OS SUC plans)部署到目标集群。
GitRepo/Bundle 资源始终部署在 management cluster 上。是否使用 GitRepo 或 Bundle 资源取决于您的用例,请查看 第 33.1.2 节 “确定您的用例” 以获取更多信息。
OS SUC plans 描述了以下工作流程:
在操作系统升级之前,请务必 隔离 节点。
请务必先升级
control-plane节点,然后再升级worker节点。请务必一次只升级一个 one 节点。
一旦部署了 OS SUC plans,工作流程如下所示:
SUC 会协调已部署的
OS SUC plans并在 每个节点 上创建一个Kubernetes Job。Kubernetes Job会为软件包升级或操作系统迁移创建一个 systemd.service (第 33.1.4.1.1 节 “systemd.service”)。所创建的
systemd.service会触发特定节点上的操作系统升级过程。重要一旦操作系统升级过程完成,相应的节点将被
rebooted以应用系统更新。
您可以在下方找到上述描述的图示:
33.1.4.3 要求 #
常规:
SCC 注册机器 - 所有 downstream 集群节点都应注册到
https://scc.suse.com/,这是使相应的systemd.service能够成功连接到所需 RPM 储存库所必需的。重要对于需要操作系统版本迁移的 Edge 版本(例如
6.1→6.2),请确保您的 SCC 密钥支持迁移到新版本。确保 SUC Plan 容忍度与节点容忍度匹配 - 如果您的 Kubernetes 集群节点具有自定义 污点,请确保在 SUC Plans 中为这些污点添加 容忍度。默认情况下,SUC Plans 仅具有针对 控制平面 节点的容忍度。默认容忍度包括:
CriticalAddonsOnly=true:NoExecute
node-role.kubernetes.io/control-plane:NoSchedule
node-role.kubernetes.io/etcd:NoExecute
注意任何额外的容忍度必须添加到每个计划的
.spec.tolerations部分下。与操作系统升级相关的*SUC 计划*可以在`fleets/day2/system-upgrade-controller-plans/os-upgrade`下的suse-edge/fleet-examples储存库中找到。确保您使用来自有效存储库发布标签的计划。为*控制平面* SUC 计划定义自定义容忍度的示例如下:
apiVersion: upgrade.cattle.io/v1 kind: Plan metadata: name: os-upgrade-control-plane spec: ... tolerations: # default tolerations - key: "CriticalAddonsOnly" operator: "Equal" value: "true" effect: "NoExecute" - key: "node-role.kubernetes.io/control-plane" operator: "Equal" effect: "NoSchedule" - key: "node-role.kubernetes.io/etcd" operator: "Equal" effect: "NoExecute" # custom toleration - key: "foo" operator: "Equal" value: "bar" effect: "NoSchedule" ...
隔离的:
33.1.4.4 操作系统升级 - SUC 计划部署 #
对于之前使用此过程升级过的环境,用户应确保完成以下其中*一*步骤:
这样做是为了避免旧版 Edge 发行版本之间的`SUC Plans`冲突。
如果用户在 downstream 集群上存在现有的 SUC Plans 时尝试升级,他们将看到以下 fleet 错误:
Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..如 第 33.1.4.2 节 “概述” 中所述,操作系统升级是通过以下方式之一将 SUC plans 部署到目标集群来完成的:
Fleet
GitRepo资源 - 第 33.1.4.4.1 节 “SUC 计划部署 - GitRepo 资源”。Fleet
Bundle资源 - 第 33.1.4.4.2 节 “SUC 计划部署 - Bundle 资源”。
要确定应使用哪种资源,请参阅第 33.1.2 节 “确定您的用例”。
对于希望从第三方 GitOps 工具部署`OS SUC plans`的用例,请参阅第 33.1.4.4.3 节 “SUC 计划部署 - 第三方 GitOps 工作流”
33.1.4.4.1 SUC 计划部署 - GitRepo 资源 #
可以采用以下方式之一部署包含所需`OS SUC plans`的*GitRepo*资源:
通过
Rancher UI- 第 33.1.4.4.1.1 节 “GitRepo 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 33.1.4.4.1.2 节 “GitRepo 创建 - 手动”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的操作系统升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
33.1.4.4.1.1 GitRepo 创建 - Rancher UI #
要通过 Rancher UI 创建 GitRepo 资源,请遵循其官方 文档。
Edge 团队维护着一个可直接使用的 Fleet。根据您的环境,此 Fleet 可以直接使用或作为模板使用。
对于不需要对 Fleet 附带的 SUC plans 进行任何自定义更改的用例,用户可以直接引用来自 suse-edge/fleet-examples 储存库的 os-upgrade Fleet。
如果需要自定义更改(例如添加自定义容忍度),用户应引用来自单独储存库的 os-upgrade Fleet,以便根据需要将更改添加到 SUC 计划中。
关于如何配置 GitRepo 以使用来自 suse-edge/fleet-examples 储存库的 Fleet 的示例,可以在 此处 查看。
33.1.4.4.1.2 GitRepo 创建 - 手动 #
拉取 GitRepo 资源:
curl -o os-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/gitrepos/day2/os-upgrade-gitrepo.yaml编辑 GitRepo 配置,在
spec.targets下指定您所需的目标列表。默认情况下,来自suse-edge/fleet-examples的GitRepo资源 不会 映射到任何下游集群。要匹配所有集群,请将默认
GitRepo目标 更改为:spec: targets: - clusterSelector: {}或者,如果您需要更细粒度的集群选择,请参阅 映射到下游集群
应用 GitRepo 资源到您的
management cluster:kubectl apply -f os-upgrade-gitrepo.yaml在
fleet-default名称空间下查看已创建的 GitRepo 资源:kubectl get gitrepo os-upgrade -n fleet-default # Example output NAME REPO COMMIT BUNDLEDEPLOYMENTS-READY STATUS os-upgrade https://github.com/suse-edge/fleet-examples.git release-3.6.1 0/0
33.1.4.4.2 SUC 计划部署 - Bundle 资源 #
一个 Bundle 资源(用于交付所需的 OS SUC Plans)可以通过以下方式之一进行部署:
通过
Rancher UI- 第 33.1.4.4.2.1 节 “Bundle 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 33.1.4.4.2.2 节 “Bundle 创建 - 手动”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的操作系统升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
33.1.4.4.2.1 Bundle 创建 - Rancher UI #
Edge 团队维护了一个可直接使用的 bundle,可用于以下步骤。
通过 Rancher UI 创建 bundle:
在左上角,点击 ☰ → 持续交付
转到 高级 > Bundles
选择 从 YAML 创建
在此处,您可以通过以下方式之一创建 Bundle:
注意在某些用例中,您可能需要将自定义更改包含到 bundle 所交付的
SUC plans中(例如,添加自定义容忍度)。请确保将这些更改包含在通过以下步骤生成的 bundle 中。通过手动将 bundle 内容 从
suse-edge/fleet-examples复制到 从 YAML 创建 页面。通过从所需的 发布 标签克隆 suse-edge/fleet-examples 储存库,并在 从 YAML 创建 页面中选择 从文件读取 选项。从那里,导航到 bundle 位置 (
bundles/day2/system-upgrade-controller-plans/os-upgrade) 并选择 bundle 文件。这将自动填充 从 YAML 创建 页面中的 bundle 内容。
更改
Bundle的 目标 集群:要匹配所有下游集群,请将默认 Bundle
.spec.targets更改为:spec: targets: - clusterSelector: {}有关更细粒度的下游集群映射,请参阅 映射到下游集群。
选择 创建
33.1.4.4.2.2 Bundle 创建 - 手动 #
拉取 Bundle 资源:
curl -o os-upgrade-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/bundles/day2/system-upgrade-controller-plans/os-upgrade/os-upgrade-bundle.yaml编辑
Bundle目标 配置,在spec.targets下提供您所需的目标列表。默认情况下,来自suse-edge/fleet-examples的Bundle资源 不 映射到任何下游集群。要匹配所有集群,请将默认
Bundle目标 更改为:spec: targets: - clusterSelector: {}或者,如果您需要更细粒度的集群选择,请参阅 映射到下游集群
将 Bundle 资源应用到您的
management cluster:kubectl apply -f os-upgrade-bundle.yaml在
fleet-default名称空间下查看已创建的 Bundle 资源:kubectl get bundles -n fleet-default
33.1.4.4.3 SUC 计划部署 - 第三方 GitOps 工作流 #
在某些用例中,用户可能希望将 OS SUC plans 集成到他们自己的第三方 GitOps 工作流(例如 Flux)中。
要获取所需的操作系统升级资源,请首先确定您想要使用的 suse-edge/fleet-examples 储存库的 Edge 发布 标签。
之后,可以在 fleets/day2/system-upgrade-controller-plans/os-upgrade 处找到资源,其中:
plan-control-plane.yaml是用于 控制平面 节点的 SUC 计划资源。plan-worker.yaml是用于 工作节点 的 SUC 计划资源。secret.yaml是一个包含upgrade.sh脚本的 Secret,该脚本负责创建 systemd.service (第 33.1.4.1.1 节 “systemd.service”)。config-map.yaml是一个 ConfigMap,其中保存了供upgrade.sh脚本使用的配置。
这些 Plan 资源由 System Upgrade Controller 进行解释,并应部署在您希望升级的每个下游集群上。有关 SUC 部署信息,请参见 第 18.2 节 “安装系统升级控制器”。
为了更好地了解如何使用 GitOps 工作流来部署用于操作系统升级的 SUC Plans,查看 overview (第 33.1.4.2 节 “概述”) 会有所帮助。
33.1.5 Kubernetes 版本升级 #
本节涵盖了 未通过 Rancher (第 4 章 “Rancher”) 实例创建的下游集群的 Kubernetes 升级。有关如何升级 Rancher 创建的集群的 Kubernetes 版本的信息,请参阅 升级和回滚 Kubernetes。
本节介绍了如何使用 第 6 章 “Fleet” 和 第 18 章 “系统升级控制器” 执行 Kubernetes 升级。
本节涵盖以下主题:
第 33.1.5.1 节 “组件” - 升级过程中使用的其他组件。
第 33.1.5.2 节 “概述” - 升级过程概述。
第 33.1.5.3 节 “要求” - 升级过程的要求。
第 33.1.5.4 节 “K8s 升级 - SUC 计划部署” - 有关如何部署
SUC plans的信息,它负责触发升级过程。
33.1.5.1 组件 #
本节涵盖了 K8s upgrade 过程在默认“Day 2”组件 (第 33.1.1 节 “组件”)之外使用的自定义组件。
33.1.5.1.1 rke2-upgrade #
负责升级特定节点 RKE2 版本的容器镜像。
通过 SUC 基于 SUC 计划 创建的 Pod 进行分发。该计划应位于每个需要 RKE2 升级的 集群 上。
有关 rke2-upgrade 镜像如何执行升级的更多信息,请参阅 上游 文档。
33.1.5.1.2 k3s-upgrade #
负责升级特定节点 K3s 版本的容器镜像。
通过 SUC 基于 SUC 计划 创建的 Pod 进行分发。该计划应位于每个需要 K3s 升级的 集群 上。
有关 k3s-upgrade 镜像如何执行升级的更多信息,请参阅 上游 文档。
33.1.5.2 概述 #
downstream 集群节点的 Kubernetes 发行版升级是通过利用 Fleet 和 System Upgrade Controller (SUC) 完成的。
Fleet 用于将 SUC plans 部署并管理到目标集群上。
K8s SUC plans 通过将 GitRepo 或 Bundle 资源部署到特定的 Fleet 工作区,从而在每个集群上进行交付。Fleet 获取已部署的 GitRepo/Bundle 并将其内容(即 K8s SUC plans)部署到一个或多个目标集群。
GitRepo/Bundle 资源始终部署在 management cluster 上。是使用 GitRepo 还是 Bundle 资源取决于您的用例,请查看 第 33.1.2 节 “确定您的用例” 以获取更多信息。
K8s SUC plans 描述了以下工作流程:
在 K8s 升级之前,请务必 隔离 节点。
请务必先升级
control-plane节点,然后再升级worker节点。请务必每次升级
control-plane节点中的 一个 节点,以及worker节点中的 两个 节点。
一旦部署了 K8s SUC plans,工作流程如下所示:
SUC 会协调已部署的
K8s SUC plans并在 每个节点 上创建一个Kubernetes Job。根据 Kubernetes 发行版的不同,该 Job 将创建一个运行 rke2-upgrade (第 33.1.5.1.1 节 “rke2-upgrade”) 或 k3s-upgrade (第 33.1.5.1.2 节 “k3s-upgrade”) 容器镜像的 Pod。
创建的 Pod 将经历以下工作流程:
将节点上现有的
rke2/k3s二进制文件替换为来自rke2-upgrade/k3s-upgrade镜像的文件。终止正在运行的
rke2/k3s进程。
终止
rke2/k3s进程会触发重启,启动一个运行更新后二进制文件的新进程,从而实现 Kubernetes 发行版版本的升级。
您可以在下方找到上述描述的图示:
33.1.5.3 要求 #
备份您的 Kubernetes 发行版:
对于 RKE2 集群,请参阅 RKE2 备份与恢复 文档。
对于 K3s 集群,请参阅 K3s 备份与恢复 文档。
确保 SUC Plan 容忍度与节点容忍度匹配 - 如果您的 Kubernetes 集群节点具有自定义 污点,请确保在 SUC Plans 中为这些污点添加 容忍度。默认情况下,SUC Plans 仅包含针对 控制平面 节点的容忍度。默认容忍度包括:
CriticalAddonsOnly=true:NoExecute
node-role.kubernetes.io/control-plane:NoSchedule
node-role.kubernetes.io/etcd:NoExecute
注意任何额外的容忍度必须添加到每个 Plan 的
.spec.tolerations部分下。与 Kubernetes 版本升级相关的 SUC Plans 可以在 suse-edge/fleet-examples 储存库的以下位置找到:对于 RKE2 -
fleets/day2/system-upgrade-controller-plans/rke2-upgrade对于 K3s -
fleets/day2/system-upgrade-controller-plans/k3s-upgrade
请确保您使用的是来自有效储存库 发布 标签的 Plans。
为 RKE2 控制平面 SUC Plan 定义自定义容忍度的示例如下:
apiVersion: upgrade.cattle.io/v1 kind: Plan metadata: name: rke2-upgrade-control-plane spec: ... tolerations: # default tolerations - key: "CriticalAddonsOnly" operator: "Equal" value: "true" effect: "NoExecute" - key: "node-role.kubernetes.io/control-plane" operator: "Equal" effect: "NoSchedule" - key: "node-role.kubernetes.io/etcd" operator: "Equal" effect: "NoExecute" # custom toleration - key: "foo" operator: "Equal" value: "bar" effect: "NoSchedule" ...
33.1.5.4 K8s 升级 - SUC 计划部署 #
对于之前使用此过程升级过的环境,用户应确保完成以下 一项 步骤:
这样做是为了避免旧版 Edge 发行版本之间的 SUC Plans 冲突。
如果用户在 downstream 集群上存在现有 SUC Plans 的情况下尝试升级,他们将看到以下 fleet 错误:
Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..如 第 33.1.5.2 节 “概述” 中所述,Kubernetes 升级是通过以下方式之一将 SUC plans 发送到目标集群来完成的:
Fleet GitRepo 资源 (第 33.1.5.4.1 节 “SUC 计划部署 - GitRepo 资源”)
Fleet Bundle 资源 (第 33.1.5.4.2 节 “SUC 计划部署 - Bundle 资源”)
要确定应使用哪种资源,请参阅 第 33.1.2 节 “确定您的用例”。
对于希望从第三方 GitOps 工具部署 K8s SUC plans 的用例,请参阅 第 33.1.5.4.3 节 “SUC 计划部署 - 第三方 GitOps 工作流”
33.1.5.4.1 SUC 计划部署 - GitRepo 资源 #
所需 K8s SUC plans 的 GitRepo 资源可通过以下方式之一进行部署:
通过
Rancher UI- 第 33.1.5.4.1.1 节 “GitRepo 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 33.1.5.4.1.2 节 “GitRepo 创建 - 手动”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的 Kubernetes 升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
33.1.5.4.1.1 GitRepo 创建 - Rancher UI #
要通过 Rancher UI 创建 GitRepo 资源,请遵循其官方 文档。
Edge 团队维护着适用于 rke2 和 k3s Kubernetes 发行版的现成 fleet。根据您的环境,此 fleet 可以直接使用或作为模板使用。
对于不需要对这些 fleet 所发送的 SUC plans 进行任何自定义更改的用例,用户可以直接引用 suse-edge/fleet-examples 储存库中的 fleet。
如果需要自定义更改(例如添加自定义容忍度),用户应引用单独储存库中的 fleet,以便根据需要将更改添加到 SUC 计划中。
使用来自 GitRepo 储存库的 fleet 的 suse-edge/fleet-examples 资源配置示例:
33.1.5.4.1.2 GitRepo 创建 - 手动 #
拉取 GitRepo 资源:
对于 RKE2 集群:
curl -o rke2-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/gitrepos/day2/rke2-upgrade-gitrepo.yaml对于 K3s 集群:
curl -o k3s-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/gitrepos/day2/k3s-upgrade-gitrepo.yaml
编辑 GitRepo 配置,在
spec.targets下指定您所需的目标列表。默认情况下,来自suse-edge/fleet-examples的GitRepo资源 不会 映射到任何下游集群。要匹配所有集群,请将默认的
GitRepotarget 更改为:spec: targets: - clusterSelector: {}或者,如果您需要更细粒度的集群选择,请参阅 Mapping to Downstream Clusters
将 GitRepo 资源应用到您的
management cluster:# RKE2 kubectl apply -f rke2-upgrade-gitrepo.yaml # K3s kubectl apply -f k3s-upgrade-gitrepo.yaml在
fleet-default命名空间下查看创建的 GitRepo 资源:# RKE2 kubectl get gitrepo rke2-upgrade -n fleet-default # K3s kubectl get gitrepo k3s-upgrade -n fleet-default # Example output NAME REPO COMMIT BUNDLEDEPLOYMENTS-READY STATUS k3s-upgrade https://github.com/suse-edge/fleet-examples.git fleet-default 0/0 rke2-upgrade https://github.com/suse-edge/fleet-examples.git fleet-default 0/0
33.1.5.4.2 SUC 计划部署 - Bundle 资源 #
可以采用以下方式之一部署包含所需 Kubernetes upgrade SUC Plans 的 Bundle 资源:
通过
Rancher UI- 第 33.1.5.4.2.1 节 “Bundle 创建 - Rancher UI”(当Rancher可用时)。通过 手动部署 (第 33.1.5.4.2.2 节 “Bundle 创建 - 手动创建”) 资源到您的
management cluster。
部署完成后,要监控目标集群节点的 Kubernetes 升级过程,请参阅 第 18.3 节 “监控 System Upgrade Controller 计划”。
33.1.5.4.2.1 Bundle 创建 - Rancher UI #
Edge 团队为 rke2 和 k3s Kubernetes 发行版维护了可直接使用的 bundle。根据您的环境,这些 bundle 可以直接使用或作为模板使用。
通过 Rancher UI 创建 bundle:
在左上角,点击 ☰ → 持续交付
转到 高级 > Bundles
选择 从 YAML 创建
在此处,您可以通过以下方式之一创建 Bundle:
注意在某些用例中,您可能需要将自定义更改包含到 Bundle 附带的
SUC plans中(例如,添加自定义容忍度)。请确保在通过以下步骤生成的 Bundle 中包含这些更改。通过手动将 RKE2 或 K3s 的 Bundle 内容从
suse-edge/fleet-examples复制到 从 YAML 创建 页面。通过从所需的 发布 标签克隆 suse-edge/fleet-examples 储存库,并在 从 YAML 创建 页面中选择 从文件读取 选项。从那里,导航到您需要的 Bundle(RKE2 为
bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml,K3s 为bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml)。这将自动填充 从 YAML 创建 页面中的 Bundle 内容。
更改
Bundle的 目标 集群:要匹配所有下游集群,请将默认 Bundle
.spec.targets更改为:spec: targets: - clusterSelector: {}有关更细粒度的下游集群映射,请参阅 Mapping to Downstream Clusters.
选择 创建
33.1.5.4.2.2 Bundle 创建 - 手动创建 #
拉取 Bundle 资源:
对于 RKE2 集群:
curl -o rke2-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml对于 K3s 集群:
curl -o k3s-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.6.1/bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml
编辑
Bundletarget 配置,在spec.targets下提供您所需的目标列表。默认情况下,来自Bundle的suse-edge/fleet-examples资源 不会 映射到任何下游集群。要匹配所有集群,请将默认的
Bundletarget 更改为:spec: targets: - clusterSelector: {}或者,如果您需要更细粒度的集群选择,请参阅 Mapping to Downstream Clusters
将 Bundle 资源应用到您的
management cluster:# For RKE2 kubectl apply -f rke2-plan-bundle.yaml # For K3s kubectl apply -f k3s-plan-bundle.yaml在
fleet-default命名空间下查看创建的 Bundle 资源:# For RKE2 kubectl get bundles rke2-upgrade -n fleet-default # For K3s kubectl get bundles k3s-upgrade -n fleet-default # Example output NAME BUNDLEDEPLOYMENTS-READY STATUS k3s-upgrade 0/0 rke2-upgrade 0/0
33.1.5.4.3 SUC 计划部署 - 第三方 GitOps 工作流 #
在某些情况下,用户可能希望将 Kubernetes upgrade SUC plans 集成到他们自己的第三方 GitOps 工作流中(例如 Flux)。
要获取所需的 K8s 升级资源,请首先确定您想要使用的 suse-edge/fleet-examples 储存库的 Edge release 标签。
之后,可以在以下位置找到这些资源:
针对 RKE2 集群升级:
针对
control-plane节点 -fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-control-plane.yaml针对
worker节点 -fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-worker.yaml
针对 K3s 集群升级:
针对
control-plane节点 -fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-control-plane.yaml针对
worker节点 -fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-worker.yaml
为了更好地了解如何使用您的 GitOps 工作流来部署用于 Kubernetes 版本升级的 SUC Plans,建议查看使用 Fleet 的更新流程的 概览 (第 33.1.5.2 节 “概述”)。
33.1.6 Helm chart 升级 #
本节包含以下部分:
第 33.1.6.1 节 “针对隔离环境的准备工作” - 包含有关如何将 Edge 相关的 OCI chart 和镜像传输到您的私有镜像仓库的信息。
第 33.1.6.2 节 “升级过程” - 包含有关不同 Helm chart 升级用例及其升级过程的信息。
33.1.6.1 针对隔离环境的准备工作 #
33.1.6.1.1 确保您可以访问您的 Helm chart Fleet #
根据您的环境支持情况,您可以选择以下选项之一:
将您的 chart Fleet 资源托管在您的
management cluster可访问的本地 Git 服务器上。使用 Fleet 的 CLI 将 Helm chart 转换为 Bundle,这样您就可以直接使用它,而无需将其托管在其他地方。可以从 Fleet 的 发布 页面获取其 CLI,对于 Mac 用户,有一个 fleet-cli Homebrew 公式。
33.1.6.1.2 查找 Edge 发布版本所需的资产 #
转到“Day 2”发布页面,找到您要将 chart 升级到的 Edge 版本,然后点击 资产。
从 “资产” 部分,下载以下文件:
发布文件
说明
edge-save-images.sh
拉取
edge-release-images.txt文件中指定的镜像,并将它们打包到 '.tar.gz' 归档文件中。edge-save-oci-artefacts.sh
拉取与特定 Edge 版本相关的 OCI chart 镜像,并将它们打包到 '.tar.gz' 归档文件中。
edge-load-images.sh
从 '.tar.gz' 归档文件中加载镜像,重新标记并将其推送到私有镜像仓库。
edge-load-oci-artefacts.sh
获取包含 Edge OCI '.tgz' chart 包的目录,并将它们加载到私有镜像仓库。
edge-release-helm-oci-artefacts.txt
包含与特定 Edge 版本相关的 OCI chart 镜像列表。
edge-release-images.txt
包含与特定 Edge 版本相关的镜像列表。
33.1.6.1.3 创建 Edge 版本镜像归档文件 #
在有互联网连接的机器上:
使
edge-save-images.sh成为一个可执行程序:chmod +x edge-save-images.sh生成镜像归档文件:
./edge-save-images.sh --source-registry registry.suse.com这将创建一个名为
edge-images.tar.gz的待加载归档文件。注意如果指定了
-i|--images选项,归档文件的名称可能会有所不同。将此归档文件复制到您的 隔离的 机器:
scp edge-images.tar.gz <user>@<machine_ip>:/path
33.1.6.1.4 创建 Edge OCI chart 镜像归档文件 #
在有互联网连接的机器上:
使
edge-save-oci-artefacts.sh成为一个可执行程序:chmod +x edge-save-oci-artefacts.sh生成 OCI chart 镜像归档文件:
./edge-save-oci-artefacts.sh --source-registry registry.suse.com这将创建一个名为
oci-artefacts.tar.gz的归档文件。注意如果指定了
-a|--archive选项,归档文件的名称可能会有所不同。将此归档文件复制到您的 隔离的 机器:
scp oci-artefacts.tar.gz <user>@<machine_ip>:/path
33.1.6.1.5 将 Edge 版本镜像加载到您的隔离的机器上 #
在您的隔离的机器上:
登录到您的私有镜像仓库(如果需要):
podman login <REGISTRY.YOURDOMAIN.COM:PORT>使
edge-load-images.sh成为一个可执行程序:chmod +x edge-load-images.sh执行脚本,传入之前 复制 的
edge-images.tar.gz归档文件:./edge-load-images.sh --source-registry registry.suse.com --registry <REGISTRY.YOURDOMAIN.COM:PORT> --images edge-images.tar.gz注意这将从
edge-images.tar.gz加载所有镜像,重新打标签并将其推送到--registry选项下指定的镜像仓库。
33.1.6.1.6 将 Edge OCI chart 镜像加载到您的隔离的机器上 #
在您的隔离的机器上:
登录到您的私有镜像仓库(如果需要):
podman login <REGISTRY.YOURDOMAIN.COM:PORT>使
edge-load-oci-artefacts.sh成为一个可执行程序:chmod +x edge-load-oci-artefacts.sh解包已复制的
oci-artefacts.tar.gz归档文件:tar -xvf oci-artefacts.tar.gz这将生成一个带有命名模板
edge-release-oci-tgz-<date>的目录将此目录传递给
edge-load-oci-artefacts.sh脚本,以将 Edge OCI chart 镜像加载到您的私有镜像仓库:./edge-load-oci-artefacts.sh --archive-directory edge-release-oci-tgz-<date> --registry <REGISTRY.YOURDOMAIN.COM:PORT> --source-registry registry.suse.com
33.1.6.1.7 在您的 Kubernetes 发行版中配置您的私有镜像仓库 #
对于 RKE2,请参阅 Private Registry Configuration
对于 K3s,请参阅 Private Registry Configuration
33.1.6.2 升级过程 #
本节重点介绍以下 Helm 升级过程用例:
手动部署的 Helm charts 无法可靠地升级。我们建议使用 第 33.1.6.2.1 节 “我有一个新集群,想要部署和管理 Edge Helm chart” 方法重新部署 Helm chart。
33.1.6.2.1 我有一个新集群,想要部署和管理 Edge Helm chart #
本节介绍如何:
33.1.6.2.1.1 为您的 chart 准备 fleet 资源 #
从您希望使用的 Edge release 标签中获取该 chart 的 Fleet 资源。
导航至 Helm chart fleet (
fleets/day2/chart-templates/<chart>)如果您打算使用 GitOps 工作流,请将 chart Fleet 目录复制到您将执行 GitOps 的 Git 储存库中。
可选,如果 Helm chart 需要对其 values 进行配置,请编辑已复制目录中
.helm.values文件内的fleet.yaml配置。可选,在某些用例中,您可能需要向 chart 的 fleet 添加额外资源,以便使其更好地适应您的环境。有关如何增强 Fleet 目录的信息,请参阅 Git Repository Contents。
在某些情况下,Fleet 用于 Helm 操作的默认超时时间可能不足,从而导致以下错误:
failed pre-install: context deadline exceeded在这种情况下,请在 fleet.yaml 文件的 helm 配置下添加 timeoutSeconds 属性。
*示例*的`longhorn` Helm chart 看起来如下:
用户 Git 储存库结构:
<user_repository_root> ├── longhorn │ └── fleet.yaml └── longhorn-crd └── fleet.yaml填充了用户
fleet.yaml数据的Longhorn内容:defaultNamespace: longhorn-system helm: # timeoutSeconds: 10 releaseName: "longhorn" chart: "longhorn" repo: "https://charts.rancher.io/" version: "1.11.2" takeOwnership: true # custom chart value overrides values: # Example for user provided custom values content defaultSettings: deletingConfirmationFlag: true # https://fleet.rancher.io/bundle-diffs diff: comparePatches: - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition name: engineimages.longhorn.io operations: - {"op":"remove", "path":"/status/conditions"} - {"op":"remove", "path":"/status/storedVersions"} - {"op":"remove", "path":"/status/acceptedNames"} - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition name: nodes.longhorn.io operations: - {"op":"remove", "path":"/status/conditions"} - {"op":"remove", "path":"/status/storedVersions"} - {"op":"remove", "path":"/status/acceptedNames"} - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition name: volumes.longhorn.io operations: - {"op":"remove", "path":"/status/conditions"} - {"op":"remove", "path":"/status/storedVersions"} - {"op":"remove", "path":"/status/acceptedNames"}注意这些仅是用于说明
longhornchart 自定义配置的示例值。它们 *不*应被视为longhornchart 的部署指南。
33.1.6.2.1.2 为您的 chart 部署 Fleet #
您可以通过使用 GitRepo (第 33.1.6.2.1.2.1 节 “GitRepo”) 或 Bundle (第 33.1.6.2.1.2.2 节 “捆绑包”) 为您的 chart 部署 Fleet。
在部署 Fleet 时,如果您收到 Modified 消息,请确保在 Fleet 的 diff 部分中添加相应的 comparePatches 条目。有关更多信息,请参阅 生成忽略已修改 GitRepo 的差异。
33.1.6.2.1.2.1 GitRepo #
Fleet 的 GitRepo 资源包含有关如何访问您的 chart 的 Fleet 资源以及需要将这些资源应用到哪些集群的信息。
GitRepo 资源可以通过 Rancher UI 部署,也可以通过将资源 部署 到 management cluster 来手动部署。
用于 手动 部署的 Longhorn GitRepo 资源示例:
apiVersion: fleet.cattle.io/v1alpha1
kind: GitRepo
metadata:
name: longhorn-git-repo
namespace: fleet-default
spec:
# If using a tag
# revision: user_repository_tag
#
# If using a branch
# branch: user_repository_branch
paths:
# As seen in the 'Prepare your Fleet resources' example
- longhorn
- longhorn-crd
repo: user_repository_url
targets:
# Match all clusters
- clusterSelector: {}33.1.6.2.1.2.2 捆绑包 #
Bundle 资源包含需要由 Fleet 部署的原始 Kubernetes 资源。通常建议使用 GitRepo 方法,但对于环境处于隔离状态且无法支持本地 Git 服务器的用例,Bundles 可以帮助您将 Helm chart Fleet 传播到目标集群。
Bundle 可以通过 Rancher UI (Continuous Delivery → Advanced → Bundles → Create from YAML) 部署,也可以通过在正确的 Fleet 名称空间中手动部署 Bundle 资源来部署。有关 Fleet 名称空间的信息,请参阅上游 文档。
可以通过利用 Fleet 的 将 Helm Chart 转换为 Bundle 方法来创建用于 Edge Helm chart 的 Bundles。
您可以在下方找到关于如何从 longhorn 和 longhorn-crd Helm chart fleet 模板创建 Bundle 资源,并将此 bundle 手动部署到您的 management cluster 的示例。
导航到 longhorn Chart fleet 模板:
cd fleets/day2/chart-templates/longhorn/longhorn创建一个
targets.yaml文件,用于指示 Fleet 应将 Helm chart 部署到哪些集群:cat > targets.yaml <<EOF targets: # Matches all downstream clusters - clusterSelector: {} EOF如需更细粒度的下游集群选择,请参阅 映射到下游集群。
使用 fleet-cli 将
LonghornHelm chart Fleet 转换为 Bundle 资源。fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - longhorn-bundle > longhorn-bundle.yaml导航到 longhorn-crd Chart fleet 模板:
cd fleets/day2/chart-templates/longhorn/longhorn-crd创建一个
targets.yaml文件,用于指示 Fleet 应将 Helm chart 部署到哪些集群:cat > targets.yaml <<EOF targets: # Matches all downstream clusters - clusterSelector: {} EOF使用 fleet-cli 将
Longhorn CRDHelm chart Fleet 转换为 Bundle 资源。fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - longhorn-crd-bundle > longhorn-crd-bundle.yaml将
longhorn-bundle.yaml和longhorn-crd-bundle.yaml文件部署到您的management cluster:kubectl apply -f longhorn-crd-bundle.yaml kubectl apply -f longhorn-bundle.yaml
遵循这些步骤将确保 SUSE Storage 被部署到所有指定的 downstream 集群上。
33.1.6.2.1.3 管理已部署的 Helm chart #
使用 Fleet 部署后,有关 Helm chart 升级的信息,请参阅 第 33.1.6.2.2 节 “我想升级一个由 Fleet 管理的 Helm chart”。
33.1.6.2.2 我想升级一个由 Fleet 管理的 Helm chart #
确定您需要将 chart 升级到的版本,以便其与所需的 Edge 版本兼容。每个 Edge 版本的 Helm chart 版本可以在 发行说明 (第 41 章 “发行说明”) 中查看。
在您由 Fleet 监控的 Git 储存库中,使用 发行说明 (第 41 章 “发行说明”) 中的正确 chart 版本 和 储存库 编辑 Helm chart 的
fleet.yaml文件。提交并推送更改到您的储存库后,这将触发所需 Helm chart 的升级
33.1.6.2.3 我想升级一个通过 EIB 部署的 Helm chart #
第 8 章 “Edge Image Builder” 通过创建 HelmChart 资源并利用 RKE2/K3s Helm 集成功能引入的 helm-controller 来部署 Helm chart。
为确保通过 EIB 部署的 Helm chart 成功升级,用户需要对相应的 HelmChart 资源进行升级。
您可以在下方找到以下信息:
升级过程的常规概述 (第 33.1.6.2.3.1 节 “概述”)。
必要的升级步骤 (第 33.1.6.2.3.2 节 “升级步骤”)。
一个示例 (第 33.1.6.2.3.3 节 “示例”),展示了使用所解释的方法进行Longhorn chart 升级。
如何将升级过程与不同的 GitOps 工具 (第 33.1.6.2.3.4 节 “使用第三方 GitOps 工具进行 Helm chart 升级”)结合使用。
33.1.6.2.3.1 概述 #
通过`EIB`部署的 Helm charts 将通过一个名为eib-charts-upgrader的`fleet`进行升级。
此`fleet`处理*用户提供*的数据,以*更新*特定的一组 HelmChart 资源。
更新这些资源会触发helm-controller,它会*升级*与修改后的`HelmChart`资源相关联的 Helm charts。
用户仅需:
在本地拉取需要升级的每个 Helm chart 的归档文件。
将这些归档文件传递给generate-chart-upgrade-data.sh
generate-chart-upgrade-data.sh`脚本,该脚本会将这些归档文件中的数据包含到`eib-charts-upgraderfleet 中。将`eib-charts-upgrader` fleet 部署到其`management cluster`。这可以通过`GitRepo`或`Bundle`资源来完成。
部署完成后,`eib-charts-upgrader`将在 Fleet 的帮助下,将其资源发送到目标downstream集群。
这些资源包括:
一组`Secrets`,其中包含*用户提供*的 Helm chart 数据。
一个`Kubernetes Job`,它将部署一个`Pod`,该组件将挂载前面提到的`Secrets`,并据此对相应的 HelmChart 资源应用补丁。
如前所述,这将触发`helm-controller`,它将执行实际的 Helm chart 升级。
您可以在下方找到上述描述的图示:
33.1.6.2.3.2 升级步骤 #
从正确的发布标签克隆`suse-edge/fleet-examples`储存库。
创建一个目录,用于存储拉取的 Helm chart 归档文件。
mkdir archives在新建的归档目录中,拉取您希望升级的 Helm chart 的归档文件:
cd archives helm pull [chart URL | repo/chartname] # Alternatively if you want to pull a specific version: # helm pull [chart URL | repo/chartname] --version 0.0.0从所需 发布标签 的 资产 中,下载
generate-chart-upgrade-data.sh脚本。执行
generate-chart-upgrade-data.sh脚本:chmod +x ./generate-chart-upgrade-data.sh ./generate-chart-upgrade-data.sh --archive-dir /foo/bar/archives/ --fleet-path /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader对于
--archive-dir目录中的每个 chart 归档文件,该脚本都会生成一个包含 chart 升级数据的Kubernetes Secret YAML文件,并将其存储在由--fleet-path指定的 fleet 的base/secrets目录中。generate-chart-upgrade-data.sh脚本还会对 fleet 进行额外的修改,以确保生成的Kubernetes Secret YAML文件能被 fleet 部署的工作负载正确使用。重要用户不应在
generate-chart-upgrade-data.sh脚本生成的内容之上进行任何更改。
以下步骤取决于您运行的环境:
对于支持 GitOps 的环境(例如:非隔离的,或隔离的但允许本地 Git 服务器支持):
将
fleets/day2/eib-charts-upgraderFleet 复制到您将用于 GitOps 的储存库中。注意确保 Fleet 包含由
generate-chart-upgrade-data.sh脚本所做的更改。配置一个
GitRepo资源,该资源将用于交付eib-charts-upgraderFleet 的所有资源。有关通过 Rancher UI 进行
GitRepo配置和部署的信息,请参阅 在 Rancher UI 中访问 Fleet。有关
GitRepo手动配置和部署的信息,请参阅 创建部署。
对于不支持 GitOps 的环境(例如:为隔离的且不允许使用本地 Git 服务器):
从`rancher/fleet`release 页面下载
fleet-cli二进制文件(适用于fleet-linux-amd64的 Linux)。对于 Mac 用户,可以使用 Homebrew 配方 - fleet-cli。导航至
eib-charts-upgraderFleet:cd /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader创建一个
targets.yaml文件,用于指示 Fleet 在何处部署您的资源:cat > targets.yaml <<EOF targets: # To match all downstream clusters - clusterSelector: {} EOF有关如何映射目标集群的信息,请参阅上游 文档。
使用
fleet-cli将 Fleet 转换为Bundle资源:fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - eib-charts-upgrade > bundle.yaml这将创建一个 Bundle (
bundle.yaml),其中将包含来自eib-charts-upgraderFleet 的所有模板化资源。有关
fleet apply命令的更多信息,请参阅 fleet apply。有关将 Fleet 转换为 Bundle 的更多信息,请参阅 将 Helm Chart 转换为 Bundle。
部署
Bundle。可以通过以下两种方式之一完成此操作:通过 Rancher UI - 导航到 持续交付 → 高级 → Bundles → 从 YAML 创建,然后粘贴
bundle.yaml内容,或者点击Read from File选项并传入文件本身。手动 - 在您的
management cluster中手动部署bundle.yaml文件。
执行这些步骤将成功部署 GitRepo/Bundle 资源。该资源将被 Fleet 获取,其内容将部署到用户在先前步骤中指定的目标集群上。有关该过程的概述,请参阅 第 33.1.6.2.3.1 节 “概述”。
有关如何跟踪升级过程的信息,您可以参阅 第 33.1.6.2.3.3 节 “示例”。
一旦成功验证了 Chart 升级,请删除 Bundle/GitRepo 资源。
这将从您的 downstream 集群中删除不再需要的升级资源,以确保不会发生未来的版本冲突。
33.1.6.2.3.3 示例 #
下面的示例演示了如何在 downstream 集群上将通过 EIB 部署的 Helm Chart 从一个版本升级到另一个版本。请注意,此示例中使用的版本 不是 建议版本。有关特定于 Edge 版本的版本建议,请参阅 发行说明 (第 41 章 “发行说明”)。
适用场景:
名为
doc-example的集群正在运行 Longhorn 的旧版本。该集群已通过 EIB 部署,使用了以下镜像定义 snippet:
kubernetes: helm: charts: - name: longhorn-crd repositoryName: rancher-charts targetNamespace: longhorn-system createNamespace: true version: 104.2.0+up1.7.1 installationNamespace: kube-system - name: longhorn repositoryName: rancher-charts targetNamespace: longhorn-system createNamespace: true version: 104.2.0+up1.7.1 installationNamespace: kube-system repositories: - name: rancher-charts url: https://charts.rancher.io/ ...SUSE Storage需要升级到与 Edge 3.6 版本兼容的版本。这意味着它需要升级到1.11.2。假设负责管理
doc-example的management cluster是 *隔离的*环境,不支持本地 Git 服务器,并且拥有可正常工作的 Rancher 设置。
遵循 升级步骤 (第 33.1.6.2.3.2 节 “升级步骤”):
从
release-3.6.1标签克隆suse-edge/fleet-example储存库。git clone -b release-3.6.1 https://github.com/suse-edge/fleet-examples.git创建一个目录,用于存储
Longhorn升级归档文件。mkdir archives拉取所需的
Longhornchart 归档版本:# First add the Rancher Helm chart repository helm repo add rancher-charts https://charts.rancher.io/ # Pull the Longhorn 1.11.2 chart archive helm pull oci://dp.apps.rancher.io/charts/suse-storage --version 1.11.2在
archives目录之外,从suse-edge/fleet-examples版本 tag 下载generate-chart-upgrade-data.sh脚本。目录设置应如下所示:
. ├── archives │ └── longhorn-1.11.2.tgz ├── fleet-examples ... │ ├── fleets │ │ ├── day2 | | | ├── ... │ │ │ ├── eib-charts-upgrader │ │ │ │ ├── base │ │ │ │ │ ├── job.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── patches │ │ │ │ │ │ └── job-patch.yaml │ │ │ │ │ ├── rbac │ │ │ │ │ │ ├── cluster-role-binding.yaml │ │ │ │ │ │ ├── cluster-role.yaml │ │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ │ └── sa.yaml │ │ │ │ │ └── secrets │ │ │ │ │ ├── eib-charts-upgrader-script.yaml │ │ │ │ │ └── kustomization.yaml │ │ │ │ ├── fleet.yaml │ │ │ │ └── kustomization.yaml │ │ │ └── ... │ └── ... └── generate-chart-upgrade-data.sh执行
generate-chart-upgrade-data.sh脚本:# First make the script executable chmod +x ./generate-chart-upgrade-data.sh # Then execute the script ./generate-chart-upgrade-data.sh --archive-dir ./archives --fleet-path ./fleet-examples/fleets/day2/eib-charts-upgrader脚本执行后的目录结构应如下所示:
. ├── archives │ └── longhorn-1.11.2.tgz ├── fleet-examples ... │ ├── fleets │ │ ├── day2 │ │ │ ├── ... │ │ │ ├── eib-charts-upgrader │ │ │ │ ├── base │ │ │ │ │ ├── job.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── patches │ │ │ │ │ │ └── job-patch.yaml │ │ │ │ │ ├── rbac │ │ │ │ │ │ ├── cluster-role-binding.yaml │ │ │ │ │ │ ├── cluster-role.yaml │ │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ │ └── sa.yaml │ │ │ │ │ └── secrets │ │ │ │ │ ├── eib-charts-upgrader-script.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── longhorn-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script │ │ │ │ │ └── longhorn-crd-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script │ │ │ │ ├── fleet.yaml │ │ │ │ └── kustomization.yaml │ │ │ └── ... │ └── ... └── generate-chart-upgrade-data.shgit 中更改的文件应如下所示:
Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: fleets/day2/eib-charts-upgrader/base/patches/job-patch.yaml modified: fleets/day2/eib-charts-upgrader/base/secrets/kustomization.yaml Untracked files: (use "git add <file>..." to include in what will be committed) fleets/day2/eib-charts-upgrader/base/secrets/longhorn-VERSION.yaml fleets/day2/eib-charts-upgrader/base/secrets/longhorn-crd-VERSION.yaml为
eib-charts-upgraderFleet 创建一个Bundle:首先,导航到 Fleet 本身:
cd ./fleet-examples/fleets/day2/eib-charts-upgrader然后创建一个
targets.yaml文件:cat > targets.yaml <<EOF targets: - clusterName: doc-example EOF然后使用
fleet-cli二进制文件将 Fleet 转换为 Bundle:fleet apply --compress --targets-file=targets.yaml -n fleet-default -o - eib-charts-upgrade > bundle.yaml现在,将
bundle.yaml传输到您的management cluster机器上。
通过 Rancher UI 部署 Bundle:
图 33.1︰ 通过 Rancher UI 部署 Bundle #在此处,选择 从文件读取 并在您的系统上找到
bundle.yaml文件。这将自动填充 Rancher UI 中的
Bundle。选择 创建。
部署成功后,您的 Bundle 应如下所示:
图 33.2︰ Bundle 部署成功 #
Bundle 成功部署后,要监控升级过程:
验证
Upgrade Pod的日志:现在,验证由 helm-controller 为升级创建的 Pod 的日志:
Pod 名称将遵循以下模板 -
helm-install-longhorn-<random-suffix>Pod 将位于部署了
HelmChart资源的名称空间中。在我们的案例中,这是kube-system。图 33.3︰ 成功升级 Longhorn chart 的日志 #
通过导航到 Rancher 的
HelmCharts部分 (More Resources → HelmCharts),验证HelmChart版本是否已更新。选择部署 chart 的名称空间,在此示例中为kube-system。最后,检查 Longhorn Pod 是否正在运行。
完成上述验证后,可以确信 Longhorn Helm chart 已升级到 1.11.2 版本。
33.1.6.2.3.4 使用第三方 GitOps 工具进行 Helm chart 升级 #
在某些用例中,用户可能希望将此升级过程与 Fleet 以外的 GitOps 工作流(例如 Flux)结合使用。
为生成升级过程所需的资源,您可以使用 generate-chart-upgrade-data.sh 脚本将用户提供的数据填充到 eib-charts-upgrader Fleet 中。有关如何操作的详细信息,请参见 第 33.1.6.2.3.2 节 “升级步骤”。
完成完整设置后,您可以使用 kustomize 生成一个可在集群中部署的完整工作解决方案:
cd /foo/bar/fleets/day2/eib-charts-upgrader
kustomize build .如果您希望将该解决方案包含在 GitOps 工作流中,可以去除 fleet.yaml 文件,并将剩余部分用作有效的 Kustomize 设置。请务必先运行 generate-chart-upgrade-data.sh 脚本,以便其使用您希望升级到的 Helm chart 所需的数据来填充 Kustomize 设置。
要了解此工作流的预期用途,查看 第 33.1.6.2.3.1 节 “概述” 和 第 33.1.6.2.3.2 节 “升级步骤” 会有所帮助。
第 VII 部分 查错 #
本节提供了诊断和解决 SUSE Edge 部署和操作中常见问题的指南。它涵盖了各种主题,提供了特定于组件的故障排除步骤、关键工具和相关日志位置。
- 34 常规故障排除原则
在深入研究特定组件的问题之前,请考虑以下常规原则:
- 35 Kiwi 故障排除
Kiwi 用于生成更新的 SUSE Linux Micro 镜像,以供 Edge Image Builder 使用。
- 36 Edge Image Builder (EIB) 故障排除
EIB 用于创建自定义 SUSE Edge 镜像。
- 37 故障排除 Edge 网络 (NMC)
NMC 被注入到 SL Micro EIB 镜像中,以便在引导时通过 combustion 配置 Edge 主机的网络。它也作为检查过程的一部分在 Metal3 工作流中执行。当主机首次引导或在 Metal3 检查过程中可能会出现问题。
- 38 故障排除 Phone-Home 场景
Phone-home 场景涉及使用 Elemental 连接回管理集群和 EIB,以创建包含 elemental-registration 位的操作系统镜像。当主机首次启动、在 EIB 构建处理中或尝试注册到管理集群时,可能会出现问题。
- 39 其他组件故障排除
其他 SUSE Edge 组件故障排除指南可参考其官方文档:
- 40 收集用于支持的诊断信息
在联系 SUSE 支持部门时,提供全面的诊断信息至关重要。
34 常规故障排除原则 #
在深入研究特定组件的问题之前,请考虑以下常规原则:
检查日志:日志是信息的主要来源。大多数情况下,错误是不言自明的,并包含有关失败原因的提示。
检查时钟:系统之间的时钟差异可能导致各种不同的错误。确保时钟同步。可以指示 EIB 在引导时强制进行时钟同步,请参阅 配置操作系统时间 (第 2 章 “使用 Edge Image Builder 的独立集群”)。
引导问题:如果系统在引导过程中卡住,请记下显示的最后几条消息。访问控制台(物理或通过 BMC)以观察引导消息。
网络问题:验证网络接口配置 (
ip a)、路由表 (ip route),测试与其他节点及外部服务之间的连通性 (ping,nc)。确保防火墙规则未阻止必要的端口。验证组件状态:使用
kubectl get和kubectl describe查看 Kubernetes 资源。使用kubectl get events --sort-by='.lastTimestamp' -n <namespace>查看特定 Kubernetes 名称空间上的事件。验证服务状态:使用
systemctl status <service>查看 systemd 服务。检查语法:软件对配置文件有特定的结构和语法要求。例如,对于 yaml 文件,请使用
yamllint或类似工具来验证语法是否正确。隔离问题:尝试将问题缩小到特定的组件或层(例如,网络、存储、操作系统、Kubernetes、Metal3、Ironic,…)。
文档:请务必参考官方 SUSE Edge 文档 以及上游文档以获取详细信息。
版本:SUSE Edge 是不同 SUSE 组件经过深思熟虑且经过全面测试的版本。每个 SUSE Edge 版本中各组件的版本可以在 SUSE Edge 支持矩阵 中查看。
已知问题:对于每个 SUSE Edge 版本,发行说明中都有一个“已知问题”部分,其中包含将在未来版本中修复但可能会影响当前版本的问题的相关信息。
35 Kiwi 故障排除 #
Kiwi 用于生成更新的 SUSE Linux Micro 镜像,以供 Edge Image Builder 使用。
SL Micro 版本不匹配:构建主机操作系统版本必须与正在构建的操作系统版本匹配(SL Micro 6.0 主机 → SL Micro 6.0 镜像)。
SELinux 处于强制状态:由于某些限制,目前需要暂时禁用 SELinux 才能使用 Kiwi 构建镜像。使用
getenforce检查 SELinux 状态,并在使用setenforce 0运行构建过程之前将其禁用。构建主机未注册:构建过程使用构建主机订阅来从 SUSE SCC 拉取软件包。如果主机未注册,则会失败。
循环设备测试失败:首次执行 Kiwi 构建过程时,它会在启动后不久失败,并显示“ERROR:早期循环设备测试失败,请重试容器运行。 这是底层主机系统上创建的循环设备在容器镜像内无法立即识别的症状。重新运行 Kiwi 构建过程,它应该可以顺利进行。
缺少权限:构建过程需要以 root 用户身份(或通过 sudo)运行。
权限错误:构建过程在运行容器时需要
--privileged标志。请仔细检查该标志是否存在。
构建容器日志:检查构建容器的日志。日志生成在用于存储制品的目录中。同时检查 docker logs 或 podman logs 以获取必要信息。
临时构建目录:Kiwi 在构建过程中会创建临时目录。如果主要输出不足,请检查这些目录以获取中间日志或制品。
查看
build-image输出:控制台输出中的错误消息通常非常有指示性。检查构建环境:确保运行 Kiwi 的机器满足 Kiwi 本身的所有先决条件(例如 docker/podman、SELinux、足够的磁盘空间)。
检查构建容器日志:查看失败容器的日志以获取更详细的错误信息(见上文)。
验证定义文件:如果您使用的是自定义 Kiwi 镜像定义文件,请仔细检查该文件是否存在任何拼写错误或语法问题。
36 Edge Image Builder (EIB) 故障排除 #
EIB 用于创建自定义 SUSE Edge 镜像。
错误的 SCC 代码:确保 EIB 定义文件中使用的 SCC 代码与 SL Micro 版本和架构相匹配。
缺少依赖项:确保构建环境中没有缺失的软件包或工具。
镜像大小不正确:对于 raw 镜像,
diskSize参数是必需的,并且它在很大程度上取决于镜像、RPM 以及包含在镜像中的其他制品。权限:如果将脚本存储在 custom/files 目录中,请确保其具有可执行权限,因为这些文件仅在燃烧时可用,而 EIB 不会对其进行任何更改。
操作系统组依赖:创建包含自定义用户和组的镜像时,应显式创建设置为 “primaryGroup” 的组。
操作系统用户的 SSH 密钥需要主文件夹:创建包含带有 SSH 密钥的用户的镜像时,还需要使用
createHomeDir=true创建主文件夹。燃烧问题:EIB 依赖燃烧过程来定制操作系统并部署所有其他 SUSE Edge 组件。这也包括放置在 custom/scripts 目录中的自定义脚本。请注意,燃烧过程是在
initrd时间执行的,因此在执行脚本时系统尚未完全启动。Podman 机器大小:正如 EIB 提示和技巧部分 (第 IV 部分 “提示和技巧”) 中所述,请验证 Podman 机器是否有足够的处理器/内存来在非 Linux 操作系统上运行 EIB 容器。
镜像不正确:确保通过 验证
checksum正确下载了所使用的基础镜像。如果您正在使用 kiwi-builder (第 26 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 镜像”) 构建镜像,请同时检查该过程生成的校验和文件。
EIB 输出:
eib build命令的控制台输出至关重要。构建容器日志:检查构建容器的日志。日志生成在用于存储制品的目录中。同时检查
docker logs或podman logs以获取必要信息。临时构建目录:EIB 在构建过程中会创建临时目录。如果主要输出不足,请检查这些目录以获取中间日志或制品。
燃烧日志:如果使用 EIB 构建的镜像因任何原因无法启动,则可以使用 root 外壳。连接到主机控制台(物理连接、通过 BMC 等),并使用
journalctl -u combustion检查燃烧日志,同时使用journalctl检查所有操作系统日志,以查找故障的根本原因。
查看
eib-build输出:控制台输出中的错误消息通常具有很强的指示性。检查构建环境:确保运行 EIB 的机器满足 EIB 本身的所有先决条件(例如 docker/podman、足够的磁盘空间)。
检查构建容器日志:查看失败容器的日志以获取更详细的错误信息(见上文)。
验证
eib配置:仔细检查eib配置文件,查看是否有任何拼写错误,或源文件或构建脚本的路径是否不正确。测试各个组件:如果您的 EIB 构建涉及自定义脚本或阶段,请独立运行它们以隔离故障。
37 故障排除 Edge 网络 (NMC) #
NMC 被注入到 SL Micro EIB 镜像中,以便在引导时通过 combustion 配置 Edge 主机的网络。它也作为检查过程的一部分在 Metal3 工作流中执行。当主机首次引导或在 Metal3 检查过程中可能会出现问题。
主机首次无法正常引导:格式错误的网络定义文件可能导致 combustion 阶段失败,随后主机会进入 root shell。
文件未正确生成:确保网络文件符合 NMState 格式。
网络接口未正确配置:确保 MAC 地址与主机上使用的接口匹配。
接口名称不匹配:SL Micro 默认启用 网络接口的可预测命名方案,因此不再有
eth0,而是使用诸如enp2s0之类的其他命名方案。
Combustion 日志:由于 nmc 在 combustion 阶段使用,请在正在配置的主机上使用
journalctl -u combustion检查 combustion 日志。
验证 yaml 语法: nmc 配置文件是 yaml 文件,请使用
yamllint或类似工具检查语法是否正确。手动运行 nmc:由于 nmc 是 EIB 容器的一部分,若要调试任何问题,可以使用本地 podman 命令。
创建一个临时文件夹来存储 nmc 文件。
mkdir -p ${HOME}/tmp/foo将 nmc 文件保存在该位置。
❯ tree --noreport ${HOME}/tmp/foo /Users/johndoe/tmp/foo ├── host1.example.com.yaml └── host2.example.com.yaml运行以 nmc 为入口点并带有 generate 命令的 EIB 容器,以执行 nmc 在 combustion 阶段会执行的相同任务:
podman run -it --rm -v ${HOME}/tmp/foo:/tmp/foo:Z --entrypoint=/usr/bin/nmc registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 generate --config-dir /tmp/foo --output-dir /tmp/foo/ [2025-06-04T11:58:37Z INFO nmc::generate_conf] Generating config from "/tmp/foo/host2.example.com.yaml"... [2025-06-04T11:58:37Z INFO nmc::generate_conf] Generating config from "/tmp/foo/host1.example.com.yaml"... [2025-06-04T11:58:37Z INFO nmc] Successfully generated and stored network config观察在临时文件夹中生成的日志和文件。
38 故障排除 Phone-Home 场景 #
Phone-home 场景涉及使用 Elemental 连接回管理集群和 EIB,以创建包含 elemental-registration 位的操作系统镜像。当主机首次启动、在 EIB 构建处理中或尝试注册到管理集群时,可能会出现问题。
系统注册失败:节点未在 UI 中注册。确保主机已正确启动,能够与 Rancher 通信,时钟同步,并且 Elemental 服务正常。
系统配置失败:节点已注册,但配置失败。确保主机能够与 Rancher 通信,时钟同步,并且 Elemental 服务正常。
系统日志:
journalctlElemental-system-agent 日志:
journalctl -u elemental-system-agentK3s/RKE2 日志:
journalctl -u k3s or journalctl -u rke2-server(或rke2-agent)Elemental operator pod:
kubectl logs -n cattle-elemental-system -l app=elemental-operator
39 其他组件故障排除 #
其他 SUSE Edge 组件故障排除指南可参考其官方文档:
您也可以查看 SUSE 知识库。
40 收集用于支持的诊断信息 #
在联系 SUSE 支持部门时,提供全面的诊断信息至关重要。
详细的问题描述:发生了什么、何时发生、您当时在做什么、预期的行为是什么,以及实际的行为是什么?
重现步骤:您能否可靠地重现该问题?如果可以,请列出确切的步骤。
组件版本: SUSE Edge 版本,组件版本(RKE2/K3、EIB、Metal3、Elemental 等)。
相关日志:
journalctl输出(如果可能,按服务过滤,或提供完整的引导日志)。Kubernetes pod 日志 (kubectl logs)。
Metal³/Elemental 组件日志。
EIB 构建日志及其他日志
系统信息:
uname -adf -hip a/etc/os-release
配置文件:Elemental、Metal3、EIB 的相关配置文件,例如 helm chart 的 values 文件、configmap 等。
Kubernetes 信息:节点、服务、部署等。
受影响的 Kubernetes 对象:BMH、MachineRegistration 等。
对于日志:将命令输出重定向到文件(例如,
journalctl -u k3s > k3s_logs.txt)。对于 Kubernetes 资源:使用
kubectl get <resource> -o yaml > <resource_name>.yaml获取详细的 YAML 定义。对于系统信息:收集上述命令的输出。
对于 SL Micro:请查阅 SUSE Linux Micro 故障排除指南 文档,了解如何收集用于
supportconfig支持的系统信息。对于 RKE2/Rancher:请查阅 Rancher v2.x Linux 日志收集脚本 文章以运行 Rancher v2.x Linux 日志收集脚本。
对于 Edge (Nessie):Nessie 1.1.0 是一款功能强大的诊断工具,旨在从 SUSE Edge 环境中收集日志和配置数据。它从主机系统和 Kubernetes 集群中收集全面信息,对于故障排除和支持非常有用。
Nessie 有两种“模式”:kubernetes 模式和系统模式。
要从 SUSE Edge 集群收集日志,请运行(前提是您在本地拥有 kubeconfig 文件的访问权限):
podman run --rm --privileged \ -v /etc/rancher/k3s/k3s.yaml:/etc/rancher/k3s/k3s.yaml:ro \ -v /var/log/journal:/var/log/journal:ro \ -v /run/systemd:/run/systemd:ro \ -v /etc/machine-id:/etc/machine-id:ro \ -v /tmp:/tmp \ -e NESSIE_LOG_DIR="/tmp" \ -e NESSIE_ZIP_DIR="/tmp" \ registry.suse.com/edge/3.6/nessie:1.1.0注意如果需要,请调整
k3s.yaml/rke2.yaml文件的路径。有关更多信息,请参阅 Nessie。 如果您拥有适当的权限(通常k3s.yaml/rke2-server.yaml文件由 root 用户所有),则应该能够在非特权模式下运行此容器。若要从实际操作系统中以系统模式收集日志,请运行:
podman run --rm --privileged \ -v /var/log/journal:/var/log/journal:ro \ -v /run/systemd:/run/systemd:ro \ -v /etc/machine-id:/etc/machine-id:ro \ -v /tmp:/tmp \ -e NESSIE_LOG_DIR="/tmp" \ -e NESSIE_ZIP_DIR="/tmp" \ -e NESSIE_VERBOSE="1" \ -e NESSIE_SKIP_POD_LOGS="true" \ -e NESSIE_SKIP_K8S_CONFIGS="true" \ -e NESSIE_SKIP_METRICS="true" \ registry.suse.com/edge/3.6/nessie:1.1.0
与支持部门联系:请查看 如何有效利用 SUSE 技术支持 中提供的文章,以及位于 SUSE 技术支持手册 的支持手册,以了解有关如何联系 SUSE 支持部门的更多详细信息。
第 VIII 部分 附录 #
- 41 发行说明
SUSE Edge 3.6 是一款紧密集成且经过全面验证的端到端解决方案,旨在解决边缘基础设施和云原生应用部署所面临的独特挑战。其主要目标是提供一个具有明确主张、同时高度灵活、可伸缩且安全的平台,涵盖初始部署镜像构建、节点配置和上线、应用部署、可观测性及生命周期管理。
41 发行说明 #
41.1 摘要 #
SUSE Edge 3.6 是一款紧密集成且经过全面验证的端到端解决方案,旨在解决边缘基础设施和云原生应用部署所面临的独特挑战。其主要目标是提供一个具有明确主张、同时高度灵活、可伸缩且安全的平台,涵盖初始部署镜像构建、节点配置和上线、应用部署、可观测性及生命周期管理。
该解决方案的设计理念是,由于客户的需求和期望各不相同,因此不存在“一刀切”的边缘平台。边缘部署促使我们不断解决并优化一些极具挑战性的问题,包括大规模可伸缩性、受限的网络可用性、物理空间限制、新的安全威胁和攻击向量、硬件架构及系统资源的差异、部署和对接旧有基础设施与应用的需求,以及生命周期更长的客户解决方案。
SUSE Edge 从底层构建于最优秀的开源软件之上,这既符合我们 30 年来提供安全、稳定和经过认证的 SUSE Linux 平台的历史,也符合我们通过 Rancher 产品组合提供高度可扩展且功能丰富的 Kubernetes 管理的经验。SUSE Edge 在这些功能的基础上构建,以提供能够满足众多细分市场需求的功能,包括零售、医疗、交通、物流、电信、智能制造和工业物联网。
有关 SUSE Edge 产品支持生命周期更新的更多信息,请参阅 产品支持生命周期。
SUSE Telco Cloud 是 SUSE Edge 的衍生产品,具有额外的优化和组件,使该平台能够满足电信用例中的需求。
41.2 关于 #
除非另有明确说明和解释,否则这些发行说明在所有架构上都是相同的,并且最新版本以及所有其他 SUSE 产品的发行说明始终可在 https://www.suse.com/releasenotes 在线获取。
条目仅列出一次,但如果它们很重要且属于多个部分,则可以在多个地方引用它们。发行说明通常仅列出两个后续版本之间发生的更改。以前产品版本的发行说明中的某些重要条目可能会重复。为了更容易识别这些条目,它们包含相关的说明。
但是,重复的条目仅作为一种便利提供。因此,如果您跳过一个或多个版本,请同时查看所跳过版本的发行说明。如果您仅阅读当前版本的发行说明,则可能会错过可能影响系统行为的重要更改。SUSE Edge 版本定义为 x.y.z,其中“x”表示主版本,“y”表示次版本,“z”表示补丁版本,也称为“z-stream”。SUSE Edge 产品生命周期是根据给定的次要版本定义的,例如。“3.6”,但在其生命周期内会随附后续补丁更新,例如。"3.6.1".
SUSE Edge z-stream 版本作为版本化堆栈进行了紧密集成和全面测试。将任何单个组件升级到不同于上述版本的版本可能会导致系统停机时间。虽然可以在未经测试的配置中运行 Edge 集群,但不建议这样做,并且通过支持渠道提供解决方案可能需要更长时间。
41.3 Release 3.6.1 #
可用性日期:2026年6月26日
全面支持结束日期:2026年11月27日
维护支持结束日期:2028年5月27日
EOL:2028年5月28日
摘要:SUSE Edge 3.6.1 是 SUSE Edge 3.6 发布流中的第一个 z-stream 版本。
41.3.1 新功能 #
更新至 Kubernetes 1.35.4 和 Rancher Prime 2.14.2
更新至 SUSE Security (NeuVector) 5.5.2 NeuVector 发行说明
更新至 SUSE Storage (Longhorn) 1.11.2 上游 Longhorn 发行说明
更新至 Rancher Turtles (CAPI) 0.26.2 Rancher Turtles 文档
将 Metal3/Ironic 更新至 0.15.0,并包含 Ironic 35.0.0.2
41.3.2 Bug 修复与安全更新 #
Kubernetes 1.35.4 包含多项 Bug 修复和安全更新 Kubernetes 更改日志
Rancher Prime 2.14.2 包含多项 Bug 修复 上游 Rancher 发行说明
SUSE Storage (Longhorn) 1.11.2 包含多项 Bug 修复 上游 Longhorn Bug 修复
NeuVector 5.5.2 包含新功能和若干 Bug 修复 NeuVector 发行说明
Metal3/Ironic 更新修复了若干 Bug 和安全问题,包括以下内容:
41.3.3 已知问题 #
如果部署新集群,请先按照 第 26 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 镜像” 构建全新的镜像。 建议管理集群和下游集群执行此操作,以确保镜像包含最新的安全和错误修复。
当通过 Edge Image Builder 部署时,如果将
HelmChartConfigs清单放入kubernetes/manifests配置目录,它们可能会失败。建议改为使用 EIB os-files 接口将任何HelmChartConfigs放置在/var/lib/rancher/{rke2/k3s}/server/manifests/中。 如果不这样做,可能会导致节点在初始启动时保持在NotReady状态,如 #8357 RKE2 问题 中所述。在 RKE2/K3s 1.34 和 1.35 版本中,用于存储 CNI 配置的目录
/etc/cni可能不会因overlayfs相关的某些条件而触发写入该目录的文件的通知给containerd(请参阅 #8356 RKE2 问题)。这反过来会导致 RKE2/K3s 的部署卡在等待 CNI 启动的状态,并使 RKE2/K3s 节点保持在NotReady状态。这可以在节点级别通过kubectl describe node <affected_node>查看:
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
Ready False Thu, 05 Jun 2025 17:41:28 +0000 Thu, 05 Jun 2025 14:38:16 +0000 KubeletNotReady container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized作为一种变通方法,可以在 RKE2 启动之前将 tmpfs 卷挂载到 /etc/cni 目录。它避免了使用 overlayfs,因为后者会导致 containerd 丢失通知,并且配置应在每次节点重启和 Pod 初始化容器再次运行时被重写。如果使用 EIB,这可以是一个位于 04-tmpfs-cni.sh 目录中的 custom/scripts 脚本(如 此处 所述),其内容如下:
#!/bin/bash
mkdir -p /etc/cni
mount -t tmpfs -o mode=0700,size=5M tmpfs /etc/cni
echo "tmpfs /etc/cni tmpfs defaults,size=5M,mode=0700 0 0" >> /etc/fstab目前尚无通过 synce4l 配置 SyncE 以及通过 gpsd 配置 GNSS 的官方文档或示例,这些主题将在未来的版本中涵盖。
某些容器仓库目前仅可通过 IPv4 访问,因此对于仅支持 IPv6 的下游集群,需要管理集群上的本地仓库。
41.3.4 组件版本 #
下表描述了构成 3.6.1 版本的各个组件,包括版本、Helm Chart 版本(如果适用),以及可以从何处以二进制格式拉取已发布的制品。请遵循相关文档以获取使用和部署示例。
名称 | 版本 | Helm Chart 版本 | 制品位置 (URL/镜像) |
SUSE Linux Micro | 6.2 (最新) | 不适用 | |
SUSE Linux Micro | 6.2 (最新) | 不适用 | 校验和与签名可从 SUSE Linux Micro 下载页面 下载 |
SUSE Multi-Linux Manager | 5.1 | 不适用 | |
K3s | 1.35.4 | 不适用 | |
RKE2 | 1.35.4 | 不适用 | |
SUSE Rancher Prime | 2.14.2 | 2.14.2 | Rancher Prime Helm 储存库 |
SUSE Storage (Longhorn) | 1.11.2 | 1.11.2 | SUSE Storage Helm 储存库 |
SUSE Security (NeuVector) | 5.5.2 | 109.0.2+up2.10.2 | Rancher Charts Helm 储存库 |
Rancher Turtles 提供程序 (CAPI) | 0.26.2 | 306.0.7+up0.26.2 | registry.suse.com/edge/3.6/rancher-turtles-providers-chart:306.0.7+up0.26.2 |
Metal3s | 0.15.0 | 306.0.29+up0.15.0 | registry.suse.com/edge/3.6/metal3-chart:306.0.29+up0.15.0 |
MetalLB | 0.15.3 | 306.0.2+up0.15.3 | registry.suse.com/edge/3.6/metallb-chart:306.0.2+up0.15.3 |
Elemental | 1.9.0 | 1.9.0 | registry.suse.com/rancher/elemental-operator-chart:1.9.0 |
Elemental 仪表板扩展 | 3.0.1 | 3.0.1 | |
Edge Image Builder | 1.3.3.1 | 不适用 | registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 |
KubeVirt | 1.7.0 | 306.0.2+up0.7.0 | registry.suse.com/edge/3.6/kubevirt-chart:306.0.2+up0.7.0 |
KubeVirt 仪表板扩展 | 1.3.3 | 306.0.4+up1.3.3 | registry.suse.com/edge/3.6/kubevirt-dashboard-extension-chart:306.0.4+up1.3.3 |
容器化数据导入器 (CDI) | 1.64.0 | 306.0.2+up0.7.0 | registry.suse.com/edge/3.6/cdi-chart:306.0.2+up0.7.0 |
端点复制器操作员 | 0.3.0 | 306.0.1+up0.3.0 | registry.suse.com/edge/3.6/endpoint-copier-operator-chart:306.0.1+up0.3.0 |
SR-IOV 网络操作员 | 1.6.0 | 306.0.4+up1.6.0 | registry.suse.com/edge/3.6/sriov-network-operator-chart:306.0.4+up1.6.0 |
系统升级控制器 | 0.19.1 | 109.0.1 | Rancher Charts Helm 存储库 |
升级控制器 | 0.1.3 | 306.0.4+up0.1.3 | registry.suse.com/edge/3.6/upgrade-controller-chart:306.0.4+up0.1.3 |
SUSE Private Registry | 1.1.1 | 1.1.1 | oci://registry.suse.com/private-registry/private-registry-helm[SUSE Private Registry Helm 存储库] |
Kiwi 构建器 | 10.2.29.1 | 不适用 | registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 |
Cert-Manager | 1.20.1 | 1.20.1 | Jetstack Helm 存储库 |
41.4 3.6.0 版本 #
可用性日期:2026 年 5 月 27 日
全面支持结束日期:2026 年 11 月 27 日
维护支持结束日期:2028 年 5 月 27 日
EOL:2028 年 5 月 28 日
摘要:SUSE Edge 3.6.0 是 SUSE Edge 3.6 发布流中的第一个版本。
41.4.1 新功能 #
更新至 Kubernetes 1.35.3 和 Rancher Prime 2.14.1
更新至 SUSE Security (NeuVector) 5.5.1 NeuVector 发行说明
更新至 SUSE Storage (Longhorn) 1.11.1 上游 Longhorn 发行说明
更新至 Rancher Turtles (CAPI) 0.26.1 Rancher Turtles 文档
更新至 MetalLB 0.15.3 上游发行说明
更新至 KubeVirt 1.7.0 和 CDI (Containerized Data Importer) 1.64.0
更新至 Elemental 1.9.0 Elemental 发行说明
更新至 Cert-Manager 1.20.1 上游发行说明
将 Metal3/Ironic 更新至 0.15.0,其中包含 Ironic 35.0.0
MetalLB 的 BGP 模式在 SUSE Edge 3.5 中为技术预览版,现已获得全面支持
下游部署中的精确时间协议 (PTP) 在 SUSE Edge 3.5 中为技术预览版,现已获得全面支持,同时支持 SyncE 和 GNSS
现已支持单栈 IPv6 下游集群部署,但请注意,这需要双栈管理集群(单栈管理集群仍为技术预览版)
41.4.2 Bug 修复与安全更新 #
Kubernetes 1.35.3 包含多项 Bug 修复和安全更新 Kubernetes 更改日志
Rancher Prime 2.14.1 包含多项 Bug 修复 上游 Rancher 发行说明
SUSE Storage (Longhorn) 1.11.1 包含多项 Bug 修复 上游 Longhorn Bug 修复
NeuVector 5.5.1 包含新功能和若干 Bug 修复 NeuVector 发行说明
41.4.3 已知问题 #
如果部署新集群,请先按照 第 26 章 “使用 Kiwi 构建更新的 SUSE Linux Micro 镜像” 构建全新的镜像。 建议管理集群和下游集群执行此操作,以确保镜像包含最新的安全更新和 Bug 修复。
当通过 Edge Image Builder 部署时,如果将
HelmChartConfigs清单放入kubernetes/manifests配置目录,它们可能会失败。建议改为使用 EIB os-files 接口将任何HelmChartConfigs放置在/var/lib/rancher/{rke2/k3s}/server/manifests/中。 如果不这样做,可能会导致节点在初始启动时保持在NotReady状态,如 #8357 RKE2 问题 中所述。在 RKE2/K3s 1.34 和 1.35 版本中,用于存储 CNI 配置的目录
/etc/cni可能不会因与containerd相关的某些条件而触发向overlayfs发送文件写入通知(请参阅 #8356 RKE2 问题)。这反过来会导致 RKE2/K3s 的部署卡在等待 CNI 启动的状态,并使 RKE2/K3s 节点保持在NotReady状态。这可以在节点级别通过kubectl describe node <affected_node>查看:
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
Ready False Thu, 05 Jun 2025 17:41:28 +0000 Thu, 05 Jun 2025 14:38:16 +0000 KubeletNotReady container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized作为一种变通方法,可以在 RKE2 启动之前将 tmpfs 卷挂载到 /etc/cni 目录。它避免了使用 overlayfs,因为后者会导致 containerd 丢失通知,并且配置应在每次节点重启和容器的 init 容器再次运行时被重写。如果使用 EIB,这可以是一个位于 custom/scripts 目录中的 04-tmpfs-cni.sh 脚本(如 此处 所述),其内容如下:
#!/bin/bash
mkdir -p /etc/cni
mount -t tmpfs -o mode=0700,size=5M tmpfs /etc/cni
echo "tmpfs /etc/cni tmpfs defaults,size=5M,mode=0700 0 0" >> /etc/fstab目前尚无通过 synce4l 配置 SyncE 以及通过 gpsd 配置 GNSS 的官方文档或示例,这些主题将在未来的版本中涵盖。
某些容器仓库目前仅可通过 IPv4 访问,因此对于仅支持 IPv6 的下游集群,需要管理集群上的本地仓库。
41.4.4 组件版本 #
下表描述了构成 3.6.0 版本的各个组件,包括版本、Helm chart 版本(如果适用),以及可以从何处以二进制格式拉取已发布的制品。请遵循相关文档以获取使用和部署示例。
名称 | 版本 | Helm Chart 版本 | 制品位置 (URL/镜像) |
SUSE Linux Micro | 6.2 (最新) | 不适用 | |
SUSE Linux Micro | 6.2 (最新) | 不适用 | 校验和与签名可从 SUSE Linux Micro 下载页面 下载 |
SUSE Multi-Linux Manager | 5.1 | 不适用 | |
K3s | 1.35.3 | 不适用 | |
RKE2 | 1.35.3 | 不适用 | |
SUSE Rancher Prime | 2.14.1 | 2.14.1 | Rancher Prime Helm 存储库 |
SUSE Storage (Longhorn) | 1.11.1 | 1.11.1 | SUSE Storage Helm 存储库 |
SUSE Security (NeuVector) | 5.5.1 | 109.0.1+up2.8.13 | Rancher Charts Helm 存储库 |
Rancher Turtles 提供程序 (CAPI) | 0.26.1 | 306.0.6+up0.26.1 | registry.suse.com/edge/3.6/rancher-turtles-providers-chart:306.0.6+up0.26.1 |
Metal3 | 0.15.0 | 306.0.26+up0.15.0 | registry.suse.com/edge/3.6/metal3-chart:306.0.26+up0.15.0 |
MetalLB | 0.15.3 | 306.0.2+up0.15.3 | registry.suse.com/edge/3.6/metallb-chart:306.0.2+up0.15.3 |
Elemental | 1.9.0 | 1.9.0 | registry.suse.com/rancher/elemental-operator-chart:1.9.0 |
Elemental 仪表板扩展 | 3.0.1 | 3.0.1 | |
Edge Image Builder | 1.3.3.1 | 不适用 | registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 |
KubeVirt | 1.7.0 | 306.0.2+up0.7.0 | registry.suse.com/edge/3.6/kubevirt-chart:306.0.2+up0.7.0 |
KubeVirt 仪表板扩展 | 1.3.3 | 306.0.4+up1.3.3 | registry.suse.com/edge/3.6/kubevirt-dashboard-extension-chart:306.0.4+up1.3.3 |
容器化数据导入器 (CDI) | 1.64.0 | 306.0.2+up0.7.0 | registry.suse.com/edge/3.6/cdi-chart:306.0.2+up0.7.0 |
端点复制器操作员 | 0.3.0 | 306.0.1+up0.3.0 | registry.suse.com/edge/3.6/endpoint-copier-operator-chart:306.0.1+up0.3.0 |
SR-IOV 网络操作员 | 1.6.0 | 306.0.4+up1.6.0 | registry.suse.com/edge/3.6/sriov-network-operator-chart:306.0.4+up1.6.0 |
系统升级控制器 | 0.19.1 | 109.0.1 | Rancher Charts Helm 存储库 |
升级控制器 | 0.1.3 | 306.0.3+up0.1.3 | registry.suse.com/edge/3.6/upgrade-controller-chart:306.0.3+up0.1.3 |
SUSE Private Registry | 1.1.1 | 1.1.1 | oci://registry.suse.com/private-registry/private-registry-helm[SUSE Private Registry Helm 存储库] |
Kiwi 构建器 | 10.2.29.1 | 不适用 | registry.suse.com/edge/3.6/kiwi-builder:10.2.29.1 |
Cert-Manager | 1.20.1 | 1.20.1 | Jetstack Helm 存储库 |
41.5 已去除功能 #
除非另有说明,否则这些内容适用于 3.6.0 版本及所有后续 z-stream 版本。
Akri 在之前的 Edge 版本中是一项技术预览功能,从 3.4.0 版本开始被弃用。它现已从产品中完全去除。
41.6 技术预览 #
除非另有说明,否则这些内容适用于 3.6.0 版本及所有后续 z-stream 版本。
单栈 IPv6 管理集群部署是一项技术预览功能,不属于标准支持范围。
41.7 组件验证 #
上述组件可以使用软件物料清单 (SBOM) 数据进行验证 - 例如,使用如下所述的 cosign:
从 SUSE 签名密钥源 下载 SUSE Edge 容器公钥:
> cat key.pem
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7N0S2d8LFKW4WU43bq7Z
IZT537xlKe17OQEpYjNrdtqnSwA0/jLtK83m7bTzfYRK4wty/so0g3BGo+x6yDFt
SVXTPBqnYvabU/j7UKaybJtX3jc4SjaezeBqdi96h6yEslvg4VTZDpy6TFP5ZHxZ
A0fX6m5kU2/RYhGXItoeUmL5hZ+APYgYG4/455NBaZT2yOywJ6+1zRgpR0cRAekI
OZXl51k0ebsGV6ui/NGECO6MB5e3arAhszf8eHDE02FeNJw5cimXkgDh/1Lg3KpO
dvUNm0EPWvnkNYeMCKR+687QG0bXqSVyCbY6+HG/HLkeBWkv6Hn41oeTSLrjYVGa
T3zxPVQM726sami6pgZ5vULyOleQuKBZrlFhFLbFyXqv1/DokUqEppm2Y3xZQv77
fMNogapp0qYz+nE3wSK4UHPd9z+2bq5WEkQSalYxadyuqOzxqZgSoCNoX5iIuWte
Zf1RmHjiEndg/2UgxKUysVnyCpiWoGbalM4dnWE24102050Gj6M4B5fe73hbaRlf
NBqP+97uznnRlSl8FizhXzdzJiVPcRav1tDdRUyDE2XkNRXmGfD3aCmILhB27SOA
Lppkouw849PWBt9kDMvzelUYLpINYpHRi2+/eyhHNlufeyJ7e7d6N9VcvjR/6qWG
64iSkcF2DTW61CN5TrCe0k0CAwEAAQ==
-----END PUBLIC KEY-----验证容器镜像哈希,例如使用 crane:
> crane digest registry.suse.com/edge/3.6/baremetal-operator:0.12.3.0 --platform linux/amd64
sha256:example-digest-placeholder对于多架构镜像,在获取摘要时还需要指定平台,例如 --platform linux/amd64 或 --platform linux/arm64。如果不这样做,将在后续步骤 (Error: no matching attestations) 中导致错误。
使用 cosign 进行验证:
> cosign verify-attestation --type spdxjson --key key.pem registry.suse.com/edge/3.6/baremetal-operator@sha256:example-digest-placeholder > /dev/null
#
Verification for registry.suse.com/edge/3.6/baremetal-operator@sha256:example-digest-placeholder --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The signatures were verified against the specified public key按照 SUSE SBOM 文档 中的说明提取 SBOM 数据:
> cosign verify-attestation --type spdxjson --key key.pem registry.suse.com/edge/3.6/baremetal-operator@sha256:example-digest-placeholder | jq '.payload | @base64d | fromjson | .predicate'41.8 升级步骤 #
有关如何升级到新版本的详细信息,请参阅 第 VI 部分 “第2天操作”。
41.9 产品支持生命周期 #
SUSE Edge 由 SUSE 提供屡获殊荣的支持,SUSE 是一家成熟的技术领导者,在提供企业级支持服务方面拥有良好的记录。有关更多信息,请参阅 https://www.suse.com/lifecycle 以及 https://www.suse.com/support/policy.html 处的支持策略页面。如果您对提交支持案例、SUSE 如何划分严重性级别或支持范围有任何疑问,请参阅 https://www.suse.com/support/handbook/ 处的技术支持手册。
SUSE Edge “3.6”版本提供24个月的生产支持,其中最初6个月为“全面支持”,随后18个月为“维护支持”。 在这些支持阶段之后,产品达到“终止服务”(EOL),并不再获得支持。有关生命周期阶段的更多信息,请参见下表:
全面支持(6个月) | 在全面支持期间,将发布紧急和选定的高优先级 Bug 修复,所有其他补丁(非紧急、增强功能、新功能)将通过常规发布计划发布。 |
维护支持(18个月) | 在此期间,仅通过补丁发布关键修复。其他 Bug 修复可能会由SUSE酌情发布,但不应抱有预期。 |
终止服务(EOL) | 一旦产品版本达到其终止服务日期,客户可以在产品许可协议的条款范围内继续使用该产品。 SUSE的支持计划不适用于已过终止服务日期的产品版本。 |
除非另有明确说明,否则所列出的所有组件均被视为一般可用(GA),并涵盖在SUSE的标准支持范围内。某些组件可能被列为“技术预览”,SUSE在此为客户提供早期预发布功能以供评估,但这些组件不受标准支持政策的约束,也不建议用于生产环境。SUSE非常欢迎对技术预览组件的改进提出反馈和建议,但如果技术预览功能无法满足客户需求或未达到我们要求的成熟度,SUSE保留在正式发布前弃用该功能的权利。
请注意,SUSE偶尔必须弃用功能或更改API规范。弃用功能或更改API的原因可能包括:功能被更新或被新实现所取代、新功能集的引入、上游技术不再可用,或者上游社区引入了不兼容的更改。在给定的次要版本(x.z)中,我们不打算进行此类更改,因此所有z-stream版本都将保持API兼容性和功能特性。SUSE将尽力在发行说明中提前发出弃用警告,并提供变通方法、建议和缓解措施,以最大限度地减少服务中断。
SUSE Edge团队也欢迎社区反馈,您可以在 https://www.github.com/suse-edge内的相应储存库中提出问题。
41.10 获取源代码 #
本 SUSE 产品包含根据 GNU 通用公共许可证 (GPL) 及其他各种开源许可证授权给 SUSE 的材料。GPL 要求 SUSE 提供与 GPL 许可材料相对应的源代码,并且 SUSE 符合所有其他开源许可证要求。因此,SUSE 提供了所有源代码,通常可以在 SUSE Edge GitHub 储存库 (https://www.github.com/suse-edge)、用于依赖组件的 SUSE Rancher GitHub 储存库 (https://www.github.com/rancher) 中找到,特别是对于 SUSE Linux Micro,源代码可在 https://www.suse.com/download/sle-micro 的“Medium 2”上下载。
41.11 法律声明 #
SUSE 对本文档的内容或使用不做任何声明或保证,并明确声明免除任何明示或暗示的关于适销性或适用于任何特定用途的保证。此外,SUSE 保留随时修订本出版物及其内容的权利,并且没有义务将这些修订或更改通知任何个人或实体。
此外,SUSE 对任何软件不做任何声明或保证,并明确声明免除任何明示或暗示的关于适销性或适用于任何特定用途的保证。此外,SUSE 保留随时更改 SUSE 软件全部或部分内容的权利,并且没有义务将这些更改通知任何个人或实体。
依据本协议提供的任何产品或技术信息都将受到美国出口控制和其他国家/地区的贸易法律的约束。您同意遵守所有出口控制法规,并同意在出口、再出口或进口可交付产品之前获得任何必要的许可证或分类证书。您同意不出口或再出口至当前美国出口排除列表上所列的实体,或者美国出口法律中规定的任何被禁运的国家/地区或支持恐怖主义的国家/地区。您同意不将可交付产品用于禁止的核、导弹或化学/生物武器的最终用途。有关出口 SUSE 软件的更多信息,请参阅 https://www.suse.com/company/legal/。如果您未能获得任何必要的出口许可,SUSE 对此不承担任何责任。
版权所有 © 2024 SUSE LLC。
本发行说明文档采用知识共享署名-禁止演绎 4.0 国际许可协议 (CC-BY-ND-4.0) 进行许可。您应该已随本文档收到一份许可证副本。如果还没有,请参见 https://creativecommons.org/licenses/by-nd/4.0/。
SUSE 拥有与本文档所述产品中包含的技术相关的知识产权。特别是,这些知识产权可能包括但不限于在 https://www.suse.com/company/legal/ 中列出的一项或多项美国专利,以及在美国和其他国家/地区的一项或多项其他专利或专利申请。
有关 SUSE 商标的信息,请参阅 SUSE 商标和服务标志列表 (https://www.suse.com/company/legal/)。所有第三方商标均是其各自所有者的财产。有关 SUSE 品牌信息和使用要求,请参阅发布在 https://brand.suse.com/ 上的指南。






































