為 Pod 或容器配置安全上下文
安全上下文為 Pod 或容器定義了特權和訪問控制設定。安全上下文設定包括但不限於:
自由訪問控制:訪問物件(如檔案)的許可權基於使用者 ID (UID) 和組 ID (GID)。
安全增強型 Linux (SELinux):物件被分配安全標籤。
作為特權或非特權執行。
Linux Capabilities:授予程序一些特權,但不是根使用者的所有特權。
AppArmor:使用程式配置檔案來限制單個程式的功能。
Seccomp:過濾程序的系統呼叫。
allowPrivilegeEscalation
:控制程序是否可以獲得比其父程序更多的特權。這個布林值直接控制容器程序是否設定no_new_privs
標誌。當容器滿足以下條件時,allowPrivilegeEscalation
總是為 true:- 以特權方式執行,或者
- 具有
CAP_SYS_ADMIN
readOnlyRootFilesystem
:將容器的根檔案系統掛載為只讀。
以上並非完整的安全上下文設定列表——請參閱 SecurityContext 獲取完整列表。
準備工作
你需要有一個 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。建議在至少有兩個不充當控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用以下 Kubernetes 試玩環境之一:
要檢查版本,請輸入 kubectl version
。
設定 Pod 的安全上下文
要為 Pod 指定安全設定,請在 Pod 規範中包含 securityContext
欄位。securityContext
欄位是一個 PodSecurityContext 物件。你為 Pod 指定的安全設定適用於 Pod 中的所有容器。以下是一個包含 securityContext
和 emptyDir
卷的 Pod 的配置檔案:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
supplementalGroups: [4000]
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox:1.28
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
在配置檔案中,runAsUser
欄位指定 Pod 中所有容器的所有程序都以使用者 ID 1000 執行。runAsGroup
欄位指定 Pod 中所有容器內所有程序的主要組 ID 為 3000。如果省略此欄位,容器的主要組 ID 將為 root(0)。當指定 runAsGroup
時,建立的任何檔案也將由使用者 1000 和組 3000 擁有。由於指定了 fsGroup
欄位,容器的所有程序也是補充組 ID 2000 的一部分。卷 /data/demo
的所有者以及在該卷中建立的任何檔案都將是組 ID 2000。此外,當指定 supplementalGroups
欄位時,容器的所有程序也是指定組的一部分。如果省略此欄位,則表示為空。
建立 Pod
kubectl apply -f https://k8s.io/examples/pods/security/security-context.yaml
驗證 Pod 的容器是否正在執行
kubectl get pod security-context-demo
進入執行中的容器的 shell
kubectl exec -it security-context-demo -- sh
在你的 shell 中,列出正在執行的程序
ps
輸出顯示程序以使用者 1000 執行,這是 runAsUser
的值。
PID USER TIME COMMAND
1 1000 0:00 sleep 1h
6 1000 0:00 sh
...
在你的 shell 中,導航到 /data
,並列出其中的一個目錄
cd /data
ls -l
輸出顯示 /data/demo
目錄的組 ID 為 2000,這是 fsGroup
的值。
drwxrwsrwx 2 root 2000 4096 Jun 6 20:08 demo
在你的 shell 中,導航到 /data/demo
,並建立一個檔案
cd demo
echo hello > testfile
列出 /data/demo
目錄中的檔案
ls -l
輸出顯示 testfile
的組 ID 為 2000,這是 fsGroup
的值。
-rw-r--r-- 1 1000 2000 6 Jun 6 20:08 testfile
執行以下命令:
id
輸出類似於:
uid=1000 gid=3000 groups=2000,3000,4000
從輸出中,你可以看到 gid
是 3000,與 runAsGroup
欄位相同。如果 runAsGroup
被省略,gid
將保持為 0 (root),並且程序將能夠與 root(0) 組擁有的檔案以及對 root (0) 組具有所需組許可權的組進行互動。你還可以看到 groups
包含 fsGroup
和 supplementalGroups
指定的組 ID,以及 gid
。
退出你的 shell
exit
容器映象中 /etc/group
定義的隱含組成員資格
預設情況下,Kubernetes 會將 Pod 中的組資訊與容器映象中 /etc/group
中定義的資訊合併。
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
supplementalGroups: [4000]
containers:
- name: sec-ctx-demo
image: registry.k8s.io/e2e-test-images/agnhost:2.45
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
allowPrivilegeEscalation: false
此 Pod 安全上下文包含 runAsUser
、runAsGroup
和 supplementalGroups
。但是,你可以看到附加到容器程序的實際補充組將包括來自容器映象中 /etc/group
的組 ID。
建立 Pod
kubectl apply -f https://k8s.io/examples/pods/security/security-context-5.yaml
驗證 Pod 的容器是否正在執行
kubectl get pod security-context-demo
進入執行中的容器的 shell
kubectl exec -it security-context-demo -- sh
檢查程序身份
$ id
輸出類似於:
uid=1000 gid=3000 groups=3000,4000,50000
你可以看到 groups
包含組 ID 50000
。這是因為映象中定義的使用者 (uid=1000
) 屬於容器映象中 /etc/group
中定義的組 (gid=50000
)。
檢查容器映象中的 /etc/group
$ cat /etc/group
你可以看到 uid 1000
屬於組 50000
。
...
user-defined-in-image:x:1000:
group-defined-in-image:x:50000:user-defined-in-image
退出你的 shell
exit
注意
隱式合併的補充組可能會導致安全問題,尤其是在訪問卷時(有關詳細資訊,請參閱 kubernetes/kubernetes#112879)。如果你想避免這種情況,請參閱以下部分。為 Pod 配置細粒度的補充組控制
Kubernetes v1.33 [beta]
(預設啟用:true)此功能可以透過為 kubelet 和 kube-apiserver 設定 SupplementalGroupsPolicy
功能門控,併為 pod 設定 .spec.securityContext.supplementalGroupsPolicy
欄位來啟用。
supplementalGroupsPolicy
欄位定義了用於計算 pod 中容器程序的補充組的策略。此欄位有兩個有效值:
Merge
:將合併容器主使用者在/etc/group
中定義的組成員資格。如果未指定,這是預設策略。Strict
:只有fsGroup
、supplementalGroups
或runAsGroup
欄位中的組 ID 會作為容器程序的補充組附加。這意味著不會合並容器主使用者在/etc/group
中的任何組成員資格。
當該功能啟用時,它還會將附加到第一個容器程序的程序身份暴露在 .status.containerStatuses[].user.linux
欄位中。這對於檢測是否附加了隱含的組 ID 會很有用。
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
supplementalGroups: [4000]
supplementalGroupsPolicy: Strict
containers:
- name: sec-ctx-demo
image: registry.k8s.io/e2e-test-images/agnhost:2.45
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
allowPrivilegeEscalation: false
此 Pod 清單定義了 supplementalGroupsPolicy=Strict
。你可以看到 /etc/group
中定義的組成員資格沒有合併到容器程序的補充組中。
建立 Pod
kubectl apply -f https://k8s.io/examples/pods/security/security-context-6.yaml
驗證 Pod 的容器是否正在執行
kubectl get pod security-context-demo
檢查程序身份
kubectl exec -it security-context-demo -- id
輸出類似於:
uid=1000 gid=3000 groups=3000,4000
檢視 Pod 的狀態
kubectl get pod security-context-demo -o yaml
你可以看到 status.containerStatuses[].user.linux
欄位公開了附加到第一個容器程序的程序身份。
...
status:
containerStatuses:
- name: sec-ctx-demo
user:
linux:
gid: 3000
supplementalGroups:
- 3000
- 4000
uid: 1000
...
注意
請注意,status.containerStatuses[].user.linux
欄位中的值是附加到容器中第一個容器程序的 第一個 程序身份。如果容器具有足夠的許可權來執行與程序身份相關的系統呼叫(例如 setuid(2)
、setgid(2)
或 setgroups(2)
等),容器程序可以更改其身份。因此,實際的程序身份將是動態的。實現
已知以下容器執行時支援細粒度的補充組控制。
CRI 級別
- containerd,自 v2.0 起
- CRI-O,自 v1.31 起
你可以檢視節點狀態,判斷該功能是否受支援。
apiVersion: v1
kind: Node
...
status:
features:
supplementalGroupsPolicy: true
注意
在此 Alpha 版本(從 v1.31 到 v1.32),當一個帶有 SupplementalGroupsPolicy=Strict
的 Pod 被排程到不支援此功能的節點(即 .status.features.supplementalGroupsPolicy=false
)時,該 Pod 的補充組策略將 靜默地 回退到 Merge
策略。
然而,從 Beta 版本(v1.33)開始,為了更嚴格地執行策略,** kubelet 將拒絕此類 Pod 建立,因為節點無法確保指定的策略**。當你的 Pod 被拒絕時,你將看到帶有 reason=SupplementalGroupsPolicyNotSupported
的警告事件,如下所示:
apiVersion: v1
kind: Event
...
type: Warning
reason: SupplementalGroupsPolicyNotSupported
message: "SupplementalGroupsPolicy=Strict is not supported in this node"
involvedObject:
apiVersion: v1
kind: Pod
...
為 Pod 配置卷許可權和所有權變更策略
Kubernetes v1.23 [stable]
預設情況下,當掛載卷時,Kubernetes 會遞迴地更改每個卷內容的許可權和所有權,以匹配 Pod 的 securityContext
中指定的 fsGroup
。對於大容量,檢查和更改所有權和許可權可能需要很長時間,從而減慢 Pod 啟動。你可以使用 securityContext
中的 fsGroupChangePolicy
欄位來控制 Kubernetes 檢查和管理卷許可權和所有權的方式。
fsGroupChangePolicy - fsGroupChangePolicy
定義了在將卷暴露到 Pod 內部之前更改卷所有權和許可權的行為。此欄位僅適用於支援 fsGroup
控制所有權和許可權的卷型別。此欄位有兩個可能的值:
- OnRootMismatch:僅當根目錄的許可權和所有權與卷的預期許可權不匹配時才更改許可權和所有權。這有助於縮短更改卷所有權和許可權所需的時間。
- Always:掛載卷時始終更改卷的許可權和所有權。
例如
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"
注意
此欄位對secret
、configMap
和 emptyDir
等臨時卷型別無效。將卷許可權和所有權更改委託給 CSI 驅動
Kubernetes v1.26 [stable]
如果你部署了一個支援 VOLUME_MOUNT_GROUP
NodeServiceCapability
的 容器儲存介面 (CSI) 驅動,那麼根據 securityContext
中指定的 fsGroup
設定檔案所有權和許可權的過程將由 CSI 驅動執行,而不是 Kubernetes。在這種情況下,由於 Kubernetes 不執行任何所有權和許可權更改,fsGroupChangePolicy
不生效。根據 CSI 規範,驅動程式應該使用提供的 fsGroup
掛載卷,從而使卷對 fsGroup
可讀/寫。
為容器設定安全上下文
要為容器指定安全設定,請在容器清單中包含 securityContext
欄位。securityContext
欄位是一個 SecurityContext 物件。你為容器指定的安全設定僅適用於單個容器,並且在重疊時會覆蓋 Pod 級別的設定。容器設定不影響 Pod 的卷。
以下是包含一個容器的 Pod 的配置檔案。Pod 和容器都具有 securityContext
欄位:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-2
spec:
securityContext:
runAsUser: 1000
containers:
- name: sec-ctx-demo-2
image: gcr.io/google-samples/hello-app:2.0
securityContext:
runAsUser: 2000
allowPrivilegeEscalation: false
建立 Pod
kubectl apply -f https://k8s.io/examples/pods/security/security-context-2.yaml
驗證 Pod 的容器是否正在執行
kubectl get pod security-context-demo-2
進入執行中的容器的 shell
kubectl exec -it security-context-demo-2 -- sh
在你的 shell 中,列出正在執行的程序
ps aux
輸出顯示程序以使用者 2000 執行。這是為容器指定的 runAsUser
的值。它會覆蓋為 Pod 指定的值 1000。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
2000 1 0.0 0.0 4336 764 ? Ss 20:36 0:00 /bin/sh -c node server.js
2000 8 0.1 0.5 772124 22604 ? Sl 20:36 0:00 node server.js
...
退出你的 shell
exit
為容器設定功能
使用 Linux 功能,你可以在不授予根使用者所有特權的情況下,授予程序某些特權。要為容器新增或刪除 Linux 功能,請在容器清單的 securityContext
部分包含 capabilities
欄位。
首先,看看當你沒有包含 capabilities
欄位時會發生什麼。以下是不新增或刪除任何容器功能的配置檔案:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-3
spec:
containers:
- name: sec-ctx-3
image: gcr.io/google-samples/hello-app:2.0
建立 Pod
kubectl apply -f https://k8s.io/examples/pods/security/security-context-3.yaml
驗證 Pod 的容器是否正在執行
kubectl get pod security-context-demo-3
進入執行中的容器的 shell
kubectl exec -it security-context-demo-3 -- sh
在你的 shell 中,列出正在執行的程序
ps aux
輸出顯示容器的程序 ID (PID)
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4336 796 ? Ss 18:17 0:00 /bin/sh -c node server.js
root 5 0.1 0.5 772124 22700 ? Sl 18:17 0:00 node server.js
在你的 shell 中,檢視程序 1 的狀態
cd /proc/1
cat status
輸出顯示了程序的功能點陣圖
...
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
...
記下功能點陣圖,然後退出你的 shell
exit
接下來,執行一個與前一個容器相同,但設定了額外功能的容器。
以下是執行一個容器的 Pod 的配置檔案。該配置添加了 CAP_NET_ADMIN
和 CAP_SYS_TIME
功能:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-4
spec:
containers:
- name: sec-ctx-4
image: gcr.io/google-samples/hello-app:2.0
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
建立 Pod
kubectl apply -f https://k8s.io/examples/pods/security/security-context-4.yaml
進入執行中的容器的 shell
kubectl exec -it security-context-demo-4 -- sh
在你的 shell 中,檢視程序 1 的功能
cd /proc/1
cat status
輸出顯示程序的功能點陣圖
...
CapPrm: 00000000aa0435fb
CapEff: 00000000aa0435fb
...
比較兩個容器的功能
00000000a80425fb
00000000aa0435fb
在第一個容器的功能點陣圖中,位 12 和 25 是清除的。在第二個容器中,位 12 和 25 是設定的。位 12 是 CAP_NET_ADMIN
,位 25 是 CAP_SYS_TIME
。有關功能常量的定義,請參閱 capability.h。
注意
Linux 功能常量具有CAP_XXX
的形式。但是,當你在容器清單中列出功能時,你必須省略常量中的 CAP_
部分。例如,要新增 CAP_SYS_TIME
,請在你的功能列表中包含 SYS_TIME
。為容器設定 Seccomp 配置檔案
要為容器設定 Seccomp 配置檔案,請在 Pod 或容器清單的 securityContext
部分中包含 seccompProfile
欄位。seccompProfile
欄位是一個 SeccompProfile 物件,由 type
和 localhostProfile
組成。type
的有效選項包括 RuntimeDefault
、Unconfined
和 Localhost
。localhostProfile
必須僅在 type: Localhost
時設定。它指示節點上預配置配置檔案的路徑,相對於 kubelet 配置的 Seccomp 配置檔案位置(透過 --root-dir
標誌配置)。
這是一個將 Seccomp 配置檔案設定為節點容器執行時預設配置檔案的示例:
...
securityContext:
seccompProfile:
type: RuntimeDefault
這是一個將 Seccomp 配置檔案設定為預配置檔案
的示例:
...
securityContext:
seccompProfile:
type: Localhost
localhostProfile: my-profiles/profile-allow.json
為容器設定 AppArmor 配置檔案
要為容器設定 AppArmor 配置檔案,請在容器的 securityContext
部分中包含 appArmorProfile
欄位。appArmorProfile
欄位是一個 AppArmorProfile 物件,由 type
和 localhostProfile
組成。type
的有效選項包括 RuntimeDefault
(預設)、Unconfined
和 Localhost
。localhostProfile
必須僅在 type
為 Localhost
時設定。它指示節點上預配置配置檔案的名稱。該配置檔案需要載入到所有適合 Pod 的節點上,因為你不知道 Pod 將被排程到哪裡。設定自定義配置檔案的方法在設定具有配置檔案的節點中討論。
注意:如果 containers[*].securityContext.appArmorProfile.type
顯式設定為 RuntimeDefault
,則如果節點上未啟用 AppArmor,Pod 將不被允許。但是,如果未指定 containers[*].securityContext.appArmorProfile.type
,則僅當節點上啟用 AppArmor 時才應用預設值(也是 RuntimeDefault
)。如果節點上停用 AppArmor,Pod 將被允許,但容器將不受 RuntimeDefault
配置檔案的限制。
這是一個將 AppArmor 配置檔案設定為節點容器執行時預設配置檔案的示例:
...
containers:
- name: container-1
securityContext:
appArmorProfile:
type: RuntimeDefault
這是一個將 AppArmor 配置檔案設定為名為 k8s-apparmor-example-deny-write
的預配置檔案的示例:
...
containers:
- name: container-1
securityContext:
appArmorProfile:
type: Localhost
localhostProfile: k8s-apparmor-example-deny-write
有關更多詳細資訊,請參閱 使用 AppArmor 限制容器對資源的訪問。
為容器分配 SELinux 標籤
要為容器分配 SELinux 標籤,請在 Pod 或容器清單的 securityContext
部分中包含 seLinuxOptions
欄位。seLinuxOptions
欄位是一個 SELinuxOptions 物件。這是一個應用 SELinux 級別的示例:
...
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
注意
要分配 SELinux 標籤,主機作業系統上必須載入 SELinux 安全模組。在沒有 SELinux 支援的 Windows 和 Linux worker 節點上,此欄位和下面描述的任何 SELinux 功能門控均無效。高效的 SELinux 卷重新標記
Kubernetes v1.28 [beta]
(預設啟用:true)注意
Kubernetes v1.27 引入了這種行為的早期受限形式,僅適用於使用 ReadWriteOncePod
訪問模式的卷(和 PersistentVolumeClaims)。
Kubernetes v1.33 將 SELinuxChangePolicy
和 SELinuxMount
功能門控 提升為 beta 版本,以將效能改進擴充套件到其他型別的 PersistentVolumeClaims,如下文詳細解釋。在 beta 階段,SELinuxMount
仍預設停用。
在停用 SELinuxMount
功能門控(Kubernetes 1.33 和所有早期版本中的預設設定)的情況下,容器執行時預設遞迴地將 SELinux 標籤分配給所有 Pod 捲上的所有檔案。為了加快此過程,Kubernetes 可以透過使用掛載選項 -o context=
立即更改卷的 SELinux 標籤。
要從這種加速中受益,必須滿足所有這些條件:
- 必須啟用 功能門控
SELinuxMountReadWriteOncePod
。 - Pod 必須使用具有適用
accessModes
和 功能門控 的 PersistentVolumeClaim- 卷具有
accessModes: ["ReadWriteOncePod"]
,並且功能門控SELinuxMountReadWriteOncePod
已啟用。 - 或者,卷可以使用任何其他訪問模式,並且所有功能門控
SELinuxMountReadWriteOncePod
、SELinuxChangePolicy
和SELinuxMount
都必須啟用,並且 Pod 的spec.securityContext.seLinuxChangePolicy
為 nil(預設)或MountOption
。
- 卷具有
- Pod(或所有使用 PersistentVolumeClaim 的容器)必須設定
seLinuxOptions
。 - 相應的 PersistentVolume 必須是以下之一:
- 使用傳統樹內
iscsi
、rbd
或fc
卷型別的卷。 - 或使用 CSI 驅動的卷。CSI 驅動必須透過在其 CSIDriver 例項中設定
spec.seLinuxMount: true
來宣告它支援使用-o context
進行掛載。
- 使用傳統樹內
當這些條件中的任何一個不滿足時,SELinux 重新標記將以另一種方式進行:容器執行時遞迴地更改卷中所有 inode(檔案和目錄)的 SELinux 標籤。明確指出,這適用於 Kubernetes 臨時卷(如 secret
、configMap
和 projected
),以及所有其 CSIDriver 例項未明確宣告使用 -o context
進行掛載的卷。
當使用此加速時,在同一節點上同時使用相同適用卷的所有 Pod **必須具有相同的 SELinux 標籤**。具有不同 SELinux 標籤的 Pod 將無法啟動,並將保持 ContainerCreating
狀態,直到刪除所有使用該卷的其他 SELinux 標籤的 Pod。
Kubernetes v1.33 [beta]
(預設啟用:true)spec.securityContext.seLinuxChangePolicy
設定為 Recursive
。當多個 Pod 在同一節點上共享單個卷,但它們使用不同的 SELinux 標籤以允許同時訪問卷時,這是必需的。例如,一個以標籤 spc_t
執行的特權 Pod 和一個以預設標籤 container_file_t
執行的非特權 Pod。如果未設定 spec.securityContext.seLinuxChangePolicy
(或使用預設值 MountOption
),則只有一個此類 Pod 能夠在節點上執行,另一個 Pod 將因錯誤 conflicting SELinux labels of volume <卷名>: <執行中的 Pod 的標籤> and <無法啟動的 Pod 的標籤>
而獲得 ContainerCreating 狀態。SELinuxWarningController
為了更容易識別受 SELinux 卷重新標記更改影響的 Pod,kube-controller-manager 中引入了一個名為 SELinuxWarningController
的新控制器。它預設停用,可以透過設定 --controllers=*,selinux-warning-controller
命令列標誌 或透過在 KubeControllerManagerConfiguration 中設定 genericControllerManagerConfiguration.controllers
欄位 來啟用。此控制器需要啟用 SELinuxChangePolicy
功能門控。
啟用後,控制器會觀察正在執行的 Pod,並在檢測到兩個 Pod 使用具有不同 SELinux 標籤的相同卷時:
- 它向兩個 Pod 發出事件。
kubectl describe pod
顯示SELinuxLabel "
。" 與使用相同卷的 Pod <其他 Pod 名稱> 的 SELinuxLabel "<其他 Pod 標籤>" 衝突。如果兩個 Pod 都落在同一個節點上,則只有一個可以訪問該卷 - 提高
selinux_warning_controller_selinux_volume_conflict
指標。該指標將 Pod 名稱 + 名稱空間作為標籤,以便輕鬆識別受影響的 Pod。
叢集管理員可以使用此資訊來識別受計劃更改影響的 Pod,並主動選擇退出最佳化(即設定 spec.securityContext.seLinuxChangePolicy: Recursive
)。
警告
我們強烈建議使用 SELinux 的叢集啟用此控制器,並確保在啟用SELinuxMount
功能門控或升級到預設啟用 SELinuxMount
的版本之前,selinux_warning_controller_selinux_volume_conflict
指標不報告任何衝突。功能門控
以下功能門控控制 SELinux 卷重新標記的行為:
SELinuxMountReadWriteOncePod
:為具有accessModes: ["ReadWriteOncePod"]
的卷啟用最佳化。這是一個非常安全的功能門控,因為兩個 Pod 無法使用這種訪問模式共享一個卷。此功能門控自 v1.28 起預設啟用。SELinuxChangePolicy
:在 Pod 中啟用spec.securityContext.seLinuxChangePolicy
欄位以及 kube-controller-manager 中相關的 SELinuxWarningController。此功能可以在啟用SELinuxMount
之前使用,以檢查叢集上執行的 Pod,並主動選擇退出最佳化。此功能門控需要啟用SELinuxMountReadWriteOncePod
。它在 1.33 中處於 Beta 階段並預設啟用。SELinuxMount
啟用所有符合條件的卷的最佳化。由於它可能會破壞現有工作負載,我們建議首先啟用SELinuxChangePolicy
功能門控 + SELinuxWarningController 以檢查更改的影響。此功能門控需要啟用SELinuxMountReadWriteOncePod
和SELinuxChangePolicy
。它處於 Beta 階段,但在 1.33 中預設停用。
管理對 /proc
檔案系統的訪問
Kubernetes v1.33 [beta]
(預設啟用:true)對於遵循 OCI 執行時規範的執行時,容器預設以多種路徑被掩蓋且只讀的模式執行。其結果是容器在容器的掛載名稱空間中存在這些路徑,它們的功能類似於容器是隔離主機,但容器程序無法寫入它們。被掩蓋和只讀的路徑列表如下:
被掩蓋的路徑
/proc/asound
/proc/acpi
/proc/kcore
/proc/keys
/proc/latency_stats
/proc/timer_list
/proc/timer_stats
/proc/sched_debug
/proc/scsi
/sys/firmware
/sys/devices/virtual/powercap
只讀路徑
/proc/bus
/proc/fs
/proc/irq
/proc/sys
/proc/sysrq-trigger
對於某些 Pod,你可能希望繞過路徑的預設掩蓋。最常見的情況是當你在 Kubernetes 容器(Pod 內)中執行容器時。
securityContext
欄位 procMount
允許使用者請求容器的 /proc
為 Unmasked
,或由容器程序以讀寫方式掛載。這也適用於不在 /proc
中的 /sys/firmware
。
...
securityContext:
procMount: Unmasked
注意
將procMount
設定為 Unmasked 要求 Pod 規範中的 spec.hostUsers
值為 false
。換句話說:希望具有 Unmasked /proc
或 Unmasked /sys
的容器也必須位於 使用者名稱空間 中。Kubernetes v1.12 到 v1.29 未強制執行此要求。討論
Pod 的安全上下文適用於 Pod 的容器,並在適用時也適用於 Pod 的卷。具體來說,fsGroup
和 seLinuxOptions
應用於卷,如下所示:
fsGroup
:支援所有權管理的卷會被修改,使其由fsGroup
中指定的 GID 擁有且可寫入。有關詳細資訊,請參閱 所有權管理設計文件。seLinuxOptions
:支援 SELinux 標籤的卷會被重新標記,以便由seLinuxOptions
下指定的標籤訪問。通常你只需要設定level
部分。這會設定分配給 Pod 中所有容器以及卷的 多類別安全 (MCS) 標籤。
警告
為 Pod 指定 MCS 標籤後,所有具有相同標籤的 Pod 都可以訪問該卷。如果你需要 Pod 之間的保護,則必須為每個 Pod 分配一個唯一的 MCS 標籤。清理
刪除 Pod
kubectl delete pod security-context-demo
kubectl delete pod security-context-demo-2
kubectl delete pod security-context-demo-3
kubectl delete pod security-context-demo-4
下一步
- PodSecurityContext
- SecurityContext
- CRI 外掛配置指南
- 安全上下文設計文件
- 所有權管理設計文件
- PodSecurity 准入
- AllowPrivilegeEscalation 設計文件
- 有關 Linux 中安全機制的更多資訊,請參閱 Linux 核心安全功能概述(注意:某些資訊已過時)
- 閱讀有關 Linux Pod 的 使用者名稱空間。
- OCI 執行時規範中的掩蓋路徑
此頁面上的專案涉及提供 Kubernetes 所需功能的第三方產品或專案。Kubernetes 專案的作者不對此類第三方產品或專案負責。有關詳細資訊,請參閱 CNCF 網站指南。
在提議新增額外第三方連結的更改之前,你應該閱讀內容指南。