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

Kubernetes 1.27: 高效的 SELinux 卷重新打标签 (Beta)

问题

在启用 Security-Enhanced Linux (SELinux) 的 Linux 系统上,传统上是由容器运行时将 SELinux 标签应用于 Pod 及其所有卷。Kubernetes 仅将 Pod 的 securityContext 字段中的 SELinux 标签传递给容器运行时。

容器运行时随后递归地更改对 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 Security Context 中必须至少分配了 seLinuxOptions.level,或者所有 Pod 容器的 Security Contexts 中必须设置了该字段。Kubernetes 将从操作系统默认值(通常是 system_usystem_rcontainer_t)中读取默认的 userroletype

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

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

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

    如果你的部署中有必要运行具有两个不同 SELinux 上下文且使用同一个卷不同 subPath 的两个 Pod,请在 KEP Issue 中评论(或点赞现有评论 - 最好不要重复)。当该特性扩展到覆盖所有卷访问模式时,这些 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 卷重标记