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 核心文件。