Menu Close

3.2. 自定义节点

虽然不鼓励直接更改 OpenShift Container Platform 节点,但有时在实现低级别安全、网络或性能功能时需要这样做。通过以下方法可以对 OpenShift Container Platform 节点直接进行更改:

  • 创建包含在清单文件中的 MachineConfig,以便在 openshift-install 期间启动集群。
  • 创建通过 Machine Config Operator 传递至运行的 OpenShift Container Platform 节点的 MachineConfig。

以下小节描述了您可能需要以这种方式在节点中配置的功能。

3.2.1. 添加 day-1 内核参数

虽然修改内核参数通常应做为第 2 天的任务,但您可能希望在初始集群安装过程中将内核参数添加到所有 master 节点或 worker 节点中。下面是一些您可能需要在集群安装过程中添加内核参数以在系统第一次引导前生效的原因:

  • 禁用某个功能(比如 SELinux),以使这个功能不会对系统产生任何影响。
  • 您需要在系统启动前进行一些低级网络配置。

要向 master 节点或 worker 节点添加内核参数,您可以创建一个 MachineConfig 对象,并将该对象注入 Ignition 在集群设置过程中使用的清单文件集合中。

如需列出引导时可以传递给 RHEL 8 内核的参数,请参阅 Kernel.org 内核参数。如果需要这些参数来完成初始的 OpenShift Container Platform 安装,最好使用这个流程添加内核参数。

流程

  1. 为集群生成 Kubernetes 清单:

    $ ./openshift-install create manifests --dir=<installation_directory>
  2. 决定您要向 worker 节点或 master 节点添加的内核参数。
  3. openshift 目录中,创建一个文件(例如: 99_openshift-machineconfig_master-kargs.yaml)来定义 MachineConfig 对象以添加内核设置。这个示例为 master 节点添加了一个 loglevel=7 的内核参数:

    $ cat << EOF > 99_openshift-machineconfig_master-kargs.yaml
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: master
      name: 99_openshift-machineconfig_master-kargs
    spec:
      kernelArguments:
        - 'loglevel=7'
    EOF

    您可以将 master 改为 worker ,以将内核参数添加到 worker 节点。创建一个单独的 YAML 文件,以添加到 master 节点和 worker 节点中。

现在您可以继续创建集群。

3.2.2. 在节点中添加内核模块

对于大多数常用硬件,在计算机启动时,Linux 内核会包括使用这些硬件所需的设备驱动程序模块。但是对于一些硬件来说,在 Linux 中不提供它们的模块。因此,您必须找到一种方法来为每个主机计算机提供这些模块。此流程介绍了如何为 OpenShift Container Platform 集群中的节点进行此操作。

当首先按照这些说明部署了一个内核模块后,这个模块就可用于当前内核。如果安装了新内核,kmods-via-containers 软件将被重建并部署该模块,以便使新内核可使用该模块的兼容版本。

使这个功能可以在每个节点中保持模块最新状态的方法是:

  • 在引导时启动的每个节点中添加 systemd 服务,以检测是否安装了新内核。
  • 如果检测到一个新的内核,该服务会重建该模块并将其安装到内核中

有关此过程所需软件的详情,请查看 kmods-via-containers github 站点。

需要记住的几个重要问题:

  • 这个过程是技术预览。
  • 软件工具和示例还没有官方的 RPM,现只能从非官方的 github.com 站点获得。
  • 红帽不支持您通过这些步骤添加的第三方内核模块。
  • 在本流程中,构建您的内核模块所需的软件部署在 RHEL 8 容器中。请记住,当节点有新内核时,每个节点上会自动重新构建模块。因此,每个节点都需要访问一个 yum 存储库,该程序存储库包含重建该模块所需的内核和相关软件包。该内容最好由一个有效的 RHEL 订阅提供。

3.2.2.1. 构建并测试内核模块容器

在将内核模块部署到 OpenShift Container Platform 集群之前,您可以在单独的 RHEL 系统中测试此过程。收集内核模块的源代码、KVC 框架和 kmod-via-containers 软件。然后构建并测试模块。要在 RHEL 8 系统中做到这一点,请执行以下操作:

