Kubernetes 1.30:只读卷挂载终于可以真正实现只读了

作者: Akihiro Suda (NTT)

译者: Xin Li (DaoCloud)

只读卷挂载从一开始就是 Kubernetes 的一个特性。 令人惊讶的是,在 Linux 上的某些条件下,只读挂载并不是完全只读的。 从 v1.30 版本开始,这类卷挂载可以被处理为完全只读;v1.30 为递归只读挂载提供 Alpha 支持。

默认情况下,只读卷装载并不是真正的只读

卷挂载可能看似复杂。

你可能期望以下清单使容器中 /mnt 下的所有内容变为只读:

---
apiVersion: v1
kind: Pod
spec:
  volumes:
    - name: mnt
      hostPath:
        path: /mnt
  containers:
    - volumeMounts:
        - name: mnt
          mountPath: /mnt
          readOnly: true

但是,/mnt 下的任何子挂载可能仍然是可写的! 例如,假设 /mnt/my-nfs-server 在主机上是可写的。 在容器内部,写入 /mnt/* 将被拒绝,但 /mnt/my-nfs-server/* 仍然可写。

新的挂载选项:递归只读

Kubernetes 1.30 添加了一个新的挂载选项 recursiveReadOnly,以使子挂载递归只读。

可以按如下方式启用该选项:

---
apiVersion: v1
kind: Pod
spec:
  volumes:
    - name: mnt
      hostPath:
        path: /mnt
  containers:
    - volumeMounts:
        - name: mnt
          mountPath: /mnt
          readOnly: true
          # NEW
          # 可能的值为 `Enabled`、`IfPossible` 和 `Disabled`。
          # 需要与 `readOnly: true` 一起指定。
          recursiveReadOnly: Enabled

这是通过使用 Linux 内核 v5.12 中添加的 mount_setattr(2) 应用带有 AT_RECURSIVE 标志的 MOUNT_ATTR_RDONLY 属性来实现的。

为了向后兼容,recursiveReadOnly 字段不是 readOnly 的替代品,而是与其结合使用。 要获得正确的递归只读挂载,你必须设置这两个字段。

特性可用性

要启用 recursiveReadOnly 挂载,必须使用以下组件:

  • Kubernetes:v1.30 或更新版本,并启用 RecursiveReadOnlyMounts 特性门控。 从 v1.30 开始,此特性被标记为 Alpha。

  • CRI 运行时:

    • containerd:v2.0 或更新版本
  • OCI 运行时:

    • runc:v1.1 或更新版本
    • crun: v1.8.6 或更新版本
  • Linux 内核: v5.12 或更新版本

接下来

Kubernetes SIG Node 希望并期望该特性将在 Kubernetes 的未来版本中升级为 Beta 版本并最终稳定可用(GA),以便用户不再需要手动启用此特性门控。

为了向后兼容,recursive ReadOnly 的默认值仍将保持 Disabled

怎样才能了解更多?

请查看文档以获取 recursiveReadOnly 挂载的更多详细信息。

如何参与?

此特性由 SIG Node 社区推动。 请加入我们,与社区建立联系,并分享你对上述特性及其他特性的想法和反馈。 我们期待你的回音!