这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。

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 社区推动。 请加入我们,与社区建立联系,并分享你对上述特性及其他特性的想法和反馈。 我们期待你的回音!

最后修改 March 05, 2026 at 10:54 AM PST: [zh-cn] sync 2024 blog files structure (d416e3487a)