流程

  1. 获取 RHEL 8 系统,然后注册并订阅它:

    # subscription-manager register
    Username: yourname
    Password: ***************
    # subscription-manager attach --auto
  2. 安装构建软件和容器所需的软件:

    # yum install podman make git -y
  3. 克隆 kmod-via-containers 存储库:

    $ mkdir kmods; cd kmods
    $ git clone https://github.com/kmods-via-containers/kmods-via-containers
  4. 在 RHEL 8 构建主机上安装 KVC 框架实例来测试模块。这会添加 kmods-via-container systemd 服务并加载它:

    $ cd kmods-via-containers/
    $ sudo make install
    $ sudo systemctl daemon-reload
  5. 获取内核模块源代码。通过源代码,可以构建一个您无法控制但由其他人提供的第三方模块。您需要类似 kvc -simple-kmod 示例中显示的内容 ,使用以下步骤将这些内容克隆到您的系统中:

    $ cd ..
    $ git clone https://github.com/kmods-via-containers/kvc-simple-kmod
  6. 编辑示例中的配置文件 simple-kmod.conf,将 Dockerfile 的名称改为 Dockerfile.rhel ,该文件如下所示:

    $ cd kvc-simple-kmod
    $ cat simple-kmod.conf
    
    KMOD_CONTAINER_BUILD_CONTEXT="https://github.com/kmods-via-containers/kvc-simple-kmod.git"
    KMOD_CONTAINER_BUILD_FILE=Dockerfile.rhel
    KMOD_SOFTWARE_VERSION=dd1a7d4
    KMOD_NAMES="simple-kmod simple-procfs-kmod"
  7. 为您的内核模块创建一个 kmods-via-containers@.service 实例(在这个示例中是 simple-kmod )并启用它:

    $ sudo make install
    $ sudo kmods-via-containers build simple-kmod $(uname -r)
  8. 启用并启动 systemd 服务,然后检查状态:

    $ sudo systemctl enable kmods-via-containers@simple-kmod.service
    $ sudo systemctl start kmods-via-containers@simple-kmod.service
    $ sudo systemctl status kmods-via-containers@simple-kmod.service
    ● kmods-via-containers@simple-kmod.service - Kmods Via Containers - simple-kmod
       Loaded: loaded (/etc/systemd/system/kmods-via-containers@.service;
              enabled; vendor preset: disabled)
       Active: active (exited) since Sun 2020-01-12 23:49:49 EST; 5s ago...
  9. 要确认载入了内核模块,请使用 lsmod 命令列出模块:

    $ lsmod | grep simple_
    simple_procfs_kmod     16384  0
    simple_kmod            16384  0
  10. simple-kmod 示例还有几个其它方法来测试它是否可以正常工作。使用 dmesg 在内核环缓冲中查找 "Hello world" 信息:

    $ dmesg | grep 'Hello world'
    [ 6420.761332] Hello world from simple_kmod.

    /proc 中检查 simple-procfs-kmod 的值:

    $ sudo cat /proc/simple-procfs-kmod
    simple-procfs-kmod number = 0

    运行 spkut 命令从模块中获取更多信息:

    $ sudo spkut 44
    KVC: wrapper simple-kmod for 4.18.0-147.3.1.el8_1.x86_64
    Running userspace wrapper using the kernel module container...
    + podman run -i --rm --privileged
       simple-kmod-dd1a7d4:4.18.0-147.3.1.el8_1.x86_64 spkut 44
    simple-procfs-kmod number = 0
    simple-procfs-kmod number = 44

下一步,当系统引导这个服务时,会检查新内核是否在运行。如果有一个新内核,该服务会构建内核模块的新版本,然后载入它。如果已经构建了该模块,它将只载入该模块。

3.2.2.2. 为 OpenShift Container Platform 置备内核模块

根据 OpenShift Container Platform 集群首次引导时是否必须存在内核模块,您可以通过以下两种方式之一设置内核模块部署:

  • 在集群安装时(day-1)置备内核模块:您可以通过一个 MachineConfig 创建内容,并通过包括一组清单文件来将其提供给 openshift-install
  • 通过 Machine Config Operator 置备内核模块(day-2):如果可以等到集群启动并运行后再添加内核模块,则可以通过 Machine Config Operator (MCO) 部署内核模块软件。

在这两种情况下,每个节点都需要在检测到新内核时可以获得内核软件包及相关软件包。您可以通过以下几种方法设置每个节点来获取该内容。

  • 为每个节点提供 RHEL 权利。
  • 从现有的 RHEL 主机获取 RHEL 权利。把 /etc/pki/entitlement 目录中的 RHEL 授权复制到与您在构建 Ignition 配置时提供的其他文件相同的位置。
  • 在 Dockerfile 中,添加包括了内核和其他软件包的 yum 存储库。这必须包括新内核软件包,因为它们需要与新安装的内核相匹配。
