创建自定义 RHEL 系统镜像


Red Hat Enterprise Linux 8

在 Red Hat Enterprise Linux 8 上使用 RHEL 镜像构建器创建自定义系统镜像

Red Hat Customer Content Services

摘要

RHEL 镜像构建器是一个创建部署就绪的自定义系统镜像的工具:安装磁盘、虚拟机、特定于云提供商的镜像等。通过使用 RHEL 镜像构建器,如果与手动过程相比,您可以更快地创建这些镜像,因为它消除了每种输出类型所需的特定配置。

对红帽文档提供反馈

我们感谢您对我们文档的反馈。让我们了解如何改进它。

通过 Jira 提交反馈(需要帐户)

  1. 登录到 Jira 网站。
  2. 单击顶部导航栏中的 Create
  3. Summary 字段中输入描述性标题。
  4. Description 字段中输入您对改进的建议。包括文档相关部分的链接。
  5. 点对话框底部的 Create

第 1 章 RHEL 镜像构建器描述

要部署一个系统,请创建一个系统镜像。要创建 RHEL 系统镜像,请使用 RHEL 镜像构建器工具。您可以使用 RHEL 镜像构建器创建 RHEL 的自定义系统镜像,包括为在云平台上的部署准备的系统镜像。RHEL 镜像构建器自动为每种输出类型处理配置详情,因此比手动创建镜像方法更容易和更快地使用。您可以使用 composer-cli 工具中的命令行或 RHEL web 控制台中的图形用户界面来访问 RHEL 镜像构建器功能。

注意

从 RHEL 8.3 开始,osbuild-composer 后端替换了 lorax-composer。新服务为镜像构建提供 REST API。

1.1. RHEL 镜像构建器术语

RHEL 镜像构建器使用以下概念:

Blueprint

Blueprint 是自定义系统镜像的描述。它列出了将成为系统一部分的软件包和自定义。您可以使用自定义编辑蓝图,并将其保存为特定版本。当从蓝图创建系统镜像时,镜像与 RHEL 镜像构建器界面中的蓝图相关联。

以 TOML 格式创建蓝图。

Compose
Compose 是基于特定蓝图的特定版本的系统镜像的单独构建。作为一个术语,Compose 代表系统镜像以及来自其创建、输入、元数据和进程本身的日志。
Customizations
Customizations 是不是软件包的镜像的规范。这包括用户、组和 SSH 密钥。

1.2. RHEL 镜像构建器输出格式

RHEL 镜像构建器可以以下表中显示的多种输出格式创建镜像。

Expand
表 1.1. RHEL 镜像构建器输出格式
描述CLI 名称文件扩展名

QEMU 镜像

qcow2

.qcow2

磁盘归档

tar

.tar

Amazon Web Services

raw

.raw

Microsoft Azure

vhd

.vhd

Google Cloud Platform

gce

.tar.gz

VMware vSphere

vmdk

.vmdk

VMware vSphere

ova

.ova

Openstack

openstack

.qcow2

用于边缘提交的 RHEL

edge-commit

.tar

用于边缘容器的 RHEL

edge-container

.tar

用于边缘安装程序的 RHEL

edge-installer

.iso

RHEL for Edge Raw 镜像

edge-raw-image

.raw.xz

RHEL for Edge Simplified Installer

edge-simplified-installer

.iso

RHEL for Edge AMI

edge-ami

.ami

RHEL for Edge VMDK

edge-vsphere

.vmdk

RHEL 安装程序

image-installer

.iso

Oracle 云基础架构

.oci

.qcow2

要检查支持的类型,请运行以下命令:

# composer-cli compose types
Copy to Clipboard Toggle word wrap

1.3. 支持的用于镜像构建的构架

RHEL 镜像构建器支持为以下架构构建镜像:

  • AMD 和 Intel 64 位(x86_64)
  • ARM64 (aarch64)
  • IBM Z (s390x)
  • IBM POWER 系统

但是,RHEL 镜像构建器不支持多架构构建。它仅构建运行在相同系统架构上的镜像。例如,如果 RHEL 镜像构建器运行在 x86_64 系统上,它只能为 x86_64 架构构建镜像。

第 2 章 安装 RHEL 镜像构建器

在使用 RHEL 镜像构建器前,您必须安装它。

2.1. RHEL 镜像构建器系统要求

运行 RHEL 镜像构建器的主机必须满足以下要求:

Expand
表 2.1. RHEL 镜像构建器系统要求
参数最低要求值

系统类型

一个专用的主机或虚拟机。请注意,RHEL 镜像构建器在容器中不支持,包括 Red Hat Universal Base Images (UBI)。

处理器

2 个内核

内存

4 GiB

磁盘空间

'/var/cache/' 文件系统中有 20 GiB 可用空间

访问权限

root

网络

到 Red Hat Content Delivery Network (CDN)的互联网连接。

注意

如果您没有互联网连接,请在隔离网络中使用 RHEL 镜像构建器。为此,您必须覆盖默认存储库以指向本地存储库,来不连接到 Red Hat Content Delivery Network (CDN)。确保您的内容在内部镜像了或使用 Red Hat Satellite。

2.2. 安装 RHEL 镜像构建器

安装 RHEL 镜像构建器以访问所有 osbuild-composer 软件包功能。

先决条件

  • 您已登陆到要在其上安装 RHEL 镜像构建器的 RHEL 主机。
  • 主机已订阅到 Red Hat Subscription Manager (RHSM)或 Red Hat Satellite。
  • 您已启用了 BaseOSAppStream 存储库,以便能安装 RHEL 镜像构建器软件包。

流程

  1. 安装 RHEL 镜像构建器和其他必要的软件包:

    # yum install osbuild-composer composer-cli cockpit-composer
    Copy to Clipboard Toggle word wrap
    • osbuild-composer - 一个构建自定义 RHEL 操作系统镜像的服务。
    • composer-cli- 这个软件包提供对 CLI 界面的访问。
    • cockpit-composer - 这个软件包提供对 Web UI 界面的访问。Web 控制台作为 cockpit-composer 软件包的依赖项安装。
  2. 启用并启动 RHEL 镜像构建器套接字:

    # systemctl enable --now osbuild-composer.socket
    Copy to Clipboard Toggle word wrap
  3. 如果要在 web 控制台中使用 RHEL 镜像构建器,请启用并启动它。

    # systemctl enable --now cockpit.socket
    Copy to Clipboard Toggle word wrap

    osbuild-composercockpit 服务在第一次访问时自动启动。

  4. 加载 shell 配置脚本,以便 composer-cli 命令的自动完成功能立即开始工作,而无需退出,然后再次登录:

    $ source /etc/bash_completion.d/composer-cli
    Copy to Clipboard Toggle word wrap
重要

osbuild-composer 软件包是新的后端引擎,它将是从 Red Hat Enterprise Linux 8.3 及更高版本开始的所有新功能的首选默认和重点。之前的后端 lorax-composer 软件包被视为已弃用,将只接收 Red Hat Enterprise Linux 8 生命周期剩余部分所选定的修复,并将在以后的主发行版本中被忽略。建议卸载 lorax-composer ,使用 osbuild-composer。

验证

  • 通过运行 composer-cli 来验证安装是否正常工作:

    # composer-cli status show
    Copy to Clipboard Toggle word wrap

故障排除

您可以使用系统日志来跟踪 RHEL 镜像构建器活动。此外,您还可以在文件中找到日志消息。

  • 要查找回溯的日志输出,请运行以下命令:

    $ journalctl | grep osbuild
    Copy to Clipboard Toggle word wrap
  • 要显示本地 worker,如 osbuild-worker@.service,它是一个可启动多个服务实例的模板服务:

    $ journalctl -u osbuild-worker*
    Copy to Clipboard Toggle word wrap
  • 显示运行的服务:

    $ journalctl -u osbuild-composer.service
    Copy to Clipboard Toggle word wrap

2.3. 回到 lorax-composer RHEL 镜像构建器后端

osbuild-composer 后端虽然具有更大的可扩展性,但目前还无法与之前的 lorax-composer 后端功能相媲美。

要回到以前的后端,请按照以下步骤操作:

先决条件

  • osbuild-composer 软件包已安装

流程

  1. 删除 osbuild-composer 后端。

    # yum remove osbuild-composer
    # yum remove weldr-client
    Copy to Clipboard Toggle word wrap
  2. /etc/yum.conf 文件中 ,为 osbuild-composer 软件包添加一个排除项。

    # cat /etc/yum.conf
    [main]
    gpgcheck=1
    installonly_limit=3
    clean_requirements_on_remove=True
    best=True
    skip_if_unavailable=False
    exclude=osbuild-composer weldr-client
    Copy to Clipboard Toggle word wrap
  3. 安装 lorax-composer 软件包。

    # yum install lorax-composer composer-cli
    Copy to Clipboard Toggle word wrap
  4. 启用并启动 lorax-composer 服务,以便在每次重启后启动。

    # systemctl enable --now lorax-composer.socket
    # systemctl start lorax-composer
    Copy to Clipboard Toggle word wrap

