×

您可以使用挂载命名空间封装来为kubelet和CRI-O进程提供私有命名空间,从而优化OpenShift Container Platform集群中的CPU使用率。这减少了systemd使用的集群CPU资源,而功能没有差异。

挂载命名空间封装仅为技术预览功能。技术预览功能不受Red Hat生产服务级别协议 (SLA) 支持,并且可能功能不完整。Red Hat不建议在生产环境中使用它们。这些功能可让您抢先体验即将推出的产品功能,使客户能够在开发过程中测试功能并提供反馈。

有关Red Hat技术预览功能的支持范围的更多信息,请参见技术预览功能支持范围

封装挂载命名空间

挂载命名空间用于隔离挂载点,以便不同命名空间中的进程无法查看彼此的文件。封装是将Kubernetes挂载命名空间移动到替代位置的过程,在该位置,主机操作系统不会对其进行持续扫描。

主机操作系统使用systemd持续扫描所有挂载命名空间:标准Linux挂载和Kubernetes用于操作的众多挂载。kubelet和CRI-O的当前实现都使用顶级命名空间来处理所有容器运行时和kubelet挂载点。但是,将这些特定于容器的挂载点封装在私有命名空间中可以减少systemd开销,而功能没有差异。为CRI-O和kubelet使用单独的挂载命名空间可以将特定于容器的挂载点与任何systemd或其他主机操作系统交互隔离开来。

现在,所有OpenShift Container Platform管理员都可以使用这种可能实现主要CPU优化的功能。封装还可以通过将Kubernetes特定的挂载点存储在非特权用户无法检查的安全位置来提高安全性。

下图说明了封装前后Kubernetes安装的情况。两种情况都显示了具有双向、主机到容器和无挂载传播设置的示例容器。

Before encapsulation

在这里,我们可以看到systemd、主机操作系统进程、kubelet和容器运行时共享单个挂载命名空间。

  • systemd、主机操作系统进程、kubelet和容器运行时都可以访问并查看所有挂载点。

  • 配置了双向挂载传播的容器1可以访问systemd和主机挂载、kubelet和CRI-O挂载。源自容器1的挂载(例如/run/a)对systemd、主机操作系统进程、kubelet、容器运行时以及配置了主机到容器或双向挂载传播的其他容器(如容器2)可见。

  • 配置了主机到容器挂载传播的容器 2 可以访问 systemd 和主机挂载、kubelet 和 CRI-O 挂载。在容器 2 中创建的挂载点,例如/run/b,对任何其他上下文不可见。

  • 容器 3 没有配置挂载传播,无法看到外部挂载点。在容器 3 中创建的挂载点,例如/run/c,对任何其他上下文不可见。

下图说明了封装后的系统状态。

After encapsulation
  • 主 systemd 进程不再用于扫描 Kubernetes 特定的挂载点。它只监控 systemd 特定的和主机挂载点。

  • 主机操作系统进程只能访问 systemd 和主机挂载点。

  • 为 CRI-O 和 kubelet 使用单独的挂载命名空间,可以完全将所有容器特定的挂载点与任何 systemd 或其他主机操作系统交互隔离开来。

  • 容器 1 的行为保持不变,除了它创建的挂载点,例如/run/a,不再对 systemd 或主机操作系统进程可见。它仍然对 kubelet、CRI-O 和配置了主机到容器或双向挂载传播的其他容器(如容器 2)可见。

  • 容器 2 和容器 3 的行为保持不变。

配置挂载命名空间封装

您可以配置挂载命名空间封装,以便集群以较低的资源开销运行。

挂载命名空间封装是技术预览功能,默认情况下处于禁用状态。要使用它,您必须手动启用此功能。

先决条件
  • 您已安装 OpenShift CLI (oc)。

  • 您已以具有cluster-admin权限的用户身份登录。

步骤
  1. 创建一个名为mount_namespace_config.yaml的文件,内容如下所示的YAML

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: master
      name: 99-kubens-master
    spec:
      config:
        ignition:
          version: 3.2.0
        systemd:
          units:
          - enabled: true
            name: kubens.service
    ---
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 99-kubens-worker
    spec:
      config:
        ignition:
          version: 3.2.0
        systemd:
          units:
          - enabled: true
            name: kubens.service
  2. 通过运行以下命令应用挂载命名空间MachineConfig CR

    $ oc apply -f mount_namespace_config.yaml
    示例输出
    machineconfig.machineconfiguration.openshift.io/99-kubens-master created
    machineconfig.machineconfiguration.openshift.io/99-kubens-worker created
  3. MachineConfig CR 最多可能需要 30 分钟才能在集群中完成应用。您可以通过运行以下命令检查MachineConfig CR 的状态

    $ oc get mcp
    示例输出
    NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
    master   rendered-master-03d4bc4befb0f4ed3566a2c8f7636751   False     True       False      3              0                   0                     0                      45m
    worker   rendered-worker-10577f6ab0117ed1825f8af2ac687ddf   False     True       False      3              1                   1
  4. 运行以下命令后,等待MachineConfig CR 在所有控制平面和工作节点上成功应用

    $ oc wait --for=condition=Updated mcp --all --timeout=30m
    示例输出
    machineconfigpool.machineconfiguration.openshift.io/master condition met
    machineconfigpool.machineconfiguration.openshift.io/worker condition met