3.2.2.2.1. 通过 MachineConfig 置备内核模块

通过将内核模块软件与 MachineConfig 一起打包,您可以在安装时或通过 Machine Config Operator 向 worker 或 master 节点发送该软件。

首先创建您要使用的基本 Ignition 配置。在安装时,Ignition 配置需要包含添加到集群中的 core 用户的 authorized_keys 文件中的 ssh 公钥 。如果在以后通过 MCO 添加 MachineConfig,则不需要 ssh 公钥。对于这两种方式,simple-kmod 服务示例都会创建一个 systemd 单元文件,它需要一个 kmods-via-containers@simple-kmod.service

注意

systemd 单元是 上游程序错误的一个临时解决方案。确保 kmods-via-containers@simple-kmod.service 在引导时启动:

  1. 获取 RHEL 8 系统,然后注册并订阅它:

    # subscription-manager register
    Username: yourname
    Password: ***************
    # subscription-manager attach --auto
  2. 安装构建软件所需的软件:

    # yum install podman make git -y
  3. 创建 Ignition 配置文件以创建 systemd 单元文件:

    $ mkdir kmods; cd kmods
    $ cat <<EOF > ./baseconfig.ign
    {
      "ignition": { "version": "2.2.0" },
      "passwd": {
        "users": [
          {
            "name": "core",
            "groups": ["sudo"],
            "sshAuthorizedKeys": [
              "ssh-rsa AAAA"
            ]
          }
        ]
      },
      "systemd": {
        "units": [{
          "name": "require-kvc-simple-kmod.service",
          "enabled": true,
          "contents": "[Unit]\nRequires=kmods-via-containers@simple-kmod.service\n[Service]\nType=oneshot\nExecStart=/usr/bin/true\n\n[Install]\nWantedBy=multi-user.target"
        }]
      }
    }
    EOF
    注意

    您必须将公共 SSH 密钥添加到 baseconfig.ign 文件中 ,以便 openshift-install 使用该文件。如果通过 MCO 创建 MachineConfig,则不需要使用公共 SSH 密钥。

  4. 创建如下所示的基础 MCO YAML 片断:
$ cat <<EOF > mc-base.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  labels:
    machineconfiguration.openshift.io/role: worker
  name: 10-kvc-simple-kmod
spec:
  config:
EOF

+

注意

Mc-base.yaml 设置为在 worker 节点上部署内核模块 。要部署到 master 节点上,请将角色从 worker 更改为 master。要进行这两个操作,您可以通过为不同类型的部署使用不同的文件名来重复整个过程。

  1. 获得 kmods-via-containers 软件:

    $ git clone https://github.com/kmods-via-containers/kmods-via-containers
    $ git clone https://github.com/kmods-via-containers/kvc-simple-kmod
  2. 获取您的模块软件。在这个示例中使用 kvc-simple-kmod
  3. 使用之前克隆的存储库,创建一个 fakeroot 目录,并将您要通过 Ignition 传递的文件放置到这个目录:

    $ FAKEROOT=$(mktemp -d)
    $ cd kmods-via-containers
    $ make install DESTDIR=${FAKEROOT}/usr/local CONFDIR=${FAKEROOT}/etc/
    $ cd ../kvc-simple-kmod
    $ make install DESTDIR=${FAKEROOT}/usr/local CONFDIR=${FAKEROOT}/etc/
  4. 获取名为 filetranspiler 的工具程序及相关的依赖软件:

    $ cd ..
    $ sudo yum install -y python3
    git clone https://github.com/ashcrow/filetranspiler.git
  5. 生成最终的 MachineConfig YAML(mc.yaml),它包含基础 Ignition 配置、基础 MachineConfig,以及包括您要提供的文件的 fakeroot 目录:

    $ ./filetranspiler/filetranspile -i ./baseconfig.ign \
         -f ${FAKEROOT} --format=yaml --dereference-symlinks \
         | sed 's/^/     /' | (cat mc-base.yaml -) > 99_simple-kmod.yaml
  6. 如果集群还没有启用,生成清单文件并将该文件添加到 openshift 目录中。如果集群已在运行,按照以下方法应用该文件:

    $ oc create -f 99_simple-kmod.yaml

    您的节点将启动 kmods-via-containers@simple-kmod.service 服务,并将载入内核模块。

  7. 为了确认内核模块已加载,您可以登录到节点(使用 oc debug node/<openshift-node>,然后运行 chroot /host)。要列出模块,请使用 lsmod 命令:

    $ lsmod | grep simple_
    simple_procfs_kmod     16384  0
    simple_kmod            16384  0

