本文发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.27:高效 SELinux 卷重新标记(Beta)

问题

在启用了安全增强型 Linux (SELinux) 的 Linux 系统上,传统上是由容器运行时将 SELinux 标签应用于 Pod 及其所有卷。Kubernetes 仅将 SELinux 标签从 Pod 的 securityContext 字段传递给容器运行时。

然后,容器运行时递归地更改 Pod 容器可见的所有文件上的 SELinux 标签。如果卷上有大量文件,尤其是当卷位于远程文件系统上时,这可能非常耗时。

如果 Pod 在 Kubernetes API 中未分配任何 SELinux 标签,则容器运行时将分配一个唯一的随机标签,以便潜在逃脱容器边界的进程无法访问主机上任何其他容器的数据。容器运行时仍然使用此随机 SELinux 标签递归地重新标记所有 pod 卷。

使用挂载选项进行改进

如果 Pod 及其卷满足以下所有条件,Kubernetes 将直接使用正确的 SELinux 标签挂载该卷。此类挂载将在恒定时间内发生,容器运行时将不需要递归地重新标记其上的任何文件。

  1. 操作系统必须支持 SELinux。

    如果未检测到 SELinux 支持,则 kubelet 和容器运行时不会对 SELinux 执行任何操作。

  2. 必须启用 功能门 ReadWriteOncePodSELinuxMountReadWriteOncePod。这些功能门在 Kubernetes 1.27 中为 Beta 版,在 1.25 中为 Alpha 版。

    如果禁用任何这些功能门,则始终由容器运行时通过递归遍历卷(或其子路径)来应用 SELinux 标签。

  3. Pod 的 Pod 安全上下文 中必须至少分配 seLinuxOptions.level,或者所有 Pod 容器必须在其 安全上下文 中设置它。Kubernetes 将从操作系统默认值中读取默认的 userroletype(通常为 system_usystem_rcontainer_t)。

    如果 Kubernetes 不知道至少 SELinux level,则容器运行时将在卷挂载分配一个随机标签。在这种情况下,容器运行时仍将递归地重新标记卷。

  4. 该卷必须是具有 访问模式 ReadWriteOncePod 的持久卷。

    这是初始实现的限制。如上所述,只要两个 Pod 使用同一卷的不同 subPath,它们就可以具有不同的 SELinux 标签并仍使用同一卷。当使用 SELinux 标签挂载卷时,此用例是不可能的,因为将挂载整个卷,并且大多数文件系统不支持多次挂载具有多个 SELinux 标签的单个卷。

    如果您的部署中必须运行两个具有两个不同 SELinux 上下文且使用同一卷的不同 subPath 的 Pod,请在 KEP 问题中发表评论(或赞成任何现有评论 - 最好不要重复)。当该功能扩展到涵盖所有卷访问模式时,此类 Pod 可能无法运行。

  5. 负责该卷的卷插件或 CSI 驱动程序支持使用 SELinux 挂载选项进行挂载。

    以下内置卷插件支持使用 SELinux 挂载选项进行挂载:fciscsirbd

    支持使用 SELinux 挂载选项进行挂载的 CSI 驱动程序必须在其 CSIDriver 实例中通过设置 seLinuxMount 字段来声明。

    由其他卷插件或未设置 seLinuxMount: true 的 CSI 驱动程序管理的卷将由容器运行时递归地重新标记。

使用 SELinux 上下文进行挂载

当满足上述所有条件时,kubelet 会将 -o context=<SELinux label> 挂载选项传递给卷插件或 CSI 驱动程序。CSI 驱动程序供应商必须确保其 CSI 驱动程序支持此挂载选项,并且在必要时,CSI 驱动程序会附加 -o context 工作所需的其他挂载选项。

例如,NFS 可能需要 -o context=<SELinux label>,nosharecache,因此从同一 NFS 服务器挂载的每个卷都可以具有不同的 SELinux 标签值。类似地,CIFS 可能需要 -o context=<SELinux label>,nosharesock

CSI 驱动程序供应商需要在启用了 SELinux 的环境中测试其 CSI 驱动程序,然后在 CSIDriver 实例中设置 seLinuxMount: true

如何了解更多信息?

容器中的 SELinux:请参阅 Daniel J Walsh 出色的 可视化 SELinux 指南。请注意,该指南比 Kubernetes 早,它以虚拟机为例描述了多类别安全性 (MCS) 模式,但是,容器使用了类似的概念。

有关容器运行时如何将 SELinux 应用于容器的详细信息,请参阅一系列博客文章

阅读 KEP:使用挂载加速 SELinux 卷重新标记