K8S 容器執行時安全設定
容器安全性-為容器配置安全上下文
安全上下文(Security Context)定義 Pod 或 Container 的特權與訪問控制設定。 安全上下文包括但不限於:
-
自主訪問控制(Discretionary Access Control):基於 使用者 ID(UID)和組 ID(GID). 來判定對物件(例如檔案)的訪問許可權。
-
安全性增強 Linux(SELinux): 為物件賦予安全性標籤,需要使用者自行開啟Selinux模組。
-
以特權模式或者非特權模式執行。
-
Linux Capabilities: 為程序賦予 root 使用者的部分特權而非全部特權。
-
AllowPrivilegeEscalation:控制程序是否可以獲得超出其父程序的特權。 此布林值直接控制是否為容器程序設定
no_new_privs
標誌。 當容器以特權模式執行或者具有CAP_SYS_ADMIN
權能時,AllowPrivilegeEscalation 總是為 true。 -
readOnlyRootFilesystem:以只讀方式載入容器的根檔案系統。
這裡主要演示:Discretionary Access Control
,Linux Capabilities
設定Discretionary Access Control
yaml示例:
apiVersion: v1 kind: Pod metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 volumes: - name: sec-ctx-vol emptyDir: {} containers: - name: sec-ctx-demo image: registry.acs.env26.shuguang-ops.com/acs/nginx:1.16 command: [ "sh", "-c", "sleep 1h" ] volumeMounts: - name: sec-ctx-vol mountPath: /data/demo securityContext: allowPrivilegeEscalation: false
在配置檔案中,runAsUser 欄位指定 Pod 中的所有容器內的程序都使用使用者 ID 1000 來執行。runAsGroup 欄位指定所有容器中的程序都以主組 ID 3000 來執行。 如果忽略此欄位,則容器的主組 ID 將是 root(0)。
當 runAsGroup 被設定時,所有建立的檔案也會劃歸使用者 1000 和組 3000。 由於 fsGroup 被設定,容器中所有程序也會是附組 ID 2000 的一部分。 卷 /data/demo 及在該卷中建立的任何檔案的屬主都會是組 ID 2000。
驗證:
kubectl exec -it security-context-demo -- /bin/bash $ id # 可以看到,容器使用的使用者不在是root(id=0),而是我們設定的值 uid=1000 gid=3000 groups=3000,2000
為容器設定Linux Capabilities
使用 Linux Capabilities,你可以 賦予程序 root 使用者所擁有的某些特權,但不必賦予其全部特權。 要為 Container 新增或移除 Linux 權能,可以在 Container 清單的 securityContext
節 包含 capabilities
欄位。
首先,檢視不包含 capabilities
欄位時候會發生什麼。 下面是一個配置檔案,其中沒有新增或移除容器的權能:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-1
spec:
containers:
- name: sec-ctx-1
image: gcr.io/google-samples/node-hello:1.0
通過控制檯建立pod,然後登入到容器中kubectl exec -it security-context-demo-1 -- /bin/bash
檢視程序1的狀態:
# cd /proc/1 && cat status
輸出Capality點陣圖:
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
然後,執行一個設定了Capality的容器:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-2
spec:
containers:
- name: sec-ctx-2
image: registry.acs.env26.shuguang-ops.com/acs/nginx:1.16
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
通過控制檯建立pod,然後登入到容器中kubectl exec -it security-context-demo-2 -- /bin/bash
檢視程序1的狀態:
# cd /proc/1 && cat status
輸出Capality點陣圖:
...
CapPrm: 00000000aa0435fb
CapEff: 00000000aa0435fb
...
對比發現:在第一個容器的權能點陣圖中,位 12 和 25 是沒有設定的。在第二個容器中,位 12 和 25 是設定了的。位 12 是 CAP_NET_ADMIN
而位 25 則是 CAP_SYS_TIME
。 參見 capability.h 瞭解權能常數的定義。
設定Selinux
若要給 Container 設定 SELinux 標籤,可以在 Pod 或 Container 清單的 securityContext
節包含 seLinuxOptions
欄位。 seLinuxOptions
欄位的取值是一個 SELinuxOptions 物件。下面是一個應用 SELinux 標籤的例子:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-3
spec:
containers:
- name: sec-ctx-3
image: registry.acs.env26.shuguang-ops.com/acs/nginx:1.16
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
說明: 要指定 SELinux,需要在宿主作業系統中裝載 SELinux 安全性模組。
文章參考:官方文章