4.8. 支持的镜像自定义
您可以通过在蓝图中添加自定义来自定义镜像,例如:
- 添加一个额外的 RPM 软件包
- 启用服务
- 自定义一个内核命令行参数.
在其他参数之间。您可以在蓝图中使用多个镜像自定义。通过使用自定义配置,您可以将软件包和组添加到默认软件包中不提供的镜像中。要使用这些选项,请在蓝图中配置自定义,并将其导入(推送)到 RHEL 镜像构建器。
4.8.1. 选择一个发行版
您可以使用 distro
字段选择制作镜像时要使用的发行版,或者解决蓝图中的依赖项。如果 distro
留空,它将使用主机发行版。如果没有指定分发,则蓝图将使用主机分发。如果您升级了主机操作系统,则没有发行版集的蓝图使用新的操作系统版本构建镜像。您无法构建一个与 RHEL 镜像构建器主机不同的操作系统镜像。
使用 RHEL 发行版自定义蓝图,以始终构建指定的 RHEL 镜像:
name = "blueprint_name" description = "blueprint_version" version = "0.1" distro = "different_minor_version"
例如:
name = "tmux" description = "tmux image with openssh" version = "1.2.16" distro = "rhel-8.5"
替换 "different_minor_version"
,以构建不同的次版本,例如,如果要构建 RHEL 9.4 镜像,请使用 distro
= "rhel-94"。在 RHEL 9.3 镜像上,您可以构建次版本,如 RHEL 9.3、RHEL 8.9 和更早的版本。
4.8.2. 选择一个软件包组
使用软件包组自定义蓝图。groups
列表描述了您要安装到镜像中的软件包组。软件包组在存储库元数据中定义。每个组都有一个描述性名称,主要用于在用户界面中显示,以及一个 ID,通常在 Kickstart 文件中使用。在这种情况下,您必须使用 ID 来列出组。组有三种不同的方法来对其软件包进行分类:mandatory、default 和 optional。蓝图中只安装了 mandatory 和 default 软件包。无法选择 optional 软件包。
name
属性是必需的字符串,必须与存储库中的软件包组 id 完全匹配。
目前,osbuild-composer
中的软件包和模块之间没有区别。两者都被视为 RPM 软件包依赖项。
使用软件包自定义您的蓝图:
[[groups]] name = "group_name"
使用组名称替换
group_name
。例如:anaconda-tools
:[[groups]] name = "anaconda-tools"
4.8.3. 嵌入容器中
您可以自定义蓝图来嵌入最新的 RHEL 容器中。容器列表包含具有源的对象,以及可选的 tls-verify
属性。
容器列表条目描述了要嵌入到镜像中的容器镜像。
-
source
- 必需的字段。它是对 registry 中的容器镜像的引用。这个示例使用registry.access.redhat.com
注册中心。您可以指定标签版本。默认标签版本为 latest。 -
name
- 本地注册中心中容器的名称。 -
tls-verify
- 布尔值字段。tls-verify 布尔值字段控制传输层安全性。默认值为 true。
嵌入的容器不会自动启动。要启动它,请使用文件自定义创建 systemd
单元文件或 四元组
。
要从
registry.access.redhat.com/ubi9/ubi:latest
和来自主机的容器嵌入容器,请在蓝图中添加以下自定义:[[containers]] source = "registry.access.redhat.com/ubi9/ubi:latest" name = "local-name" tls-verify = true [[containers]] source = "localhost/test:latest" local-storage = true
您可以使用 containers-auth.json
文件访问受保护的容器资源。请参阅 容器注册中心凭证。
4.8.4. 设置镜像主机名
customizations.hostname
是一个可选字符串,可用来配置最终的镜像主机名。此自定义是可选的,如果您未设置它,则蓝图使用默认的主机名。
自定义蓝图以配置主机名:
[customizations] hostname = "baseimage"
4.8.5. 指定其他用户
将用户添加到镜像,并可选择设置其 SSH 密钥。本节的所有字段都是可选的,但 name
除外。
流程
自定义蓝图来将用户添加到镜像中:
[[customizations.user]] name = "USER-NAME" description = "USER-DESCRIPTION" password = "PASSWORD-HASH" key = "PUBLIC-SSH-KEY" home = "/home/USER-NAME/" shell = "/usr/bin/bash" groups = ["users", "wheel"] uid = NUMBER gid = NUMBER
[[customizations.user]] name = "admin" description = "Administrator account" password = "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31L..." key = "PUBLIC SSH KEY" home = "/srv/widget/" shell = "/usr/bin/bash" groups = ["widget", "users", "wheel"] uid = 1200 gid = 1200 expiredate = 12345
GID 是可选的,且必须已存在于镜像中。(可选)软件包创建它,或者蓝图使用
[[customizations.group]
条目创建 GID。将 PASSWORD-HASH 替换为实际的
密码哈希
。要生成密码哈希
,请使用如下命令:$ python3 -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'
使用适当的值替换其他占位符。
输入
name
值,并省略您不需要的任何行。为每个要包含的用户重复这个块。
4.8.6. 指定附加组
为生成的系统镜像指定一个组。name
和 gid
属性都是必需的。
使用组自定义蓝图:
[[customizations.group]] name = "GROUP-NAME" gid = NUMBER
为每个组重复此块。例如:
[[customizations.group]] name = "widget" gid = 1130
4.8.7. 为现有用户设置 SSH 密钥
您可以使用 customizations.sshkey
为最终镜像中的现有用户设置一个 SSH 密钥。user
和 key
属性都是必需的。
通过为现有用户设置 SSH 密钥来自定义蓝图:
[[customizations.sshkey]] user = "root" key = "PUBLIC-SSH-KEY"
例如:
[[customizations.sshkey]] user = "root" key = "SSH key for root"
注意您只能为现有用户配置
customizations.sshkey
自定义。要创建用户并设置 SSH 密钥,请参阅 指定其他用户 自定义。
4.8.8. 附加一个内核参数
您可以将参数添加导引导装载程序内核命令行中。默认情况下,RHEL 镜像构建器将一个默认内核构建到镜像中。但是,您可以通过在蓝图中配置它来自定义内核。
在默认值中附加内核引导选项:
[customizations.kernel] append = "KERNEL-OPTION"
例如:
[customizations.kernel] name = "kernel-debug" append = "nosmt=force"
4.8.9. 使用实时内核构建 RHEL 镜像
要使用实时内核(kernel-rt
)构建 RHEL 镜像,您需要覆盖存储库,以便您可以构建镜像,其中 kernel-rt
被正确地选为默认内核。使用 /usr/share/osbuild-composer/repositories/
目录中的 .json
。然后,您可以部署您构建到系统的镜像,并使用实时内核功能。
实时内核在经过认证可运行 Red Hat Enterprise Linux 的 AMD64 和 Intel 64 服务器平台上运行。
前提条件
- 您的系统已注册,RHEL 已连接到 RHEL for Real Time 订阅。请参阅使用 dnf 安装 RHEL for Real Time。
流程
创建以下目录:
# mkdir /etc/osbuild-composer/repositories/
将
/usr/share/osbuild-composer/repositories/rhel-9.version.json
文件中的内容复制到新目录中:# cp /usr/share/osbuild-composer/repositories/rhel-9.version.json /etc/osbuild-composer/repositories
编辑
/etc/osbuild-composer/repositories/rhel-9.version.json
文件,以便包括 RT 内核存储库:# grep -C 6 kernel-rt /etc/osbuild-composer/repositories/rhel-9.version.json "baseurl": "https://cdn.redhat.com/content/dist/rhel9/9.version/x86_64/appstream/os", "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nm………..=\n=UZd/\n-----END PGP PUBLIC KEY BLOCK-----\n", "rhsm": true, "check_gpg": true }, { "name": "kernel-rt", "baseurl": "https://cdn.redhat.com/content/dist/rhel9/9.version/x86_64/rt/os", "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBEr………fg==\n=UZd/\n-----END PGP PUBLIC KEY BLOCK-----\n", "rhsm": true, "check_gpg": true },
重启服务:
# systemctl restart osbuild-composer
确认
kernel-rt
已包含在.json
文件中:# composer-cli sources list # composer-cli sources info kernel-rt
您将看到之前配置的 URL。
创建一个蓝图。在蓝图中,添加 "[customizations.kernel]" 自定义。以下是在蓝图中包含 "[customizations.kernel]" 的示例:
name = "rt-kernel-image" description = "" version = "2.0.0" modules = [] groups = [] distro = "rhel-9_version_" [[customizations.user]] name = "admin" password = "admin" groups = ["users", "wheel"] [customizations.kernel] name = "kernel-rt" append = ""
将蓝图推送到服务器:
# composer-cli blueprints push rt-kernel-image.toml
从您创建的蓝图构建镜像。以下示例构建一个(
.qcow2
)镜像:# composer-cli compose start rt-kernel-image qcow2
- 将您构建的镜像部署到您要使用实时内核功能的系统。
验证
从镜像引导虚拟机后,验证镜像是否是使用正确选择的
kernel-rt
作为默认内核而构建的。$ cat /proc/cmdline BOOT_IMAGE=(hd0,got3)/vmlinuz-5.14.0-362.24.1..el9_version_.x86_64+rt...
4.8.10. 设置时区和 NTP
您可以自定义蓝图,来配置时区和 网络时间协议 (NTP)。timezone
和 ntpservers
属性都是可选字符串。如果您没有自定义时区,系统将使用 Universal Time, Coordinated (UTC)。如果您没有设置 NTP 服务器,系统将使用默认发行版。
使用您想要的
timezone
和ntpservers
自定义蓝图:[customizations.timezone] timezone = "TIMEZONE" ntpservers = "NTP_SERVER"
例如:
[customizations.timezone] timezone = "US/Eastern" ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
注意有些镜像类型(如 Google Cloud)已有 NTP 服务器设置。您不能覆盖它,因为镜像需要 NTP 服务器来在所选环境中引导。但是,您可以在蓝图中自定义时区。
4.8.11. 自定义区域设置
您可以为生成的系统镜像自定义区域设置。language
和 keyboard
属性都是必需的。您可以添加许多其他语言。您添加的第一个语言是主语言,其他语言是次要语言。
流程
设置区域设置:
[customizations.locale] languages = ["LANGUAGE"] keyboard = "KEYBOARD"
例如:
[customizations.locale] languages = ["en_US.UTF-8"] keyboard = "us"
要列出语言支持的值,请运行以下命令:
$ localectl list-locales
要列出键盘支持的值,请运行以下命令:
$ localectl list-keymaps
4.8.12. 自定义防火墙
为生成的系统镜像设置防火墙。默认情况下,防火墙阻止进入的连接,但明确启用其端口的服务除外,如 sshd
。
如果您不想使用 [customizations.firewall]
或 [customizations.firewall.services]
,可以删除属性,或者将它们设置为空列表 []。如果您只想使用默认的防火墙设置,您可以从蓝图中省略自定义。
Google 和 OpenStack 模板为其环境明确禁用防火墙。您无法通过设置蓝图来覆盖此行为。
流程
使用以下设置自定义蓝图,以打开其他端口和服务:
[customizations.firewall] ports = ["PORTS"]
其中
ports
是包含要打开的端口或一系列端口和协议的可选字符串列表。您可以使用以下格式:port:protocol
格式配置端口。您可以使用portA-portB:protocol
格式配置端口范围。例如:[customizations.firewall] ports = ["22:tcp", "80:tcp", "imap:tcp", "53:tcp", "53:udp", "30000-32767:tcp", "30000-32767:udp"]
您可以使用数字端口或
/etc/services
中的名称来启用或禁用端口列表。在
customizations.firewall.service
部分中指定要启用或禁用的防火墙服务:[customizations.firewall.services] enabled = ["SERVICES"] disabled = ["SERVICES"]
您可以检查可用的防火墙服务:
$ firewall-cmd --get-services
例如:
[customizations.firewall.services] enabled = ["ftp", "ntp", "dhcp"] disabled = ["telnet"]
注意firewall.services
中列出的服务与/etc/services
文件中提供的service-names
不同。
4.8.13. 启用或禁用服务
您可以控制在引导期间要启用哪些服务。有些镜像类型已经启用或禁用了服务,以确保镜像可以正常工作,您无法覆盖此设置。蓝图中的 [customizations.services]
设置不会替换这些服务,但是将服务添加到已在镜像模板中存在的服务列表中。
自定义在引导时要启用哪些服务:
[customizations.services] enabled = ["SERVICES"] disabled = ["SERVICES"]
例如:
[customizations.services] enabled = ["sshd", "cockpit.socket", "httpd"] disabled = ["postfix", "telnetd"]
4.8.14. 指定分区模式
使用 partitioning_mode
变量选择如何对您要构建的磁盘镜像进行分区。您可以使用以下支持的模式自定义镜像:
-
auto-lvm
:它使用原始分区模式,除非有一个或多个文件系统自定义。在这种情况下,它使用 LVM 分区模式。 -
lvm
:它总是使用 LVM 分区模式,即使没有额外的挂载点。 -
raw
:它使用原始分区,即使有一个或多个挂载点。 您可以使用以下自定义,使用
partitioning_mode
变量自定义蓝图:[customizations] partitioning_mode = "lvm"
4.8.15. 指定一个自定义文件系统配置
您可以在蓝图中指定自定义的文件系统配置,因此可以使用特定的磁盘布局创建镜像,而不是默认的布局配置。通过使用蓝图中的非默认布局配置,您可以受益于:
- 安全基准合规性
- 防止磁盘不足错误
- 提高的性能
- 与现有设置的一致
OSTree 系统不支持文件系统自定义,因为 OSTree 镜像有自己的挂载规则,如只读。不支持以下镜像类型:
-
image-installer
-
edge-installer
-
edge-simplified-installer
另外,以下镜像类型不支持文件系统自定义,因为这些镜像类型不创建分区的操作系统镜像:
-
edge-commit
-
edge-container
-
tar
-
container
对于 RHEL 8.10 和 9.4 之前的发行版本,蓝图支持以下 挂载点
及其子目录:
-
/
- root 挂载点 -
/var
-
/home
-
/opt
-
/srv
-
/usr
-
/app
-
/data
-
/tmp
从 RHEL 9.4 和 8.10 发行版本开始,您可以指定任意自定义挂载点,为操作系统保留的特定路径除外。
您不能在以下挂载点及其子目录中指定任意自定义挂载点:
-
/bin
-
/boot/efi
-
/dev
-
/etc
-
/lib
-
/lib64
-
/lost+found
-
/proc
-
/run
-
/sbin
-
/sys
-
/sysroot
-
/var/lock
-
/var/run
您可以在蓝图中为 /usr
自定义挂载点自定义文件系统,但不允许为其子目录自定义文件系统。
从 RHEL 9.0 发行版开始,才支持使用 CLI 自定义挂载点。在之前的发行版本中,您只能将 root
分区指定为挂载点,并将 size
参数指定为镜像大小的别名。
如果您在自定义镜像中有多个分区,您可以在 LVM 上创建带有自定义文件系统分区的镜像,并在运行时调整这些分区大小。为此,您可以在蓝图中指定一个自定义的文件系统配置,因此可以创建具有所需磁盘布局的镜像。默认文件系统布局保持不变 - 如果您使用没有文件系统自定义的普通镜像,cloud-init
会调整 root 分区的大小。
蓝图会自动将文件系统自定义转换为 LVM 分区。
您可以使用自定义文件蓝图自定义来创建新文件或替换现有文件。您指定的文件的父目录必须存在,否则镜像构建会失败。通过在 [[customizations.directories]]
自定义中指定它来确保父目录存在。
如果您将文件自定义与其他蓝图自定义相结合,这可能会影响其他自定义的功能,或者可能会覆盖当前的文件自定义。
4.8.15.1. 在蓝图中指定自定义文件
使用 [[customizations.files]]
蓝图自定义,您可以:
- 创建新文本文件。
- 修改现有文件。警告:这可能会覆盖现有内容。
- 为您要创建的文件设置用户和组所有权。
- 以八进制格式设置模式权限。
您不能创建或替换以下文件:
-
/etc/fstab
-
/etc/shadow
-
/etc/passwd
-
/etc/group
您可以使用 [[customizations.files]]
和 [[customizations.directories]]
蓝图自定义在镜像中创建自定义文件和目录。您只能在 /etc
目录中使用这些自定义。
这些蓝图自定义被所有镜像类型支持,但部署 OSTree 提交的镜像类型除外,如 edge-raw-image
、edge-installer
和edge-simplified-installer
。
如果您将已设置了 mode
、user
或 group
的镜像中已存在的目录路径与 customizations.directories
一起使用,则镜像构建无法防止更改现有目录的所有权或权限。
4.8.15.2. 在蓝图中指定自定义目录
使用 [[customizations.directory]]
蓝图自定义,您可以:
- 创建新目录。
- 为您要创建的目录设置用户和组所有权。
- 以八进制格式设置目录模式权限。
- 确保根据需要创建父目录。
使用 [[customizations.files]]
蓝图自定义,您可以:
- 创建新文本文件。
- 修改现有文件。警告:这可能会覆盖现有内容。
- 为您要创建的文件设置用户和组所有权。
- 以八进制格式设置模式权限。
您不能创建或替换以下文件:
-
/etc/fstab
-
/etc/shadow
-
/etc/passwd
-
/etc/group
以下自定义可用:
在蓝图中自定义文件系统配置:
[[customizations.filesystem]] mountpoint = "MOUNTPOINT" minsize = MINIMUM-PARTITION-SIZE
MINIMUM-PARTITION-SIZE
值没有默认大小格式。蓝图自定义支持以下值和单位:kB 到 TB 和 KiB 到 TiB。例如,您可以以字节为单位定义挂载点大小:[[customizations.filesystem]] mountpoint = "/var" minsize = 1073741824
使用单位定义挂载点大小。例如:
[[customizations.filesystem]] mountpoint = "/opt" minsize = "20 GiB"
[[customizations.filesystem]] mountpoint = "/boot" minsize = "1 GiB"
通过设置
minsize
来定义最小分区。例如:[[customizations.filesystem]] mountpoint = "/var" minsize = 2147483648
使用
[[customizations.directories]]
在镜像的/etc
目录下创建自定义目录:[[customizations.directories]] path = "/etc/directory_name" mode = "octal_access_permission" user = "user_string_or_integer" group = "group_string_or_integer" ensure_parents = boolean
蓝图条目如下所述:
-
path
- 必需 - 输入您要创建的目录的路径。它必须是/etc
目录下的绝对路径。 -
mode
- 可选 - 以八进制格式设置目录的访问权限。如果没有指定权限,则默认为 0755。前面的零是可选的。 -
user
- 可选 - 将用户设置为目录的所有者。如果没有指定用户,则默认为root
。您可以将用户指定为字符串或整数。 -
group
- 可选 - 将组设置为目录的所有者。如果没有指定组,则默认为root
。您可以将组指定为字符串或整数。 -
ensure_parents
- 可选 - 指定是否要根据需要创建父目录。如果没有指定值,则默认为false
。
-
使用
[[customizations.directories]]
在镜像的/etc
目录下创建自定义文件:[[customizations.files]] path = "/etc/directory_name" mode = "octal_access_permission" user = "user_string_or_integer" group = "group_string_or_integer" data = "Hello world!"
蓝图条目如下所述:
-
path
- 必需 - 输入您要创建的文件的路径。它必须是/etc
目录下的绝对路径。 -
模式
可选 - 以八进制格式设置对文件的访问权限。如果没有指定权限,则默认为 0644。前面的零是可选的。 -
user
- 可选 - 将用户设置为文件所有者。如果没有指定用户,则默认为root
。您可以将用户指定为字符串或整数。 -
group
- 可选 - 将组设置为文件所有者。如果没有指定组,则默认为root
。您可以将组指定为字符串或整数。 -
data
- 可选 - 指定纯文本文件的内容。如果没有指定内容,它会创建一个空文件。
-