Seccomp 和 Kubernetes
Seccomp 表示安全计算模式,自 2.6.12 版本以来一直是 Linux 内核的一项功能。它可以用于沙盒化进程的权限,限制它能够从用户空间向内核发起的调用。Kubernetes 允许您将加载到节点上的 seccomp 配置文件自动应用于您的 Pod 和容器。
Seccomp 字段 (Seccomp fields)
Kubernetes v1.19 [稳定]
有四种方法可以为Pod 指定 seccomp 配置文件
- 使用
spec.securityContext.seccompProfile
为整个 Pod 指定 - 使用
spec.containers[*].securityContext.seccompProfile
为单个容器指定 - 使用
spec.initContainers[*].securityContext.seccompProfile
为(可重启/sidecar)初始化容器指定 - 使用
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 继承配置文件。
注意 (Note)
无法将 seccomp 配置文件应用于在容器的 `securityContext` 中设置了 `privileged: true` 的 Pod 或容器。特权容器始终以 `Unconfined` 运行。以下是 `seccompProfile.type` 的可能值
Unconfined(无限制)
- 工作负载运行时没有任何 seccomp 限制。
RuntimeDefault(运行时默认)
- 应用由容器运行时定义的默认 seccomp 配置文件。默认配置文件旨在提供一组强大的安全默认设置,同时保留工作负载的功能。默认配置文件可能在不同的容器运行时及其发行版本之间有所不同,例如比较CRI-O和containerd的默认配置文件。
Localhost(本地主机)
- 将应用 `localhostProfile`,它必须在节点磁盘上可用(在 Linux 上是 `/var/lib/kubelet/seccomp`)。seccomp 配置文件的可用性由容器运行时在容器创建时验证。如果配置文件不存在,则容器创建将失败并显示 `CreateContainerError`。
`Localhost` 配置文件 (`Localhost` profiles)
Seccomp 配置文件是遵循OCI 运行时规范定义的方案的 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 运行时规范 和 Seccomp Linux 内核文档。