本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kubernetes 1.27:高效的 SELinux 卷重新標記(Beta)
問題所在
在啟用了安全增強型 Linux(SELinux)的 Linux 系統上,傳統上是由容器執行時為 Pod 及其所有卷應用 SELinux 標籤。Kubernetes 只是將 Pod 的 securityContext 欄位中的 SELinux 標籤傳遞給容器執行時。
然後,容器執行時會遞迴地更改 Pod 容器可見的所有檔案上的 SELinux 標籤。如果捲上有大量檔案,這可能會非常耗時,特別是當卷位於遠端檔案系統上時。
說明
如果容器使用卷的subPath,則只有整個卷的那個 subPath 會被重新打上標籤。這允許兩個擁有不同 SELinux 標籤的 Pod 使用同一個卷,只要它們使用不同的子路徑即可。如果一個 Pod 在 Kubernetes API 中沒有分配任何 SELinux 標籤,容器執行時會分配一個唯一的隨機標籤,這樣,一個可能逃逸出容器邊界的程序就無法訪問主機上任何其他容器的資料。容器執行時仍然會用這個隨機的 SELinux 標籤遞迴地重新標記所有 Pod 卷。
使用掛載選項進行改進
如果一個 Pod 及其卷滿足以下**所有**條件,Kubernetes 將直接使用正確的 SELinux 標籤來**掛載**該卷。這樣的掛載將在恆定時間內完成,容器執行時將無需遞迴地為捲上的任何檔案重新打標籤。
作業系統必須支援 SELinux。
如果未檢測到 SELinux 支援,kubelet 和容器執行時不會執行任何與 SELinux 相關的操作。
特性門控
ReadWriteOncePod和SELinuxMountReadWriteOncePod必須被啟用。這些特性門控在 Kubernetes 1.27 中是 Beta 版,在 1.25 中是 Alpha 版。如果這些特性門控中的任何一個被停用,SELinux 標籤將總是由容器執行時透過遞迴遍歷卷(或其 subPath)來應用。
Pod 必須在其 Pod Security Context 中至少分配了
seLinuxOptions.level,或者所有 Pod 容器必須在其 Security Contexts 中設定了它。Kubernetes 將從作業系統的預設值(通常是system_u、system_r和container_t)中讀取預設的user、role和type。如果 Kubernetes 不知道至少 SELinux 的
level,容器執行時將在卷掛載**後**分配一個隨機的 level。在這種情況下,容器執行時仍將遞迴地為卷重新打標籤。該卷必須是訪問模式為
ReadWriteOncePod的 Persistent Volume。這是初始實現的限制。如上所述,兩個 Pod 可以擁有不同的 SELinux 標籤,並且仍然使用同一個卷,只要它們使用不同的
subPath即可。當卷是以 SELinux 標籤**掛載**時,這種用例是不可能的,因為整個卷都被掛載了,而且大多數檔案系統不支援使用多個 SELinux 標籤多次掛載同一個卷。如果在你的部署中,必須執行兩個具有不同 SELinux 上下文的 Pod 並使用同一卷的不同
subPath,請在 KEP issue 中發表評論(或對任何現有評論點贊——最好不要重複)。當該特性擴充套件到所有卷訪問模式時,這樣的 Pod 可能無法執行。負責該卷的卷外掛或 CSI 驅動程式支援使用 SELinux 掛載選項進行掛載。
這些樹內(in-tree)卷外掛支援使用 SELinux 掛載選項進行掛載:
fc、iscsi和rbd。支援使用 SELinux 掛載選項的 CSI 驅動程式必須在其 CSIDriver 例項中透過設定
seLinuxMount欄位來宣告這一點。由其他卷外掛或未設定
seLinuxMount: true的 CSI 驅動程式管理的卷,將由容器執行時進行遞迴的重新打標籤。
使用 SELinux 上下文掛載
當滿足所有上述條件時,kubelet 會將 -o context=<SELinux 標籤> 掛載選項傳遞給卷外掛或 CSI 驅動程式。CSI 驅動程式供應商必須確保其 CSI 驅動程式支援此掛載選項,並且在必要時,CSI 驅動程式會附加其他使 -o context 生效所需的掛載選項。
例如,NFS 可能需要 -o context=<SELinux 標籤>,nosharecache,這樣從同一個 NFS 伺服器掛載的每個卷都可以有不同的 SELinux 標籤值。類似地,CIFS 可能需要 -o context=<SELinux 標籤>,nosharesock。
CSI 驅動程式供應商有責任在啟用 SELinux 的環境中測試其 CSI 驅動程式,然後再在 CSIDriver 例項中設定 seLinuxMount: true。
我如何瞭解更多資訊?
容器中的 SELinux:請參閱 Daniel J Walsh 撰寫的優秀的 SELinux 視覺化指南。請注意,該指南比 Kubernetes 更早,它以虛擬機器為例描述了**多類別安全**(MCS)模式,然而,類似的概念也用於容器。
請參閱一系列部落格文章,瞭解容器執行時如何精確地將 SELinux 應用於容器的詳細資訊
閱讀 KEP:使用掛載加速 SELinux 卷的重新打標籤