3.2.3. 在安装过程中加密磁盘

在 OpenShift Container Platform 安装过程中,您可以在所有 master 和 worker 节点上启用磁盘加密。这个功能:

  • 可用于安装程序置备的基础架构和用户置备的基础架构部署
  • 只在 Red Hat Enterprise Linux CoreOS (RHCOS) 系统上被支持
  • 在清单安装阶段设置磁盘加密,以便加密所有写入磁盘的数据(从第一次引导开始)
  • 只加密 root 文件系统中的数据(/dev/mapper/coreos-luks-root on /
  • 不需要用户干预就可以提供密码短语
  • 使用 AES-256-CBC 加密
  • 应该为集群启用来支持 FIPS。

支持的加密模式有两种:

  • TPM v2:这是首选模式。TPM v2 在安全加密处理器中存储密码短语。要实现 TPM v2 磁盘加密,请创建 Ignition 配置文件,如下所述。
  • Tang:要使用 Tang 来加密集群,您需要使用一个 Tang 服务器。Clevis 在客户端实现解密。只有在裸机上的安装支持 Tang 加密模式。

按照以下两个流程之一为集群中的节点启用磁盘加密。

3.2.3.1. 启用 TPM v2 磁盘加密

使用这个流程在 OpenShift Container Platform 部署过程中启用 TPM v2 模式磁盘加密。

流程

  1. 检查每个节点的 BIOS 是否需要启用 TPM v2 加密。这在大多数 Dell 系统中是必需的。请参阅您的计算机的相关手册。
  2. 为集群生成 Kubernetes 清单:

    $ ./openshift-install create manifests --dir=<installation_directory>
  3. openshift 目录中,创建一个 master 和/或 worker 文件来为这些节点加密磁盘。以下是这两个文件的例子:

    $ cat << EOF > ./99_openshift-worker-tpmv2-encryption.yaml
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      name: worker-tpm
      labels:
        machineconfiguration.openshift.io/role: worker
    spec:
      config:
        ignition:
          version: 2.2.0
        storage:
          files:
          - contents:
              source: data:text/plain;base64,e30K
            filesystem: root
            mode: 420
            path: /etc/clevis.json
    EOF
    $ cat << EOF > ./99_openshift-master-tpmv2-encryption.yaml
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      name: master-tpm
      labels:
        machineconfiguration.openshift.io/role: master
    spec:
      config:
        ignition:
          version: 2.2.0
        storage:
          files:
          - contents:
              source: data:text/plain;base64,e30K
            filesystem: root
            mode: 420
            path: /etc/clevis.json
    EOF
  4. 生成 YAML 文件的备份副本。在创建集群时会删除该文件,所以您应该进行备份。
  5. 继续进行 OpenShift Container Platform 部署的剩余部分。

3.2.3.2. 启用 Tang 磁盘加密

使用这个流程在 OpenShift Container Platform 部署过程中启用 Tang 模式磁盘加密。

流程

  1. 使用一个 Red Hat Enterprise Linux 服务器配置加密设置,并运行 openshift-install 来安装一个集群及 oc
  2. 设置或访问现有的 Tang 服务器。具体步骤请查看网络绑定磁盘加密 。另请参阅 Securing Automated Decryption New Cryptography and Techni
  3. 添加内核参数来配置集群在安装 Red Hat Enterprise Linux CoreOS(RHCOS)时的网络。例如:在内核命令行中添加参数来配置 DHCP 网络,指定 ip=dhcp,或者设置静态网络。对于 DHCP 和静态网络,您必须提供 rd.neednet=1 内核参数。
重要

跳过这一步会导致第二次引导失败。

  1. 生成 thumbprint。安装 clevis 软件包(如果还没有安装),并从 Tang 服务器生成一个 thumbprint。使用 Tang 服务器 URL 替换 url 的值:

    $ sudo yum install clevis -y
    $ echo nifty random wordwords \
         | clevis-encrypt-tang \
           '{"url":"https://tang.example.org"}'
    
    The advertisement contains the following signing keys:
    
    PLjNyRdGw03zlRoGjQYMahSZGu9
    
    Do you wish to trust these keys? [ynYN] y
    eyJhbmc3SlRyMXpPenc3ajhEQ01tZVJiTi1oM...
  2. 创建 Base64 编码文件,使用新生成的 Tang server 替换 url,thumbprint 替换thp

    $ (cat <<EOM
    {
     "url": "https://tang.example.com",
     "thp": "PLjNyRdGw03zlRoGjQYMahSZGu9"
    }
    EOM
    ) | base64 -w0
    
    ewogInVybCI6ICJodHRwczovL3RhbmcuZXhhbXBsZS5jb20iLAogInRocCI6ICJaUk1leTFjR3cwN3psVExHYlhuUWFoUzBHdTAiCn0K
  3. 将 TPM2 示例中的 “source” 替换为 worker 和/或 master 节点的其中一个或两个示例的 Base64 编码文件:

    重要

    您必须添加 rd.neednet=1 内核参数。

    $ cat << EOF > ./99-openshift-worker-tang-encryption.yaml
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      name: worker-tang
      labels:
        machineconfiguration.openshift.io/role: worker
    spec:
      config:
        ignition:
          version: 2.2.0
        storage:
          files:
          - contents:
              source: data:text/plain;base64,e30K
              source: data:text/plain;base64,ewogInVybCI6ICJodHRwczovL3RhbmcuZXhhbXBsZS5jb20iLAogInRocCI6ICJaUk1leTFjR3cwN3psVExHYlhuUWFoUzBHdTAiCn0K
            filesystem: root
            mode: 420
            path: /etc/clevis.json
      kernelArguments:
        - rd.neednet=1 <.>
    EOF
    必需。
    $ cat << EOF > ./99_openshift-master-encryption.yaml
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      name: master-tang
      labels:
        machineconfiguration.openshift.io/role: master
    spec:
      config:
        ignition:
          version: 2.2.0
        storage:
          files:
          - contents:
              source: data:text/plain;base64,e30K
              source: data:text/plain;base64,ewogInVybCI6ICJodHRwczovL3RhbmcuZXhhbXBsZS5jb20iLAogInRocCI6ICJaUk1leTFjR3cwN3psVExHYlhuUWFoUzBHdTAiCn0K
            filesystem: root
            mode: 420
            path: /etc/clevis.json
      kernelArguments:
        - rd.neednet=1 <.>
    EOF
    必需。
  4. 继续进行 OpenShift Container Platform 部署的剩余部分。

3.2.4. 配置 chrony 时间服务

您可以通过修改 chrony.conf 文件的内容来设置 chrony 时间服务 (chronyd) 使用的时间服务器和相关设置,并通过一个 MachineConfig 将这些内容传递给节点。

流程

  1. 创建 chrony.conf 文件的内容并对其进行 base64 编码。例如:

    $ cat << EOF | base64
        server clock.redhat.com iburst
        driftfile /var/lib/chrony/drift
        makestep 1.0 3
        rtcsync
        logdir /var/log/chrony
        EOF
    
    ICAgIHNlcnZlciBjbG9jay5yZWRoYXQuY29tIGlidXJzdAogICAgZHJpZnRmaWxlIC92YXIvbGli
    L2Nocm9ueS9kcmlmdAogICAgbWFrZXN0ZXAgMS4wIDMKICAgIHJ0Y3N5bmMKICAgIGxvZ2RpciAv
    dmFyL2xvZy9jaHJvbnkK
  2. 创建 MachineConfig 文件,将 base64 字符串替换为您刚刚创建的字符串。本例将文件添加到 master 节点。您可以将其更改为 worker ,或为 worker 角色创建额外的 MachineConfig:

    $ cat << EOF > ./99_masters-chrony-configuration.yaml
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: master
      name: masters-chrony-configuration
    spec:
      config:
        ignition:
          config: {}
          security:
            tls: {}
          timeouts: {}
          version: 2.2.0
        networkd: {}
        passwd: {}
        storage:
          files:
          - contents:
              source: data:text/plain;charset=utf-8;base64,c2VydmVyIGNsb2NrLnJlZGhhdC5jb20gaWJ1cnN0CmRyaWZ0ZmlsZSAvdmFyL2xpYi9jaHJvbnkvZHJpZnQKbWFrZXN0ZXAgMS4wIDMKcnRjc3luYwpsb2dkaXIgL3Zhci9sb2cvY2hyb255Cg==
              verification: {}
            filesystem: root
            mode: 420
            path: /etc/chrony.conf
      osImageURL: ""
    EOF
  3. 对配置文件做一个副本备份。
  4. 如果集群还没有启动,生成清单文件,将此文件添加到 openshift 目录中,然后继续创建集群。
  5. 如果集群已在运行,按照以下方法应用该文件:

     $ oc apply -f ./masters-chrony-configuration.yaml

3.2.5. 其他资源

如需更多与 FIPS 相关的信息,请参阅 Support for FIPS cryptography