验证

要验证集群主机的封装,请运行以下命令

  1. 打开到集群主机的调试 shell

    $ oc debug node/<node_name>
  2. 打开一个chroot会话

    sh-4.4# chroot /host
  3. 检查 systemd 挂载命名空间

    sh-4.4# readlink /proc/1/ns/mnt
    示例输出
    mnt:[4026531953]
  4. 检查 kubelet 挂载命名空间

    sh-4.4# readlink /proc/$(pgrep kubelet)/ns/mnt
    示例输出
    mnt:[4026531840]
  5. 检查 CRI-O 挂载命名空间

    sh-4.4# readlink /proc/$(pgrep crio)/ns/mnt
    示例输出
    mnt:[4026531840]

这些命令返回与 systemd、kubelet 和容器运行时关联的挂载命名空间。在 OpenShift Container Platform 中,容器运行时是 CRI-O。

如果 systemd 与 kubelet 和 CRI-O 位于不同的挂载命名空间(如上例所示),则封装有效。如果所有三个进程都在同一个挂载命名空间中,则封装无效。

检查封装的命名空间

您可以使用 Red Hat Enterprise Linux CoreOS (RHCOS) 中提供的kubensenter脚本,检查集群主机操作系统中的 Kubernetes 特定挂载点,以进行调试或审计。

对集群主机的 SSH shell 会话位于默认命名空间中。要在 SSH shell 提示符中检查 Kubernetes 特定的挂载点,您需要以 root 用户身份运行kubensenter脚本。kubensenter脚本知道挂载封装的状态,即使未启用封装,也可以安全运行。

oc debug远程 shell 会话默认在 Kubernetes 命名空间内启动。使用oc debug时,无需运行kubensenter即可检查挂载点。

如果未启用封装功能,则无论是在oc debug会话中还是在 SSH shell 提示符中运行,kubensenter findmntfindmnt命令都会返回相同的输出。

先决条件
  • 您已安装 OpenShift CLI (oc)。

  • 您已以具有cluster-admin权限的用户身份登录。

  • 您已配置对集群主机的 SSH 访问。

步骤
  1. 打开到集群主机的远程 SSH shell。例如

    $ ssh core@<node_name>
  2. 使用提供的kubensenter脚本以 root 用户身份运行命令。要在 Kubernetes 命名空间内运行单个命令,请将命令和任何参数提供给kubensenter脚本。例如,要在 Kubernetes 命名空间内运行findmnt命令,请运行以下命令

    [core@control-plane-1 ~]$ sudo kubensenter findmnt
    示例输出
    kubensenter: Autodetect: kubens.service namespace found at /run/kubens/mnt
    TARGET                                SOURCE                 FSTYPE     OPTIONS
    /                                     /dev/sda4[/ostree/deploy/rhcos/deploy/32074f0e8e5ec453e56f5a8a7bc9347eaa4172349ceab9c22b709d9d71a3f4b0.0]
    |                                                            xfs        rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,prjquota
                                          shm                    tmpfs
    ...
  3. 要在 Kubernetes 命名空间内启动新的交互式 shell,请运行kubensenter脚本,无需任何参数

    [core@control-plane-1 ~]$ sudo kubensenter
    示例输出
    kubensenter: Autodetect: kubens.service namespace found at /run/kubens/mnt

在封装的命名空间中运行其他服务

任何依赖于能够在主机操作系统中运行并具有 kubelet、CRI-O 或容器本身创建的挂载点可见性的监控工具,都必须进入容器挂载命名空间才能查看这些挂载点。OpenShift Container Platform 提供的kubensenter脚本在 Kubernetes 挂载点内执行另一个命令,并可用于调整任何现有工具。

kubensenter脚本知道挂载封装功能状态,即使未启用封装,也可以安全运行。在这种情况下,脚本在默认挂载命名空间中执行提供的命令。

例如,如果 systemd 服务需要在新的 Kubernetes 挂载命名空间内运行,请编辑服务文件并使用带有kubensenterExecStart=命令行。

[Unit]
Description=Example service
[Service]
ExecStart=/usr/bin/kubensenter /path/to/original/command arg1 arg2