使用 anaconda 部署接口

Ironic 支持使用 anaconda 安装程序部署操作系统。此 anaconda 部署接口适用于 pxeipxe 启动接口。

配置

默认情况下未启用 anaconda 部署接口。要启用此接口,请将 anaconda 添加到 ironic.conf 文件中 enabled_deploy_interfaces 配置选项的值中。例如

[DEFAULT]
...
enabled_deploy_interfaces = direct,anaconda
...

更改生效后,必须重新启动所有 ironic conductor 进程。

默认 kickstart 模板通过配置选项 anaconda.default_ks_template 指定。它设置为此 ks.cfg.template,但可以修改为使用其他模板。

[anaconda]
default_ks_template = /etc/ironic/ks.cfg.template

创建 ironic 节点时,将 anaconda 指定为部署接口。例如

baremetal node create --driver ipmi \
    --deploy-interface anaconda \
    --boot-interface ipxe

您还可以通过现有节点的 --deploy-interface 选项设置 anaconda 部署接口

baremetal node set <node> --deploy-interface anaconda

创建操作系统镜像

虽然 anaconda 允许安装单个 RPM 包,但默认 kickstart 文件期望使用操作系统 tarball 作为操作系统镜像。

baremetal.yum 文件包含生成操作系统 tarball 所需的所有 yum/dnf 命令。这些命令安装需要包含在镜像中的软件包和软件包组

group install 'Minimal Install'
install cloud-init
ts run

可以使用以下命令集以及上述 baremetal.yum 文件创建操作系统 tarball

export CHROOT=/home/<user>/os-image
mkdir -p $(CHROOT)
mkdir -p $(CHROOT)/{dev,proc,run,sys}
chown -hR root:root $(CHROOT)
mount --bind /var/cache/yum $(CHROOT)/var/cache/yum
mount --bind /dev $(CHROOT)/dev
mount -t proc proc $(CHROOT)/proc
mount -t tmpfs tmpfs $(CHROOT)/run
mount -t sysfs sysfs $(CHROOT)/sys
dnf -y --installroot=$(CHROOT) makecache
dnf -y --installroot=$(CHROOT) shell baremetal.yum
rpm --root $(CHROOT) --import $(CHROOT)/etc/pki/rpm-gpg/RPM-GPG-KEY-*
truncate -s 0 $(CHROOT)/etc/machine-id
umount $(CHROOT)/var/cache/yum
umount $(CHROOT)/dev
umount $(CHROOT)/proc
umount $(CHROOT)/run
umount $(CHROOT)/sys
tar cpzf os-image.tar.gz --xattrs --acls --selinux -C $(CHROOT) .

在 glance 中配置操作系统镜像

Anaconda 是一个两阶段安装程序——第一阶段包括内核和 ramdisk,第二阶段位于 squashfs 文件中。所有这些组件都可以在 CentOS/RHEL/Fedora ISO 镜像中找到。

内核和 ramdisk 可以在 ISO 中的 /images/pxeboot/vmlinuz/images/pxeboot/initrd.img 处找到。第二阶段 squashfs 镜像通常位于 /LiveOS/squashfs.img/images/install.img 处。

anaconda 部署驱动程序使用 glance 中的以下镜像属性,这些属性都是可选的,具体取决于您创建裸机服务器的方式

  • kernel_id

  • ramdisk_id

  • stage2_id

  • ks_template

  • disk_file_extension

disk_file_extension 之外的所有属性都是 glance 镜像 ID。它们可以以 glance:// 为前缀。

有效的 disk_file_extension 值包括

  • .img

  • .tar

  • .tbz

  • .tgz

  • .txz

  • .tar.gz

  • .tar.bz2

  • .tar.xz

disk_file_extension 属性未设置为上述有效值之一时,anaconda 安装程序将假定提供的镜像是一个可挂载的操作系统磁盘。

以下是一个创建必要的 glance 镜像以及 anaconda 文件和操作系统 tarball 并设置属性以引用组件的示例。

注意

除了具有设置属性的操作系统镜像外,所有镜像都必须共享。此镜像必须设置为公共。有关更多详细信息,请参阅 bug 2099276

