Seccomp 和 Kubernetes
Seccomp 是 secure computing mode(安全計算模式)的縮寫,自 2.6.12 版本起一直是 Linux 核心的一項功能。它可用於對程序的許可權進行沙盒化,限制其能從使用者空間發起到核心的呼叫。Kubernetes 允許您將載入到 節點 上的 seccomp 配置檔案自動應用到您的 Pod 和容器。
Seccomp 欄位
Kubernetes v1.19 [stable]有四種方式可以為 Pod 指定 seccomp 配置檔案:
- 使用
spec.securityContext.seccompProfile為整個 Pod 設定 - 使用
spec.containers[*].securityContext.seccompProfile為單個容器設定 - 使用
spec.initContainers[*].securityContext.seccompProfile為(可重啟 / 邊車)初始化容器設定 - 使用
spec.ephemeralContainers[*].securityContext.seccompProfile為 臨時容器 設定
apiVersion: v1
kind: Pod
metadata:
name: pod
spec:
securityContext:
seccompProfile:
type: Unconfined
ephemeralContainers:
- name: ephemeral-container
image: debian
securityContext:
seccompProfile:
type: RuntimeDefault
initContainers:
- name: init-container
image: debian
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: container
image: docker.io/library/debian:stable
securityContext:
seccompProfile:
type: Localhost
localhostProfile: my-profile.json
上面的示例 Pod 以 Unconfined 模式執行,而 ephemeral-container 和 init-container 則明確定義了 RuntimeDefault。如果臨時容器或初始化容器未顯式設定 securityContext.seccompProfile 欄位,則將從 Pod 繼承該值。對於執行 Localhost 配置檔案 my-profile.json 的容器也是如此。
總的來說,(臨時)容器的欄位優先順序高於 Pod 級別的設定,而未設定 seccomp 欄位的容器則繼承 Pod 的配置檔案。
注意
對於在容器的securityContext 中設定了 privileged: true 的 Pod 或容器,無法應用 seccomp 配置檔案。特權容器始終以 Unconfined 模式執行。seccompProfile.type 可能的取值如下:
Unconfined- 工作負載在沒有任何 seccomp 限制的情況下執行。
RuntimeDefault- 應用由 容器執行時 定義的預設 seccomp 配置檔案。預設配置檔案旨在提供強大的安全預設設定,同時保留工作負載的功能。預設配置檔案可能因容器執行時及其釋出版本而異,例如,比較 CRI-O 和 containerd 之間的差異。
Localhost- 將應用
localhostProfile,該檔案必須存在於節點磁碟上(在 Linux 上是/var/lib/kubelet/seccomp)。在容器建立時,由 容器執行時 驗證 seccomp 配置檔案的可用性。如果配置檔案不存在,則容器建立將失敗並出現CreateContainerError。
localhostProfile
Seccomp 配置檔案是遵循 OCI runtime specification 定義的模式的 JSON 檔案。配置檔案主要根據匹配的系統呼叫定義操作,但也允許將特定值作為引數傳遞給系統呼叫。例如:
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 38,
"syscalls": [
{
"names": [
"adjtimex",
"alarm",
"bind",
"waitid",
"waitpid",
"write",
"writev"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
上面的配置檔案中的 defaultAction 被定義為 SCMP_ACT_ERRNO,並作為回退返回到 syscalls 中定義的動作。錯誤碼透過 defaultErrnoRet 欄位定義為 38。
通常可能的動作包括:
SCMP_ACT_ERRNO- 返回指定的錯誤碼。
SCMP_ACT_ALLOW- 允許執行系統呼叫。
SCMP_ACT_KILL_PROCESS- 終止程序。
SCMP_ACT_KILL_THREAD和SCMP_ACT_KILL- 僅終止執行緒。
SCMP_ACT_TRAP- 丟擲
SIGSYS訊號。 SCMP_ACT_NOTIFY和SECCOMP_RET_USER_NOTIF。- 通知使用者空間。
SCMP_ACT_TRACE- 使用指定的值通知跟蹤程序。
SCMP_ACT_LOG- 在將系統呼叫操作記錄到 syslog 或 auditd 後,允許執行該系統呼叫。
某些操作(如 SCMP_ACT_NOTIFY 或 SECCOMP_RET_USER_NOTIF)可能不受支援,具體取決於所使用的容器執行時、OCI 執行時或 Linux 核心版本。可能還存在進一步的限制,例如 SCMP_ACT_NOTIFY 不能用作 defaultAction 或用於某些系統呼叫(如 write)。所有這些限制由 OCI 執行時(runc,crun)或 libseccomp 定義。
syscalls JSON 陣列包含一個物件列表,這些物件透過各自的 names 引用系統呼叫。例如,SCMP_ACT_ALLOW 操作可用於建立允許的系統呼叫白名單,如上面的示例所示。也可以定義另一個使用 SCMP_ACT_ERRNO 操作但具有不同返回值(errnoRet)的列表。
還可以指定傳遞給某些系統呼叫的引數(args)。有關這些高階用例的更多資訊,請參閱 OCI runtime spec 和 Seccomp Linux 核心文件。