第 3 章 配置 RHEL 镜像构建器存储库

要使用 RHEL 镜像构建器,您必须确保配置了存储库。您可以在 RHEL 镜像构建器中使用以下类型的存储库:

官方存储库覆盖
如果您要从 Red Hat Content Delivery Network (CDN)官方存储库(如网络中的自定义镜像)以外的其他位置下载基础系统 RPM。使用官方存储库覆盖会禁用默认存储库,您的自定义镜像必须包含所有必需的软件包。
自定义第三方存储库
使用这些存储库来包括官方 RHEL 软件仓库中没有的软件包。

您可以将自定义第三方源添加到存储库中,并使用 composer-cli 管理这些存储库。

先决条件

  • 您有自定义第三方存储库的 URL。

步骤

  1. 创建一个存储库源文件,如 /root/repo.toml。例如:

    id = "k8s"
    name = "Kubernetes"
    type = "yum-baseurl"
    url = "https://server.example.com/repos/company_internal_packages/"
    check_gpg = false
    check_ssl = false
    system = false
    Copy to Clipboard Toggle word wrap

    type 字段接受以下有效值 yum-baseurlyum-mirrorlistyum-metalink

  2. 以 TOML 格式保存文件。
  3. 将新的第三方源添加到 RHEL 镜像构建器中:

    $ composer-cli sources add <file-name>.toml
    Copy to Clipboard Toggle word wrap

验证

  1. 检查新源是否已成功添加:

    $ composer-cli sources list
    Copy to Clipboard Toggle word wrap
  2. 检查新源内容:

    $ composer-cli sources info <source_id>
    Copy to Clipboard Toggle word wrap

您可以使用可选字段 distro 在自定义第三方源文件中指定发行版列表。在解析镜像构建期间解析依赖项时,存储库文件使用分发字符串列表。

任何指定 rhel-8 的请求都使用这个源。例如,如果您列出软件包并指定 rhel-8,它将包含此源。但是,列出主机发行版的软件包不包括此源。

先决条件

  • 您有自定义第三方存储库的 URL。
  • 您有要指定的发行版的列表。

步骤

  1. 创建一个存储库源文件,如 /root/repo.toml。例如,要指定发行版:

    check_gpg = true
    check_ssl = true
    distros = ["rhel-8"]
    id = "rh9-local"
    name = "packages for RHEL"
    system = false
    type = "yum-baseurl"
    url = "https://local/repos/rhel8/projectrepo/"
    Copy to Clipboard Toggle word wrap
  2. 以 TOML 格式保存文件。
  3. 将新的第三方源添加到 RHEL 镜像构建器中:

    $ composer-cli sources add <file-name>.toml
    Copy to Clipboard Toggle word wrap

验证

  1. 检查新源是否已成功添加:

    $ composer-cli sources list
    Copy to Clipboard Toggle word wrap
  2. 检查新源内容:

    $ composer-cli sources info <source_id>
    Copy to Clipboard Toggle word wrap

3.3. 使用 GPG 检查存储库元数据

要检测和避免损坏的软件包,您可以使用 DNF 软件包管理器检查 RPM 软件包上的 GNU Privacy Guard (GPG)签名,以及检查存储库元数据是否已使用 GPG 密钥进行了签名。

您可以使用密钥 URL 设置 gpgkeys 字段,输入您要通过 https 进行检查的 gpgkey。或者,为了提高安全性,您还可以将整个密钥嵌入到 gpgkeys 字段中,来直接导入它,而不是直接从 URL 获取密钥。

先决条件

  • 您要用作存储库的目录存在,且包含软件包。

步骤

  1. 访问您要创建存储库的文件夹:

    $ cd repo/
    Copy to Clipboard Toggle word wrap
  2. 运行 createrepo_c 来从 RPM 软件包创建存储库:

    $ createrepo_c .
    Copy to Clipboard Toggle word wrap
  3. 访问 repodata 的目录:

    $ cd repodata/
    Copy to Clipboard Toggle word wrap
  4. repomd.xml 文件签名:

    $ gpg -u <_gpg-key-email_> --yes --detach-sign --armor /srv/repo/example/repomd.xml
    Copy to Clipboard Toggle word wrap
  5. 要在存储库中启用 GPG 签名检查:

    1. 在存储库源中设置 check_repogpg = true
    2. 输入您要进行检查的 gpgkey。如果您的密钥可以通过 https 使用,请使用密钥的密钥 URL 设置 gpgkeys 字段。您可以根据需要添加任意数量的 URL 密钥。

      以下是一个示例:

      check_gpg = true
      check_ssl = true
      id = "signed local packages"
      name = "repository_name"
      type = "yum-baseurl"
      url = "https://local/repos/projectrepo/"
      check_repogpg = true
      gpgkeys=["https://local/keys/repokey.pub"]
      Copy to Clipboard Toggle word wrap

      作为替代方案,直接在 gpgkeys 字段中添加 GPG 密钥,例如:

      check_gpg = true
      check_ssl = true
      check_repogpg
      id = "custom-local"
      name = "signed local packages"
      type = "yum-baseurl"
      url = "https://local/repos/projectrepo/"
      gpgkeys=["https://remote/keys/other-repokey.pub",
      '''-----BEGIN PGP PUBLIC KEY BLOCK-----
      …​
      -----END PGP PUBLIC KEY BLOCK-----''']
      Copy to Clipboard Toggle word wrap
      • 如果测试没有找到签名,GPG 工具会显示一个类似如下的错误:

        $ GPG verification is enabled, but GPG signature is not available.
        This may be an error or the repository does not support GPG verification:
        Status code: 404 for http://repo-server/rhel/repodata/repomd.xml.asc (IP: 192.168.1.3)
        Copy to Clipboard Toggle word wrap
      • 如果签名无效,GPG 工具会显示一个类似如下的错误:

        repomd.xml GPG signature verification error: Bad GPG signature
        Copy to Clipboard Toggle word wrap

验证

  • 手动测试存储库的签名:

    $ gpg --verify /srv/repo/example/repomd.xml.asc
    Copy to Clipboard Toggle word wrap

3.4. RHEL 镜像构建器官方存储库覆盖

RHEL 镜像构建器 osbuild-composer 后端不继承位于 /etc/yum.repos.d/ 目录中的系统存储库。相反,它拥有自己的一组在 /usr/share/osbuild-composer/repositories 目录中定义的官方存储库。这包括红帽官方存储库,其中包含要安装附加软件或将已安装的程序基础更新到新版本的基础系统 RPM。如果要覆盖官方存储库,您必须在 /etc/osbuild-composer/repositories/ 中定义覆盖。此目录用于用户定义的覆盖,这里的文件优先于 /usr/share/osbuild-composer/repositories/ 目录中的文件。

配置文件不是 /etc/yum.repos.d/ 中常见的 YUM 存储库格式。相反,它们是 JSON 文件。

3.5. 覆盖系统存储库

您可以在 /etc/osbuild-composer/repositories 目录中为 RHEL 镜像构建器配置自己的存储库覆盖。

注意

在 RHEL 8.5 发行版本中,仓库覆盖的名称为 rhel-8.json。从 RHEL 8.5 开始,名称也会尊重次要版本: rhel-84.jsonrhel-85.json 等等。

先决条件

  • 您有一个可从主机系统访问的自定义存储库。

步骤

  1. 创建 /etc/osbuild-composer/repositories/ 目录来存储存储库覆盖:

    $ sudo mkdir -p /etc/osbuild-composer/repositories
    Copy to Clipboard Toggle word wrap
  2. 使用与 RHEL 版本对应的名称,创建一个 JSON 文件。或者,您还可以从 /usr/share/osbuild-composer/ 中复制用于分发的文件,并修改其内容。

    对于 RHEL 8.9,请使用 /etc/osbuild-composer/repositories/rhel-89.json

  3. 将以下结构添加到 JSON 文件中。仅以字符串格式指定以下属性之一:

    • baseurl - 存储库的基本 URL。
    • metalink - 包含有效镜像存储库列表的 metalink 文件的 URL。
    • mirrorlist - 包含有效镜像存储库列表的 mirrorlist 文件的 URL。其余的字段(如 gpgkey )和 metadata_expire 是可选的。

      例如:

      {
           "x86_64": [
              {
                  "name": "baseos",
                  "baseurl": "http://mirror.example.com/composes/released/RHEL-8/8.0/BaseOS/x86_64/os/",
                  "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n (…​)",
                  "check_gpg": true
              }
          ]
      }
      Copy to Clipboard Toggle word wrap

      或者,您可以通过将 rhel-version.json 替换为 RHEL 版本(例如:rhel-8.json)来复制用于分发的 JSON 文件。

      $  cp /usr/share/osbuild-composer/repositories/rhel-version.json /etc/osbuild-composer/repositories/
      Copy to Clipboard Toggle word wrap
  4. 可选:验证 JSON 文件:

    $ json_verify < /etc/osbuild-composer/repositories/rhel-version.json
    Copy to Clipboard Toggle word wrap
  5. 编辑 rhel-8.json 文件中的 baseurl 路径,并保存。例如:

    $ /etc/osbuild-composer/repositories/rhel-version.json
    Copy to Clipboard Toggle word wrap
  6. 重启 osbuild-composer.service

    $ sudo systemctl restart osbuild-composer.service
    Copy to Clipboard Toggle word wrap

