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

Kubernetes 1.20:对卷权限更改的精细控制

Kubernetes 1.20 引入了两个重要的 Beta 功能,使 Kubernetes 管理员和用户可以更充分地控制卷在 Pod 内挂载时如何应用权限。

允许用户跳过挂载时递归的权限更改

传统上,如果您的 Pod 以非 root 用户身份运行(您应该这样做),则必须在 Pod 的安全上下文中指定 fsGroup,以便 Pod 可以读取和写入该卷。 此处更详细地介绍了此要求。

但是设置 fsGroup 的一个副作用是,每次挂载卷时,Kubernetes 都必须递归地 chown()chmod() 卷内的所有文件和目录 - 下面会提到一些例外情况。 即使卷的组所有权已经与请求的 fsGroup 匹配,也会发生这种情况,并且对于包含许多小文件的大型卷来说,这可能会非常耗时,从而导致 Pod 启动时间很长。这种情况是一个已知问题 一段时间了,在 Kubernetes 1.20 中,我们提供了用于在卷已经具有正确权限时选择不进行递归权限更改的旋钮。

配置 Pod 的安全上下文时,请将 fsGroupChangePolicy 设置为“OnRootMismatch”,这样如果卷的根目录已经具有正确的权限,则可以跳过递归权限更改。 Kubernetes 确保在第一次应用权限时最后更改顶层目录的权限。

securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  fsGroupChangePolicy: "OnRootMismatch"

您可以在为 Pod 配置卷权限和所有权更改策略中了解更多信息。

允许 CSI 驱动程序声明对基于 fsGroup 的权限的支持

尽管上一节暗示如果 Pod 具有 fsGroup,Kubernetes 总是递归更改卷的权限,但这并非完全正确。 对于某些多写入器卷类型(例如 NFS 或 Gluster),即使 Pod 具有 fsGroup,群集也不会执行递归权限更改。 其他卷类型甚至可能不支持 chown()/chmod(),它们依赖于 Unix 样式的权限控制原语。

那么,我们如何知道何时应用递归权限更改以及何时不应应用呢?对于内部存储驱动程序,这相对简单。对于可以跨越众多平台和存储类型的 CSI 驱动程序,此问题可能是一个更大的挑战。

以前,每当将 CSI 卷挂载到 Pod 时,Kubernetes 都会尝试自动确定是否应修改权限和所有权。正如我们已经提到的,这些方法是不精确的,并且可能会导致问题,具体取决于存储类型。

CSIDriver 自定义资源现在具有 .spec.fsGroupPolicy 字段,允许存储驱动程序显式选择加入或退出这些递归修改。 通过让 CSI 驱动程序为后备卷指定策略,Kubernetes 可以避免不必要的修改尝试。此优化有助于减少卷挂载时间,并减少有关永远不会成功的修改的错误报告。

CSIDriver FSGroupPolicy API

从 Kubernetes 1.20 开始,提供了三个 FSGroupPolicy 值,计划在将来的版本中提供更多值。

  • ReadWriteOnceWithFSType - 这是默认策略,如果在未定义 fsGroupPolicy 的情况下应用;这保留了以前 Kubernetes 版本的行为。在挂载时检查每个卷,以确定是否应递归应用权限。
  • File - 始终尝试应用权限修改,无论文件系统类型或 PersistentVolumeClaim 的访问模式如何。
  • None - 永远不要应用权限修改。

如何使用?

唯一需要配置的是在 CSIDriver 的 .spec 内定义 fsGroupPolicy。定义该元素后,任何后续挂载的卷都将自动使用定义的策略。无需其他部署!

下一步是什么?

根据反馈和采用情况,Kubernetes 团队计划在 1.21 或 1.22 版本中将这些实现推向 GA。

如何了解更多?

Kubernetes 项目文档中更详细地解释了此功能:CSI 驱动程序 fsGroup 支持为 Pod 配置卷权限和所有权更改策略

如何参与?

Kubernetes Slack 频道 #csi标准 SIG Storage 通信渠道是联系 SIG Storage 和 CSI 团队的好途径。

那些有兴趣参与 CSI 或 Kubernetes Storage 系统任何部分的设计和开发的人员,请加入Kubernetes Storage 特殊兴趣小组 (SIG)。我们正在快速发展,并且始终欢迎新的贡献者。