本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes 1.30:只讀卷掛載終於可以真正地只讀了

只讀卷掛載從一開始就是 Kubernetes 的一個特性。但令人驚訝的是,在 Linux 上的某些條件下,只讀掛載並非完全只讀。從 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/*` 的寫入仍然是可行的。

新的掛載選項:recursiveReadOnly

Kubernetes 1.30 添加了一個新的掛載選項 `recursiveReadOnly`,以便將子掛載點遞迴地設定為只讀。

該選項可以按如下方式啟用

---
apiVersion: v1
kind: Pod
spec:
  volumes:
    - name: mnt
      hostPath:
        path: /mnt
  containers:
    - volumeMounts:
        - name: mnt
          mountPath: /mnt
          readOnly: true
          # NEW
          # Possible values are `Enabled`, `IfPossible`, and `Disabled`.
          # Needs to be specified in conjunction with `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),這樣使用者就不再需要手動啟用該特性門控了。

為了向後相容,`recursiveReadOnly` 的預設值將仍然是 `Disabled`。

我如何瞭解更多資訊?

有關 `recursiveReadOnly` 掛載的更多詳情,請查閱文件

如何參與?

此功能由 SIG Node 社群推動。歡迎加入我們,與社群建立聯絡,分享你對上述功能及其他方面的想法和反饋。我們期待你的迴音!