验证

  • 检查存储库是否指向正确的 URL:

    $ cat /etc/yum.repos.d/redhat.repo
    Copy to Clipboard Toggle word wrap

    您可以看到仓库指向从 /etc/yum.repos.d/redhat.repo 文件复制的正确 URL。

3.6. 覆盖需要订阅的系统存储库

您可以设置 osbuild-composer 服务,以使用 /etc/yum.repos.d/redhat.repo 文件中定义的系统订阅。要使用 osbuild-composer 中的系统订阅,请定义一个具有以下详情的存储库覆盖:

  • /etc/yum.repos.d/redhat.repo 中定义的存储库相同的 baseurl
  • JSON 对象中定义的 "rhsm": true 值。

    注意

    osbuild-composer 不自动使用 /etc/yum.repos.d/ 中定义的存储库。您需要手动将它们指定为系统存储库覆盖,或使用 composer-cli 将其指定为附加 。"BaseOS"和"AppStream"存储库通常使用系统存储库覆盖,而所有其他存储库则使用 composer-cli 源。

先决条件

  • 您的系统有一个在 /etc/yum.repos.d/redhat.repo 中定义的订阅
  • 您已创建了一个存储库覆盖。请参阅 覆盖系统存储库

步骤

  1. /etc/yum.repos.d/redhat.repo 文件中获取 baseurl

    # cat /etc/yum.repos.d/redhat.repo
    [AppStream]
    name = AppStream mirror example
    baseurl = https://mirror.example.com/RHEL-8/8.0/AppStream/x86_64/os/
    enabled = 1
    gpgcheck = 0
    sslverify = 1
    sslcacert = /etc/pki/ca1/ca.crt
    sslclientkey = /etc/pki/ca1/client.key
    sslclientcert = /etc/pki/ca1/client.crt
    metadata_expire = 86400
    enabled_metadata = 0
    Copy to Clipboard Toggle word wrap
  2. 配置存储库覆盖以使用相同的 baseurl,并将 rhsm 设为 true:

    {
        "x86_64": [
            {
                "name": "AppStream mirror example",
                "baseurl": "https://mirror.example.com/RHEL-8/8.0/AppStream/x86_64/os/",
                "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n (…​)",
                "check_gpg": true,
                "rhsm": true
            }
        ]
    }
    Copy to Clipboard Toggle word wrap
  3. 重启 osbuild-composer.service

    $ sudo systemctl restart osbuild-composer.service
    Copy to Clipboard Toggle word wrap

3.7. 配置 Satellite CV ,并将其用作内容源

您可以使用 Satellite 的内容视图(CV)作为存储库来使用 RHEL 镜像构建器构建镜像。为此,在注册到 Satellite 的主机上手动配置存储库引用,以便能够从 Satellite 存储库检索,而不是 Red Hat Content Delivery Network (CDN)官方存储库。

先决条件

  • 您已安装了 RHEL 镜像构建器。请参阅安装 RHEL 镜像构建器
  • 您在注册到 Satellite 6 的主机上使用 RHEL 镜像构建器。请参阅 linkhttps://docs.redhat.com/en/documentation/red_hat_satellite/6.7/html/provisioning_guide/index#using-an-image-builder-image-for-provisioning[Using 一个 RHEL image builder image for Provisioning]。