# vmlinuz
openstack image create --container-format bare --disk-format raw --shared \
    --file ./vmlinuz anaconda-kernel-<version>

# initrd/initramfs/ramdisk
openstack image create --container-format bare --disk-format raw --shared \
    --file ./initrd.img anaconda-ramdisk-<version>

# squashfs/stage2
openstack image create --container-format bare --disk-format raw --shared \
    --file ./squashfs.img anaconda-stage2-<version>

KERNEL_ID=$(openstack image show -f value -c id anaconda-kernel-<version>)
RAMDISK_ID=$(openstack image show -f value -c id anaconda-ramdisk-<version>)
STAGE2_ID=$(openstack image show -f value -c id anaconda-stage2-<version>)

# the actual OS image we'll use as our source
openstack image create --container-format bare --disk-format raw --public \
    --property kernel_id=${KERNEL_ID} \
    --property ramdisk_id=${RAMDISK_ID} \
    --property stage2_id=${STAGE2_ID} \
    --property disk_file_extension=.tgz \
    --file ./os-image.tar.gz \
    my-anaconda-based-os-<version>

部署节点

要能够使用 anaconda 部署接口部署节点,节点 instance_info 必须至少具有 image_source,但具体取决于节点的部署方式,必须填充更多字段。

如果您通过 Nova 使用 Ironic,它只会将 image_source 设置在 instance_info 上,因此需要以下镜像属性

  • kernel_id

  • ramdisk_id

  • stage2_id

您可以选择将 anaconda 部署接口通过 --deploy-interface 上传到现有节点

openstack server create --image my-anaconda-based-os-<version> ...

如果您不通过 Nova 使用 Ironic,则可以通过 instance_info 或通过操作系统镜像属性提供除 disk_file_extension 之外的所有属性。 instance_info 中的值将优先于 OS 镜像中指定的值。但是,它们的大部分名称略有更改。

  • kernel_id 镜像属性是 instance_info 中的 kernel

  • ramdisk_id 镜像属性是 instance_info 中的 ramdisk

  • stage2_id 镜像属性是 instance_info 中的 stage2

ks_template 属性在 instance_info 中保持不变。

注意

如果未提供 ks_template,则将使用 anaconda.default_ks_template

这是一个为特定 ironic 节点设置 kickstart 模板的示例

openstack baremetal node set <node> \
    --instance_info ks_template=glance://uuid

最终,要部署您的节点,它必须能够通过 glance 镜像属性或通过 instance_info 找到内核、ramdisk、stage2 文件和操作系统镜像。

openstack baremetal node set <node> \
    --instance_info image_source=glance://uuid

警告

在 Ironic 项目术语中,单词 template 通常指的是提供给部署的文件,Ironic 会向其提供参数以呈现特定输出。Ironic 工作流中一个关键示例,特别是使用此驱动程序时,就是生成的 agent token 会被传递到启动 ramdisk,从而使其能够回叫到 Ironic 并指示状态。此令牌是为每次部署随机生成的,并且是必需的。具体来说,这在模板的 preonerrorpost 步骤中利用。有关 Agent Token 的更多信息,请参阅 Agent Token

独立部署

虽然此部署接口驱动程序围绕着与其他 OpenStack 服务的使用而开发,但它并非显式必需。例如,API 用户可以通过 HTTP(S) URL 显式设置预期的裸机节点 instance_info 字段

baremetal node set <node> \
   --instance_info image_source=<Mirror URL> \
   --instance_info kernel=<Kernel URL> \
   --instance_info ramdisk=<Initial Ramdisk URL> \
   --instance_info stage2=<Installer Stage2 Ramdisk URL>

在这样做时,您可能还希望使用自定义 kickstart 模板,也可以是一个 URL。请参考 ironic 社区提供的模板 ks.cfg.template,并将其用作您自己的 kickstart 的基础,因为它考虑了特定的阶段和适当的回调到 Ironic。

警告

默认模板(用于 kickstart ‘liveimg’ 命令)期望由用户提供 instance_info\image_info 设置,作为基本操作系统镜像。在 anaconda 驱动程序的上下文中,它几乎可以被认为是“stage3”。如果您使用自定义模板,则可能不需要它,但请谨慎操作。有关 liveimg 文件格式、结构和使用的更多信息,请参阅 pykickstart 文档

baremetal node set <node> \
    --instance_info ks_template=<URL>

如果您选择使用 liveimg 和自定义模板,或者如果您希望使用库存模板和 liveimg,则需要提供此设置。

baremetal node set <node> \
    --instance_info image_info=<URL>

警告

如果未将此设置设置为上述有效值,则需要这样做。就像使用 Ironic 的库存模板一样。

在这种情况下,部署模式与 Ironic 与 OpenStack 集成的情况相同,但是,在这种情况下,Ironic 会收集文件并适当地分阶段进行。

此时,您应该能够请求裸机节点进行部署。

使用仓库的独立部署

Anaconda 支持传递仓库,而不是专用 URL 路径,该路径具有 .treeinfo 文件,该文件告诉初始启动脚本从哪里获取各种依赖项,例如将用作 anaconda stage2 ramdisk 的内容。不幸的是,此功能没有很好地记录。

可以在 http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/.treeinfo 处找到一个示例 .treeinfo 文件。

注意

.treeinfo 文件和使用 anaconda 部署接口的部署相关的文件夹结构中,images/install.img 文件代表 stage2 ramdisk。

在希望部署 Centos Stream-9 的情况下,以下内容可能有用。

baremetal node set <node> \
    --instance_info image_source=http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/ \
    --instance_info kernel=http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/images/pxeboot/vmlinuz \
    --instance_info ramdisk=http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/images/pxeboot/initrd.img

设置后,可以通过 instance_info 参数提供 kickstart 模板,然后部署节点。

部署过程

从高级别来看,anaconda 驱动程序的机制以以下流程工作,我们还记录了每个部分的目的和阶段以供参考。

  1. 网络引导程序(例如 iPXE)下载内核和初始 ramdisk。

  2. 内核启动,解压缩初始 ramdisk,并在 ramdisk 内部执行 init。

  3. 初始 ramdisk 启动脚本(例如 Dracut)识别 Ironic 提供的启动配置中的内核命令行参数,并下载第二阶段工件,在本例中称为 stage2 镜像。此镜像包含 Anaconda 和基本依赖项。

  4. Anaconda 下载并解析 kickstart 配置文件,该配置文件也通过内核命令行提供,并执行 kickstart 模板中定义的命令。

  5. 如果 kickstart 模板在其内容中指定,它将下载 liveimg,用作开始使用的基本操作系统镜像。

配置注意事项

在使用 anaconda 部署接口时,可能需要在您的环境中调整一些配置参数。这很大程度上是由于常规默认值设置为基于镜像的部署的低得多值,但 anaconda 部署接口的工作方式,您可能需要进行一些调整。

  • conductor.deploy_callback_timeout 可能需要由大多数 anaconda 部署接口用户进行调整。默认情况下,这是一个计时器,用于查找未向 Ironic 签入的“代理”,或者可能在启动后崩溃或失败的代理。如果达到该值,则当前操作将失败。应将此值设置为超过平均 anaconda 部署时间的秒数。

  • pxe.boot_retry_timeout 也可能会被触发,并导致正在进行的 anaconda 部署被重置,因为它旨在重新启动可能已失败其初始 PXE 操作的节点。根据镜像的大小以及确切部署的内容,可能需要确保此值更高。

限制

  • 此部署接口仅经过使用基于 Red Hat 的操作系统的测试,这些操作系统使用 anaconda。不支持其他系统。

  • 将运行时 TLS 证书注入到 ramdisk 中不受支持。诸如 ramdiskstage2 ramdisk 镜像之类的资源需要在镜像内包含受信任的证书颁发机构 (CA) 证书,或者使用的 Ironic API 端点应使用已知的受信任的证书颁发机构。

  • 部署实例/工作负载的 anaconda 工具不会像由 ironic-python-agent 驱动的 ramdisk 那样向 Ironic 发送心跳。因此,您可能需要调整一些计时器。有关此方面的详细信息,请参阅 配置注意事项