流程

  1. 从您当前配置的存储库中找到存储库 URL:

    $ sudo yum -v repolist "-baseos-rpms" | grep -i repo-baseurl
      Repo-baseurl :
    Copy to Clipboard Toggle word wrap

    以下输出是一个示例:

    https://satellite6.example.com/pulp/content/YourOrg/YourEnv/YourCV/content/dist/rhel8/8/x86_64/baseos/os
    Copy to Clipboard Toggle word wrap
  2. 将硬编码的存储库修改为 Satellite 服务器。

    1. 创建具有 0755 权限的存储库目录:

      $ sudo mkdir -pvm 0755 /etc/osbuild-composer/repositories
      Copy to Clipboard Toggle word wrap
    2. /usr/share/osbuild-composer/repositories/*.json 中的内容复制到您创建的目录中:

      $ sudo cp /usr/share/osbuild-composer/repositories/*.json /etc/osbuild-composer/repositories/
      Copy to Clipboard Toggle word wrap
    3. 通过 /content/dist/* 行更新 Satellite URL 和文件内容:

      $ sudo sed -i -e 's|cdn.redhat.com|satellite6.example.com/pulp/content/YourOrg/YourEnv/YourCV|' /etc/osbuild-composer/repositories/*.json
      Copy to Clipboard Toggle word wrap
    4. 验证配置是否已被正确替换:

      $ sudo vi /etc/osbuild-composer/repositories/rhel-8.json
      Copy to Clipboard Toggle word wrap
  3. 重启服务:

    $ sudo systemctl restart osbuild-worker@1.service osbuild-composer.service
    Copy to Clipboard Toggle word wrap
  4. 覆盖红帽镜像构建器配置中所需的系统存储库,并使用 Satellite 存储库的 URL 作为 baseurl。请参阅 覆盖系统存储库

配置 RHEL 镜像构建器,以使用 Satellite 的内容视图(CV)作为存储库来构建您的自定义镜像。

先决条件

流程

  1. 在 Satellite Web UI 中,导航到 Content > Products,选择您的 Product 并点击您要使用的存储库。
  2. 在 Published 字段中搜索安全 URL (HTTPS),并复制它。
  3. 使用您复制的 URL 作为红帽镜像构建器存储库的 baseurl。请参阅 在 RHEL 镜像构建器中添加自定义第三方存储库

RHEL 镜像构建器是一个创建自定义系统镜像的工具。要控制 RHEL 镜像构建器并创建自定义系统镜像,您可以使用命令行(CLI)或 Web 控制台界面。

4.1. RHEL 镜像构建器命令行界面简介

您可以使用 RHEL 镜像构建器命令行界面(CLI)创建蓝图,方法是运行带有合适的选项和子命令的 composer-cli 命令。

命令行的工作流可以总结如下:

  1. 创建蓝图或将现有蓝图定义导出(保存)到纯文本文件中
  2. 在文本编辑器中编辑这个文件
  3. 将蓝图文本文件重新导回到镜像构建器中
  4. 运行 compose 来从蓝图构建镜像
  5. 导出镜像文件以下载它

除了创建蓝图的基本子命令外,composer-cli 命令还提供了许多子命令来检查配置的蓝图和组成的状态。

4.2. 以非 root 用户身份使用 RHEL 镜像构建器

要以非 root 身份运行 composer-cli 命令,该用户必须在 weldr 组中。

先决条件

  • 您已创建了一个用户

流程

  • 要在 weldrroot 组中添加用户,请运行以下命令:

    $ sudo usermod -a -G weldr user
    $ newgrp weldr
    Copy to Clipboard Toggle word wrap

4.3. 使用命令行创建蓝图

您可以使用 RHEL 镜像构建器命令行界面(CLI)创建一个新蓝图。蓝图描述了最终的镜像及其自定义,如软件包和内核自定义。

先决条件

  • 您以 root 用户身份登录,或者是 weldr 组成员的用户身份登录

流程

  1. 创建一个包含以下内容的纯文本文件:

    name = "BLUEPRINT-NAME"
    description = "LONG FORM DESCRIPTION TEXT"
    version = "0.0.1"
    modules = []
    groups = []
    Copy to Clipboard Toggle word wrap

    用您的蓝图的名称和描述替换 BLUEPRINT-NAMELONG FORM DESCRIPTION TEXT

    根据 Semantic Versioning 方案,将 0.0.1 替换为版本号。

  2. 对于您要包含在蓝图中的每个软件包,请在文件中添加以下行:

    [[packages]]
    name = "package-name"
    version = "package-version"
    Copy to Clipboard Toggle word wrap

    使用软件包名称替换 package-name,如 httpdgdb-doccoreutils

    可选,将 package-version 替换为要使用的版本。此字段支持 dnf 版本规范:

    • 对于特定版本,请使用确切的版本号,如 8.7.0
    • 对于最新可用版本,请使用星号 *
    • 对于最新的次版本,请使用以下格式,如 8.*。
  3. 自定义蓝图以满足您的需要。例如,禁用 Simultaneous Multi Threading (SMT),在蓝图文件中添加以下行:

    [customizations.kernel]
    append = "nosmt=force"
    Copy to Clipboard Toggle word wrap

    有关其他可用的定制信息,请参阅 支持的镜像自定义

    请注意,[][[]] 是以 TOML 表示的不同的数据结构。

    • [customizations.kernel] 标头代表一个由一组键及其相应的值对定义的表,例如:append = "nosmt=force"
    • [[packages]] 标头代表表数组。第一个实例定义数组及其第一个表元素,例如 name = "package-name"version = "package-version",每个后续实例都按照您定义它们的顺序创建并定义一个新的表元素。
  4. 将文件保存为 例如 BLUEPRINT-NAME.toml,并关闭文本编辑器。
  5. 可选:检查蓝图 TOML 文件中的所有设置是否已被正确解析。保存蓝图,并将保存的输出与输入文件进行比较:

    # composer-cli blueprints save BLUEPRINT-NAME.toml
    Copy to Clipboard Toggle word wrap
    1. BLUEPRINT-NAME.toml 保存的文件与输入文件进行比较。
  6. 推送蓝图:

    # composer-cli blueprints push BLUEPRINT-NAME.toml
    Copy to Clipboard Toggle word wrap

    BLUEPRINT-NAME 替换为您在前面步骤中使用的值。

    注意

    以非 root 身份运行 composer-cli 命令创建镜像,请将您的用户添加到 weldrroot 组中。

    # usermod -a -G weldr user
    $ newgrp weldr
    Copy to Clipboard Toggle word wrap

验证

  • 列出现有的蓝图以验证蓝图是否已推送并已存在:

    # composer-cli blueprints list
    Copy to Clipboard Toggle word wrap
  • 显示您刚刚添加的蓝图配置:

    # composer-cli blueprints show BLUEPRINT-NAME
    Copy to Clipboard Toggle word wrap
  • 检查蓝图中列出的组件和版本是否有效:

    # composer-cli blueprints depsolve BLUEPRINT-NAME
    Copy to Clipboard Toggle word wrap

    如果 RHEL 镜像构建器无法解决自定义存储库中软件包的依赖项,请清除 osbuild-composer 缓存:

    $ sudo rm -rf /var/cache/osbuild-composer/*
    $ sudo systemctl restart osbuild-composer
    Copy to Clipboard Toggle word wrap

4.4. 使用命令行编辑蓝图

您可以在命令行中编辑现有蓝图,例如添加新软件包或定义新组,并创建自定义镜像。

先决条件

  • 您已创建了一个蓝图

流程

  1. 列出现有的蓝图:

    # composer-cli blueprints list
    Copy to Clipboard Toggle word wrap
  2. 将蓝图保存到一个本地文本文件中:

    # composer-cli blueprints save BLUEPRINT-NAME
    Copy to Clipboard Toggle word wrap
  3. 使用文本编辑器编辑 BLUEPRINT-NAME.toml 文件并进行更改。
  4. 在完成编辑前,请验证该文件是否是一个有效的蓝图:

    1. 如果存在,从蓝图中删除以下行:

      packages = []
      Copy to Clipboard Toggle word wrap
    2. 增加版本号,例如,从 0.0.1 增加到 0.1.0。请记住,RHEL 镜像构建器蓝图版本必须使用 Semantic Versioning 方案。请注意,如果您没有更改版本,补丁版本组件会自动增加。
  5. 保存文件并关闭文本编辑器。
  6. 将蓝图推送回 RHEL 镜像构建器:

    # composer-cli blueprints push BLUEPRINT-NAME.toml
    Copy to Clipboard Toggle word wrap
    注意

    要将蓝图导回到 RHEL 镜像构建器,请提供包括 .toml 扩展名的文件名,而在其他命令中则只使用蓝图名称。

验证

  1. 要验证上传到 RHEL 镜像构建器的内容是否与您编辑的内容匹配,请列出蓝图的内容:

    # composer-cli blueprints show BLUEPRINT-NAME
    Copy to Clipboard Toggle word wrap
  2. 检查蓝图中列出的组件和版本是否有效:

    # composer-cli blueprints depsolve BLUEPRINT-NAME
    Copy to Clipboard Toggle word wrap

您可以使用 RHEL 镜像构建器命令行界面构建一个自定义 RHEL 镜像。为此,您必须指定蓝图和镜像类型。可选,您还可以指定一个发行版。如果没有指定发行版,它将使用与主机系统一样的发行版和版本。架构也与主机上的架构一样。

先决条件

流程

  1. 可选:列出您可以创建的镜像格式:

    # composer-cli compose types
    Copy to Clipboard Toggle word wrap
  2. 启动 compose:

    # composer-cli compose start BLUEPRINT-NAME IMAGE-TYPE
    Copy to Clipboard Toggle word wrap

    BLUEPRINT-NAME 替换为蓝图的名称,将 IMAGE-TYPE 替换为镜像的类型。有关可用值,请查看 composer-cli compose types 命令的输出。

    compose 进程在后台启动,并显示 composer Universally Unique Identifier (UUID)。

  3. 镜像创建最多可能需要十分钟才能完成。

    检查 Compose 的状态:

    # composer-cli compose status
    Copy to Clipboard Toggle word wrap

    完成的 compose 显示 FINISHED 状态值。要识别列表中您的 compose,请使用其 UUID。

  4. 完成 compose 过程后,下载生成的镜像文件:

    # composer-cli compose image UUID
    Copy to Clipboard Toggle word wrap

    使用前面步骤中显示的 UUID 值替换 UUID。

验证

创建镜像后,您可以使用以下命令检查镜像的创建进度:

  • 下载镜像的元数据以获取 compose 的元数据的 .tar 文件:

    $ sudo composer-cli compose metadata UUID
    Copy to Clipboard Toggle word wrap
  • 下载镜像的日志:

    $ sudo composer-cli compose logs UUID
    Copy to Clipboard Toggle word wrap

    该命令会创建一个 .tar 文件,其中包含创建镜像的日志。如果日志为空,您可以检查日志。

  • 检查日志:

    $ journalctl | grep osbuild
    Copy to Clipboard Toggle word wrap
  • 检查镜像的清单:

    $ sudo cat /var/lib/osbuild-composer/jobs/job_UUID.json
    Copy to Clipboard Toggle word wrap

    您可以在日志中找到 job_UUID.json。

4.6. 基本 RHEL 镜像构建器命令行命令

RHEL 镜像构建器命令行界面提供以下子命令。

蓝图操作

列出所有可用的蓝图
# composer-cli blueprints list
Copy to Clipboard Toggle word wrap
显示 TOML 格式的蓝图内容
# composer-cli blueprints show <BLUEPRINT-NAME>
Copy to Clipboard Toggle word wrap
将蓝图内容以 TOML 格式保存(导出)到文件 BLUEPRINT-NAME.toml
# composer-cli blueprints save <BLUEPRINT-NAME>
Copy to Clipboard Toggle word wrap
删除蓝图
# composer-cli blueprints delete <BLUEPRINT-NAME>
Copy to Clipboard Toggle word wrap
将 TOML 格式的蓝图文件推送(导入)到 RHEL 镜像构建器
# composer-cli blueprints push <BLUEPRINT-NAME>
Copy to Clipboard Toggle word wrap

从蓝图制作镜像

列出可用的镜像类型
# composer-cli compose types
Copy to Clipboard Toggle word wrap
启动一个目录
# composer-cli compose start <BLUEPRINT> <COMPOSE-TYPE>
Copy to Clipboard Toggle word wrap
列出所有 compose
# composer-cli compose list
Copy to Clipboard Toggle word wrap
列出所有 compose 及其状态
# composer-cli compose status
Copy to Clipboard Toggle word wrap
取消正在运行的 compose
# composer-cli compose cancel <COMPOSE-UUID>
Copy to Clipboard Toggle word wrap
删除完成的 compose
# composer-cli compose delete <COMPOSE-UUID>
Copy to Clipboard Toggle word wrap
显示有关 compose 的详细信息
# composer-cli compose info <COMPOSE-UUID>
Copy to Clipboard Toggle word wrap
下载 compose 的镜像文件
# composer-cli compose image <COMPOSE-UUID>
Copy to Clipboard Toggle word wrap
更多子命令和选项
# composer-cli help
Copy to Clipboard Toggle word wrap

4.7. RHEL 镜像构建器蓝图格式

RHEL 镜像构建器蓝图以 TOML 格式的纯文本向用户显示。

典型的蓝图文件元素包括:

蓝图元数据
name = "<BLUEPRINT-NAME>"
description = "<LONG FORM DESCRIPTION TEXT>"
version = "<VERSION>"
Copy to Clipboard Toggle word wrap

BLUEPRINT-NAMELONG FORM DESCRIPTION TEXT 字段是您的蓝图的名称和描述。

VERSION 是根据 Semantic Versioning 方案的版本号,只对整个蓝图文件显示一次。

镜像中包含的组
[[groups]]
name = "group-name"
Copy to Clipboard Toggle word wrap

group 条目描述要安装到镜像中的一组软件包。组使用以下软件包类别:

  • Mandatory(必需)
  • Default(默认)
  • 选填

    group-name 是组的名称,例如 anaconda-tools, widget, wheelusers。蓝图安装必需的和默认的软件包。没有选择可选软件包的机制。

镜像中包含的软件包
[[packages]]
name = "<package-name>"
version = "<package-version>"
Copy to Clipboard Toggle word wrap

package-name 是软件包的名称,如 httpdgdb-doccoreutils

package-version 是要使用的版本。此字段支持 dnf 版本规范:

  • 对于特定版本,请使用确切的版本号,如 8.7.0
  • 对于最新的可用版本,请使用星号 *
  • 对于最新的次版本,请使用以下格式,如 8.*。

    为每个要包括的软件包重复这个块。

注意

RHEL 镜像构建器工具中的软件包和模块之间没有区别。两者都被视为 RPM 软件包依赖项。

4.8. 支持的镜像自定义

您可以通过向蓝图中添加自定义来自定义镜像,例如:

  • 添加一个额外的 RPM 软件包
  • 启用一个服务
  • 自定义一个内核命令行参数.

在其他参数之间。您可以在蓝图中使用多个镜像自定义。通过使用自定义,您可以将软件包和组添加到在默认软件包中不可用的镜像中。要使用这些选项,请在蓝图中配置自定义,并将其导入(推送)到 RHEL 镜像构建器。

4.8.1. 选择一个发行版

您可以使用 distro 字段指定在制作镜像或在蓝图中解决依赖项时要使用的发行版。如果 distro 字段留空,蓝图会自动使用主机的操作系统发行版。如果没有指定发行版,蓝图将使用主机分发。当您升级主机操作系统时,没有指定发行版的蓝图使用升级的操作系统版本构建镜像。

您可以在较新的系统上为旧的主版本构建镜像。例如,您可以使用 RHEL 10 主机创建 RHEL 9 和 RHEL 8 镜像。但是,您无法在较旧的系统上为较新的主版本构建镜像。

重要

您无法构建一个与 RHEL 镜像构建器主机不同的操作系统镜像。例如,您无法使用 RHEL 系统构建 Fedora 或 CentOS 镜像。

  • 自定义带有 RHEL 发行版本的蓝图,以始终构建指定的 RHEL 镜像:

    name = "blueprint_name"
    description = "blueprint_version"
    version = "0.1"
    distro = "different_minor_version"
    Copy to Clipboard Toggle word wrap

    例如:

    name = "tmux"
    description = "tmux image with openssh"
    version = "1.2.16"
    distro = "rhel-9.5"
    Copy to Clipboard Toggle word wrap

替换 "different_minor_version" ,来构建不同的次版本,例如,如果要构建 RHEL 8.10 镜像,请使用 distro = "rhel-810"。在 RHEL 8.10 镜像上,您可以构建次版本,如 RHEL 8.9 及更早版本。

4.8.2. 选择一个软件包组

自定义带有软件包组的蓝图。groups 列表描述您要安装到镜像中的软件包组。软件包组在存储库元数据中定义。每个组都有一个描述性名称,主要用于在用户界面中显示,以及一个通常在 Kickstart 文件中使用的 ID。在这种情况下,您必须使用 ID 来列出组。组有三种不同的对其软件包进行分类的方法:强制、默认和可选。蓝图中只安装了强制和默认软件包。无法选择可选软件包。

name 属性是必需的字符串,必须与存储库中的软件包组 id 完全匹配。

注意

目前,osbuild-composer 中的软件包和模块之间没有区别。两者都被视为 RPM 软件包依赖项。

  • 自定义带有软件包的蓝图:

    [[groups]]
    name = "group_name"
    Copy to Clipboard Toggle word wrap

    使用组的名称替换 group_name。例如:anaconda-tools

    [[groups]]
    name = "anaconda-tools"
    Copy to Clipboard Toggle word wrap

4.8.3. 嵌入容器

您可以自定义蓝图来嵌入最新的 RHEL 容器。容器列表包含带有源的对象,以及可选的 tls-verify 属性。

容器列表条目描述要嵌入到镜像中的容器镜像。

  • source - 必需的字段。它是对 registry 中的容器镜像的引用。这个示例使用 registry.access.redhat.com registry。您可以指定标签版本。默认标签版本为 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
    Copy to Clipboard Toggle word wrap

您可以使用 containers-auth.json 文件访问受保护的容器资源。请参阅 容器注册中心凭证

4.8.4. 设置镜像主机名

customizations.hostname 是一个可选字符串,您可以用来配置最终镜像主机名。此自定义是可选的,如果您未设置它,则蓝图使用默认主机名。

  • 自定义蓝图以配置主机名:

    [customizations]
    hostname = "baseimage"
    Copy to Clipboard Toggle word wrap

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
    Copy to Clipboard Toggle word wrap
    [[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
    Copy to Clipboard Toggle word wrap

    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())'
    Copy to Clipboard Toggle word wrap

    使用适当的值替换其他占位符。

    输入 name 值,并省略您不需要的任何行。

    为每个要包含的用户重复这个块。

4.8.6. 指定附加组

为生成的系统镜像指定一个组。namegid 属性都是必需的。

  • 自定义带有组的蓝图:

    [[customizations.group]]
    name = "GROUP-NAME"
    gid = NUMBER
    Copy to Clipboard Toggle word wrap

    为每个组重复此块。例如:

    [[customizations.group]]
    name = "widget"
    gid = 1130
    Copy to Clipboard Toggle word wrap

4.8.7. 为现有用户设置 SSH 密钥

您可以使用 customizations.sshkey 为最终镜像中的现有用户设置 SSH 密钥。userkey 属性是必需的。

  • 通过为现有用户设置 SSH 密钥来自定义蓝图:

    [[customizations.sshkey]]
    user = "root"
    key = "PUBLIC-SSH-KEY"
    Copy to Clipboard Toggle word wrap

    例如:

    [[customizations.sshkey]]
    user = "root"
    key = "SSH key for root"
    Copy to Clipboard Toggle word wrap
    注意

    您只能为现有用户配置 customizations.sshkey 自定义。要创建用户并设置 SSH 密钥,请参阅 指定其他用户 自定义。

4.8.8. 附加一个内核参数

您可以向引导装载程序内核命令行中附加参数。默认情况下,RHEL 镜像构建器将默认内核构建到镜像中。但是,您可以通过在蓝图中配置它来自定义内核。

  • 在默认值中附加内核引导选项:

    [customizations.kernel]
    append = "KERNEL-OPTION"
    Copy to Clipboard Toggle word wrap

    例如:

    [customizations.kernel]
    name = "kernel-debug"
    append = "nosmt=force"
    Copy to Clipboard Toggle word wrap

4.8.9. 使用实时内核构建 RHEL 镜像

要使用实时内核(kernel-rt)构建 RHEL 镜像,您需要覆盖存储库,以便您然后可以构建一个镜像,其中 kernel-rt 被正确选择为默认内核。使用 /usr/share/osbuild-composer/repositories/ 目录中的 .json。然后,您可以部署您构建到系统的镜像,并使用实时内核功能。

注意

实时内核在经过认证可运行 Red Hat Enterprise Linux 的 AMD64 和 Intel 64 服务器平台上运行。

先决条件

流程

  1. 创建以下目录:

    # mkdir /etc/osbuild-composer/repositories/
    Copy to Clipboard Toggle word wrap
  2. /usr/share/osbuild-composer/repositories/rhel-8.version.json 文件中的内容复制到新目录中:

    # cp /usr/share/osbuild-composer/repositories/rhel-8.version.json /etc/osbuild-composer/repositories
    Copy to Clipboard Toggle word wrap
  3. 编辑 /etc/osbuild-composer/repositories/rhel-8.version.json,使其包含 RT 内核存储库:

    # grep -C 6 kernel-rt /etc/osbuild-composer/repositories/rhel-8.version.json
          "baseurl": "https://cdn.redhat.com/content/dist/rhel8/8.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/rhel8/8.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
        },
    Copy to Clipboard Toggle word wrap
  4. 重启服务:

    # systemctl restart osbuild-composer
    Copy to Clipboard Toggle word wrap
  5. 确认 kernel-rt 已包含在 .json 文件中:

    # composer-cli sources list
    # composer-cli sources info kernel-rt
    Copy to Clipboard Toggle word wrap

    您将看到您之前配置的 URL。

  6. 创建一个蓝图。在蓝图中,添加 "[customizations.kernel]" 自定义。以下是蓝图中包含 "[customizations.kernel]" 的一个示例:

    name = "rt-kernel-image"
    description = ""
    version = "2.0.0"
    modules = []
    groups = []
    distro = "rhel-8_version_"
    [[customizations.user]]
    name = "admin"
    password = "admin"
    groups = ["users", "wheel"]
    [customizations.kernel]
    name = "kernel-rt"
    append = ""
    Copy to Clipboard Toggle word wrap
  7. 将蓝图推送到服务器:

    # composer-cli blueprints push rt-kernel-image.toml
    Copy to Clipboard Toggle word wrap
  8. 从您创建的蓝图中构建镜像。以下示例构建一个(.qcow2)镜像:

    # composer-cli compose start rt-kernel-image qcow2
    Copy to Clipboard Toggle word wrap
  9. 将您构建的镜像部署到您要使用实时内核功能的系统中。

验证

  • 从镜像引导虚拟机后,验证镜像是否是使用正确选择为默认内核的 kernel-rt 构建的。

    $ cat /proc/cmdline
    BOOT_IMAGE=(hd0,got3)/vmlinuz-5.14.0-362.24.1..el8_version_.x86_64+rt...
    Copy to Clipboard Toggle word wrap

4.8.10. 设置时区和 NTP

您可以自定义蓝图来配置时区和 网络时间协议 (NTP)。timezonentpservers 属性是可选字符串。如果您没有自定义时区,系统将使用 Universal Time, Coordinated (UTC)。如果您没有设置 NTP 服务器,系统将使用默认发行版。

  • 自定义带有您想要的 timezonentpservers 的蓝图:

    [customizations.timezone]
    timezone = "TIMEZONE"
    ntpservers = "NTP_SERVER"
    Copy to Clipboard Toggle word wrap

    例如:

    [customizations.timezone]
    timezone = "US/Eastern"
    ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
    Copy to Clipboard Toggle word wrap
    注意

    有些镜像类型,如 Google Cloud,已经建立了 NTP 服务器。您无法覆盖它,因为镜像需要 NTP 服务器来在所选环境中引导。但是,您可以在蓝图中自定义时区。

4.8.11. 自定义区域设置

您可以为生成的系统镜像自定义区域设置。languagekeyboard 属性是必需的。您可以添加许多其他语言。您添加的第一个语言是主语言,其他语言是次要语言。

流程

  • 设置区域设置:

    [customizations.locale]
    languages = ["LANGUAGE"]
    keyboard = "KEYBOARD"
    Copy to Clipboard Toggle word wrap

    例如:

    [customizations.locale]
    languages = ["en_US.UTF-8"]
    keyboard = "us"
    Copy to Clipboard Toggle word wrap
  • 要列出语言支持的值,请运行以下命令:

    $ localectl list-locales
    Copy to Clipboard Toggle word wrap
  • $ localectl list-keymaps
    Copy to Clipboard Toggle word wrap

4.8.12. 

注意

  • [customizations.firewall]
    ports = ["PORTS"]
    Copy to Clipboard Toggle word wrap

    [customizations.firewall]
    ports = ["22:tcp", "80:tcp", "imap:tcp", "53:tcp", "53:udp", "30000-32767:tcp", "30000-32767:udp"]
    Copy to Clipboard Toggle word wrap

  • [customizations.firewall.services]
    enabled = ["SERVICES"]
    disabled = ["SERVICES"]
    Copy to Clipboard Toggle word wrap
  • $ firewall-cmd --get-services
    Copy to Clipboard Toggle word wrap

    [customizations.firewall.services]
    enabled = ["ftp", "ntp", "dhcp"]
    disabled = ["telnet"]
    Copy to Clipboard Toggle word wrap
    注意

4.8.13. 

  • [customizations.services]
    enabled = ["SERVICES"]
    disabled = ["SERVICES"]
    Copy to Clipboard Toggle word wrap

    [customizations.services]
    enabled = ["sshd", "cockpit.socket", "httpd"]
    disabled = ["postfix", "telnetd"]
    Copy to Clipboard Toggle word wrap

4.8.14. 

警告

[customizations.installer]
unattended = true
sudo-nopasswd = ["user", "%wheel"]
Copy to Clipboard Toggle word wrap

liveimg --url file:///run/install/<_repo_>/liveimg.tar.gz
lang en_US.UTF-8
keyboard us
timezone UTC
zerombr
clearpart --all --initlabel
text
autopart --type=plain --fstype=xfs --nohome
reboot --eject
network --device=link --bootproto=dhcp --onboot=on --activate
Copy to Clipboard Toggle word wrap

%post
echo -e "user\tALL=(ALL)\tNOPASSWD: ALL" > "/etc/sudoers.d/user"
chmod 0440 /etc/sudoers.d/user
echo -e "%wheel\tALL=(ALL)\tNOPASSWD: ALL" > "/etc/sudoers.d/%wheel"
chmod 0440 /etc/sudoers.d/%wheel
restorecon -rvF /etc/sudoers.d
%end
Copy to Clipboard Toggle word wrap

[customizations.installer.kickstart]
contents = """
text --non-interactive
zerombr
clearpart --all --initlabel --disklabel=gpt
autopart --noswap --type=lvm
network --bootproto=dhcp --device=link --activate --onboot=on
"""
Copy to Clipboard Toggle word wrap

4.8.15. 

  • [customizations]
    partitioning_mode = "lvm"
    Copy to Clipboard Toggle word wrap

4.8.16. 

注意

注意

警告

4.8.16.1. 

注意

警告

4.8.16.2. 

注意

  • [[customizations.filesystem]]
    mountpoint = "MOUNTPOINT"
    minsize = MINIMUM-PARTITION-SIZE
    Copy to Clipboard Toggle word wrap

    [[customizations.filesystem]]
    mountpoint = "/var"
    minsize = 1073741824
    Copy to Clipboard Toggle word wrap
  • [[customizations.filesystem]]
    mountpoint = "/opt"
    minsize = "20 GiB"
    Copy to Clipboard Toggle word wrap
    [[customizations.filesystem]]
    mountpoint = "/boot"
    minsize = "1 GiB"
    Copy to Clipboard Toggle word wrap
  • [[customizations.filesystem]]
    mountpoint = "/var"
    minsize = 2147483648
    Copy to Clipboard Toggle word wrap
  • [[customizations.directories]]
    path = "/etc/directory_name"
    mode = "octal_access_permission"
    user = "user_string_or_integer"
    group = "group_string_or_integer"
    ensure_parents = boolean
    Copy to Clipboard Toggle word wrap

  • [[customizations.files]]
    path = "/etc/directory_name"
    mode = "octal_access_permission"
    user = "user_string_or_integer"
    group = "group_string_or_integer"
    data = "Hello world!"
    Copy to Clipboard Toggle word wrap

4.9. 

注意

# composer-cli blueprints depsolve BLUEPRINT-NAME
Copy to Clipboard Toggle word wrap

Expand
表 4.1. 
  

4.10. 

Expand
表 4.2. 
  

第 5 章 

5.1. 

5.2. 

注意

    1. 注意

        • 注意

      1. 注意

5.3. 

5.4. 

5.5. 

第 6 章 

  • $ composer-cli distros list
    Copy to Clipboard Toggle word wrap

    rhel-8
    rhel-84
    rhel-85
    rhel-86
    rhel-87
    rhel-88
    rhel-89
    Copy to Clipboard Toggle word wrap
    注意

6.1. 

name = "<blueprint_name>"
description = "<image-description>"
version = "0.0.1"
modules = []
groups = []
distro = "<distro-version>"
Copy to Clipboard Toggle word wrap

注意

# composer-cli blueprints save EXISTING-BLUEPRINT
Copy to Clipboard Toggle word wrap
  1. name = "blueprint_84"
    description = "A 8.8 base image"
    version = "0.0.1"
    modules = []
    groups = []
    distro = "rhel-88"
    Copy to Clipboard Toggle word wrap
  2. # composer-cli blueprints push EXISTING-BLUEPRINT.toml
    Copy to Clipboard Toggle word wrap
  3. # composer-cli compose start BLUEPRINT-NAME IMAGE-TYPE
    Copy to Clipboard Toggle word wrap

  4. # composer-cli compose status
    Copy to Clipboard Toggle word wrap

  5. # composer-cli compose image UUID
    Copy to Clipboard Toggle word wrap

6.2. 

  • check_gpg = true
    check_ssl = true
    distros = ["<distro-version>"]
    id = "<image-id>"
    name = "<image-name>_"
    system = false
    type = "<image-type>"
    url = "\http://local/repos/rhel-<distro-version>_/<project-repo>/"
    Copy to Clipboard Toggle word wrap

    check_gpg = true
    check_ssl = true
    distros = ["rhel-84"]
    id = "rhel-84-local"
    name = "local packages for rhel-84"
    system = false
    type = "yum-baseurl"
    url = "\http://local/repos/rhel-84/projectrepo/"
    Copy to Clipboard Toggle word wrap

第 7 章 

7.1. 

警告

  1. # composer-cli compose start BLUEPRINT-NAME image-installer
    Copy to Clipboard Toggle word wrap
  2. # composer-cli compose status
    Copy to Clipboard Toggle word wrap

  3. # composer-cli compose list
    Copy to Clipboard Toggle word wrap
  4. # composer-cli compose image UUID
    Copy to Clipboard Toggle word wrap

  1. $ mount -o ro path_to_ISO /mnt
    Copy to Clipboard Toggle word wrap

  2. $ tar ztvf /mnt/liveimg.tar.gz
    Copy to Clipboard Toggle word wrap

7.2. 

警告

  1. $ tar -xf content.tar
    Copy to Clipboard Toggle word wrap

7.3. 

  1. dd if=installer.iso of=/dev/sdX
    Copy to Clipboard Toggle word wrap

第 8 章 

8.1. 

[customizations.openscap]
# If you want to use the data stream from the 'scap-security-guide' package
# the 'datastream' key could be omitted.
# datastream = "/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml"
profile_id = "xccdf_org.ssgproject.content_profile_cis"
Copy to Clipboard Toggle word wrap

# oscap info /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Copy to Clipboard Toggle word wrap

# oscap xccdf generate fix --profile=cis --fix-type=blueprint /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Copy to Clipboard Toggle word wrap

# Blueprint for CIS Red Hat Enterprise Linux 8 Benchmark for Level 2 - Server
#
# Profile Description:
# This profile defines a baseline that aligns to the "Level 2 - Server"
# configuration from the Center for Internet Security® Red Hat Enterprise
# Linux 8 Benchmark™, v3.0.0, released 2023-10-30.
# This profile includes Center for Internet Security®
# Red Hat Enterprise Linux 8 CIS Benchmarks™ content.
#
# Profile ID:  xccdf_org.ssgproject.content_profile_cis
# Benchmark ID:  xccdf_org.ssgproject.content_benchmark_RHEL-8
# Benchmark Version:  0.1.74
# XCCDF Version:  1.2

name = "hardened_xccdf_org.ssgproject.content_profile_cis"
description = "CIS Red Hat Enterprise Linux 8 Benchmark for Level 2 - Server"
version = "0.1.74"

[customizations.openscap]
profile_id = "xccdf_org.ssgproject.content_profile_cis"
# If your hardening data stream is not part of the 'scap-security-guide' package
# provide the absolute path to it (from the root of the image filesystem).
# datastream = "/usr/share/xml/scap/ssg/content/ssg-xxxxx-ds.xml"

[[customizations.filesystem]]
mountpoint = "/home"
size = 1073741824

[[customizations.filesystem]]
mountpoint = "/tmp"
size = 1073741824

[[customizations.filesystem]]
mountpoint = "/var"
size = 3221225472

[[customizations.filesystem]]
mountpoint = "/var/tmp"
size = 1073741824

[[packages]]
name = "aide"
version = "*"

[[packages]]
name = "libselinux"
version = "*"

[[packages]]
name = "audit"
version = "*"

[customizations.kernel]
append = "audit_backlog_limit=8192 audit=1"

[customizations.services]
enabled = ["auditd","crond","firewalld","systemd-journald","rsyslog"]
disabled = []
masked = ["nfs-server","rpcbind","autofs","bluetooth","nftables"]
Copy to Clipboard Toggle word wrap
注意

  • 注意

8.2. 

  1. # oscap xccdf generate fix --profile=<profileID> --fix-type=<blueprint> /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml > cis.toml
    Copy to Clipboard Toggle word wrap

  2. # composer-cli blueprints push <blueprint_name>.toml
    Copy to Clipboard Toggle word wrap
  3. # composer-cli compose start <blueprint_name> <image_type>
    Copy to Clipboard Toggle word wrap

重要

8.3. 

  1. # oscap xccdf generate fix --profile=<profileID> --fix-type=blueprint /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml > <profileID>-tailored.toml
    Copy to Clipboard Toggle word wrap
  2. # Blueprint for CIS Red Hat Enterprise Linux 8 Benchmark for Level 2 - Server
    # ...
    [customizations.openscap.tailoring]
    selected = [ "xccdf_org.ssgproject.content_bind_crypto_policy" ]
    unselected = [ "grub2_password" ]
    Copy to Clipboard Toggle word wrap
  3. # composer-cli blueprints push <blueprintProfileID>-tailored.toml
    Copy to Clipboard Toggle word wrap
  4. # composer-cli compose start <blueprintProfileID> <image_type>
    Copy to Clipboard Toggle word wrap

重要

第 9 章 

  1. name = "system-fips-mode-enabled"
    description = "blueprint with FIPS enabled "
    version = "0.0.1"
    
    [customizations]
    fips = true
    
    [[customizations.user]]
    name = "admin"
    password = "admin"
    groups = ["users", "wheel"]
    Copy to Clipboard Toggle word wrap
  2. # composer-cli blueprints push <blueprint-name>.toml
    Copy to Clipboard Toggle word wrap
  3. # composer-cli blueprints show <blueprint-name>
    Copy to Clipboard Toggle word wrap
  4. # composer-cli blueprints depsolve <blueprint-name>
    Copy to Clipboard Toggle word wrap
  5. # composer-cli compose start \ <blueprint-name> \ <image-type> \
    Copy to Clipboard Toggle word wrap
  6. # composer-cli compose status
    …
    $ <UUID> FINISHED <date> <blueprint-name> <blueprint-version> <image-type>
    Copy to Clipboard Toggle word wrap
  7. # composer-cli compose image <UUID>
    Copy to Clipboard Toggle word wrap

    $ <UUID-image-name.type>: <size> MB
    Copy to Clipboard Toggle word wrap

  1. $ fips-mode-setup --check
    FIPS mode is enabled.
    Copy to Clipboard Toggle word wrap

第 10 章 

10.1. 

10.2. 

  1. $ mkdir cloudinitiso
    $ cd cloudinitiso
    Copy to Clipboard Toggle word wrap
  2. instance-id: citest
    local-hostname: vmname
    Copy to Clipboard Toggle word wrap
  3. #cloud-config
    user: admin
    password: password
    chpasswd: {expire: False}
    ssh_pwauth: True
    ssh_authorized_keys:
      - ssh-rsa AAA...fhHQ== your.email@example.com
    Copy to Clipboard Toggle word wrap

  4. # genisoimage -output cloud-init.iso -volid cidata -joliet -rock user-data meta-data
    
    I: -input-charset not specified, using utf-8 (detected in locale settings)
    Total translation table size: 0
    Total rockridge attributes bytes: 331
    Total directory bytes: 0
    Path table size(bytes): 10
    Max brk space used 0
    183 extents written (0 MB)
    Copy to Clipboard Toggle word wrap
  5. # virt-install \
        --memory 4096 \
        --vcpus 4 \
        --name myvm \
        --disk rhel-8-x86_64-kvm.qcow2,device=disk,bus=virtio,format=qcow2 \
        --disk cloud-init.iso,device=cdrom \
        --os-variant rhel 8 \
        --virt-type kvm \
        --graphics none \
        --import
    Copy to Clipboard Toggle word wrap
  6. Starting install...
    Connected to domain mytestcivm
    ...
    [  OK  ] Started Execute cloud user/final scripts.
    [  OK  ] Reached target Cloud-init target.
    
    Red Hat Enterprise Linux 8 (Ootpa)
    Kernel 4.18.0-221.el8.x86_64 on an x86_64
    Copy to Clipboard Toggle word wrap

第 11 章 

11.1. 

[[containers]]
source = "registry.access.redhat.com/ubi9/ubi:latest"
name =  "local-name"
tls-verify = true
Copy to Clipboard Toggle word wrap

11.2. 

注意

$ systemctl restart osbuild-worker@*
Copy to Clipboard Toggle word wrap

[containers]
auth_file_path = "/etc/osbuild-worker/containers-auth.json"
Copy to Clipboard Toggle word wrap

11.3. 

  1. provider = "container_provider"
    [settings]
    tls_verify = false
    username = "admin"
    password = "your_password"
    Copy to Clipboard Toggle word wrap
  2. name = "simple-container"
    description = "Simple RHEL container"
    version = "0.0.1"
    [[packages]]
    name = "nginx"
    version = "*"
    Copy to Clipboard Toggle word wrap
  3. # composer-cli blueprints push blueprint.toml
    Copy to Clipboard Toggle word wrap
  4. # composer-cli compose start simple-container container "quay.io:8080/osbuild/repository" registry-config.toml
    Copy to Clipboard Toggle word wrap
    • 注意

  1.  You can see details about the container you created, such as:
    - last modified
    - image size
    - the `manifest ID`, that you can copy to the clipboard.
    Copy to Clipboard Toggle word wrap

11.4. 

  1. name = "image"
    description = "A qcow2 image with a container"
    version = "0.0.1"
    distro = "rhel-90"
    [[packages]]
    name = "podman"
    version = "*"
    [[containers]]
    source = "registry.access.redhat.com/ubi9:8080/osbuild/container/container-image@sha256:manifest-ID-from-Repository-tag: tag-version"
    name =  "source-name"
    tls-verify = true
    Copy to Clipboard Toggle word wrap
  2. # composer-cli blueprints push blueprint-image.toml
    Copy to Clipboard Toggle word wrap
  3. # composer-cli start compose image qcow2
    Copy to Clipboard Toggle word wrap
    • 注意

  4. # composer-cli compose status
    Copy to Clipboard Toggle word wrap

  5. # composer-cli compose image UUID
    Copy to Clipboard Toggle word wrap

  1. # podman run -it registry.access.redhat.com/ubi9:8080/osbuild/repository /bin/bash/
    Copy to Clipboard Toggle word wrap

  2. # type -a nginx
    Copy to Clipboard Toggle word wrap

第 12 章 

12.1. 

12.1.1. 

  1. # yum install python3 python3-pip
    Copy to Clipboard Toggle word wrap
  2. # pip3 install awscli
    Copy to Clipboard Toggle word wrap
  3. $ aws configure
    AWS Access Key ID [None]:
    AWS Secret Access Key [None]:
    Default region name [None]:
    Default output format [None]:
    Copy to Clipboard Toggle word wrap
  4. $ BUCKET=bucketname
    $ aws s3 mb s3://$BUCKET
    Copy to Clipboard Toggle word wrap

    1. {
          "Version": "2022-10-17",
          "Statement": [{
              "Effect": "Allow",
              "Principal": {
                  "Service": "vmie.amazonaws.com"
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                  "StringEquals": {
                      "sts:Externalid": "vmimport"
                  }
              }
          }]
      }
      Copy to Clipboard Toggle word wrap
    2. {
          "Version": "2012-10-17",
          "Statement": [{
              "Effect": "Allow",
              "Action": ["s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket"],
              "Resource": ["arn:aws:s3:::%s", "arn:aws:s3:::%s/"] }, { "Effect": "Allow", "Action": ["ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe"],
              "Resource": "*"
          }]
      }
      $BUCKET $BUCKET
      Copy to Clipboard Toggle word wrap
    3. $ aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json
      Copy to Clipboard Toggle word wrap
    4. $ aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
      Copy to Clipboard Toggle word wrap

12.1.2. 

  1. provider = "aws"
    [settings]
    accessKeyID = "AWS_ACCESS_KEY_ID"
    secretAccessKey = "AWS_SECRET_ACCESS_KEY"
    bucket = "AWS_BUCKET"
    region = "AWS_REGION"
    key = "IMAGE_KEY"
    Copy to Clipboard Toggle word wrap

  2. # composer-cli compose start blueprint-name image-type image-key configuration-file.toml
    Copy to Clipboard Toggle word wrap

    • 注意

  3. # composer-cli compose status
    Copy to Clipboard Toggle word wrap

12.1.3. 

    1. 注意

    2. 注意

    1. $ chmod 400 <_your-instance-name.pem_>
      Copy to Clipboard Toggle word wrap
    2. $ ssh -i <_your-instance-name.pem_> ec2-user@<_your-instance-IP-address_>
      Copy to Clipboard Toggle word wrap

12.2. 

12.2.1. 

  1. # *rpm --import https://packages.microsoft.com/keys/microsoft.asc*
    Copy to Clipboard Toggle word wrap
  2. # yum install -y https://packages.microsoft.com/config/rhel/9.0/packages-microsoft-prod.rpm
    Copy to Clipboard Toggle word wrap
  3. # yum install azure-cli
    Copy to Clipboard Toggle word wrap
    注意

  4. $ *az login*
    Copy to Clipboard Toggle word wrap

    注意

  5. $ az storage account keys list --resource-group <resource_group_name> --account-name <storage_account_name>
    Copy to Clipboard Toggle word wrap

    注意

    $ az resource list
    Copy to Clipboard Toggle word wrap

  6. $ az storage container create --account-name <storage_account_name>\
    --account-key <key1_value> --name <storage_account_name>
    Copy to Clipboard Toggle word wrap

12.2.2. 

  1. $ az storage blob upload --account-name <_account_name_> --container-name <_container_name_> --file <_image_-disk.vhd> --name <_image_-disk.vhd> --type page
    ...
    Copy to Clipboard Toggle word wrap
  2. $ az image create --resource-group <_resource_group_name_> --name <_image_>-disk.vhd --os-type linux --location <_location_> --source https://$<_account_name_>.blob.core.windows.net/<_container_name_>/<_image_>-disk.vhd
     - Running ...
    Copy to Clipboard Toggle word wrap
    注意

  1. $ az vm create --resource-group <_resource_group_name_> --location <_location_> --name <_vm_name_> --image <_image_>-disk.vhd --admin-username azure-user --generate-ssh-keys
     - Running ...
    Copy to Clipboard Toggle word wrap

12.2.3. 

12.2.4. 

注意

  1. GOVC_URL
    GOVC_DATACENTER
    GOVC_FOLDER
    GOVC_DATASTORE
    GOVC_RESOURCE_POOL
    GOVC_NETWORK
    Copy to Clipboard Toggle word wrap
    1. $ govc import.vmdk ./composer-api.vmdk foldername
      Copy to Clipboard Toggle word wrap

      $ govc import.ova ./composer-api.ova foldername
      Copy to Clipboard Toggle word wrap
    2. govc vm.create \
      -net.adapter=vmxnet3 \
      -m=4096 -c=2 -g=rhel8_64Guest \
      -firmware=efi -disk=”foldername/composer-api.vmdk” \
      -disk.controller=scsi -on=false \
       vmname
      Copy to Clipboard Toggle word wrap

    3. govc vm.power -on vmname
      Copy to Clipboard Toggle word wrap
    4. govc vm.ip vmname
      Copy to Clipboard Toggle word wrap
    5. $ ssh admin@<_ip_address_of_the_vm_>
      Copy to Clipboard Toggle word wrap
      注意

12.2.5. 

  1. 注意

    1. $ rpm -qa | grep firefox
      Copy to Clipboard Toggle word wrap

12.3. 

12.3.1. 

12.3.1.1. 

警告

  1. provider = "gcp"
    [settings]
    bucket = "GCP_BUCKET"
    region = "GCP_STORAGE_REGION"
    object = "OBJECT_KEY"
    credentials = "GCP_CREDENTIALS"
    Copy to Clipboard Toggle word wrap
    • 注意

  2. $ sudo base64 -w 0 cee-gcp-nasa-476a1fa485b7.json
    Copy to Clipboard Toggle word wrap
  3. $ sudo composer-cli compose start BLUEPRINT-NAME gce IMAGE_KEY gcp-config.toml
    Copy to Clipboard Toggle word wrap

  • $ sudo composer-cli compose status
    Copy to Clipboard Toggle word wrap
12.3.1.2. 

    1. 注意

12.3.1.2.1. 

  1. $ base64 -w 0 "${GOOGLE_APPLICATION_CREDENTIALS}"
    Copy to Clipboard Toggle word wrap
  2. provider = "gcp"
    
    [settings]
    provider = "gcp"
    
    [settings]
    credentials = "GCP_CREDENTIALS"
    Copy to Clipboard Toggle word wrap
12.3.1.2.2. 

  • [gcp]
    credentials = "PATH_TO_GCP_ACCOUNT_CREDENTIALS"
    Copy to Clipboard Toggle word wrap

12.4. 

12.4.1. 

12.5. 

12.5.1. 

警告

  1. # composer-cli compose start blueprint_name openstack
    Copy to Clipboard Toggle word wrap
  2. # composer-cli compose status
    Copy to Clipboard Toggle word wrap

  3. # composer-cli compose image UUID
    Copy to Clipboard Toggle word wrap

12.6. 

12.6.1. 

注意

  1. $ curl -O https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/73848/cn_zh/1557459863884/image_check
    Copy to Clipboard Toggle word wrap
  2. # chmod +x image_check
    Copy to Clipboard Toggle word wrap
  3. # ./image_check
    Copy to Clipboard Toggle word wrap

12.6.2. 

12.6.3. 

  1. 注意

12.6.4. 

  1. 注意

法律通告

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat