Seccomp 和 Kubernetes
Seccomp 表示安全计算(Secure Computing)模式,自 2.6.12 版本以来,一直是 Linux 内核的一个特性。 它可以用来沙箱化进程的权限,限制进程从用户态到内核态的调用。 Kubernetes 能使你自动将加载到节点上的 seccomp 配置文件应用到你的 Pod 和容器。
Seccomp 字段
Kubernetes v1.19 [stable]
有四种方式可以为 Pod 指定 seccomp 配置文件:
- 为整个 Pod 使用
spec.securityContext.seccompProfile
- 为单个容器使用
spec.containers[*].securityContext.seccompProfile
- 为(可重启/边车)Init 容器使用
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
。
如果临时容器或 Init 容器没有明确设置 securityContext.seccompProfile
字段,
则此值将从 Pod 继承。同样的机制也适用于运行 Localhost
配置文件 my-profile.json
的容器。
一般来说,(临时)容器的字段优先级高于 Pod 层级的值,而未设置 seccomp 字段的容器则从 Pod 继承配置。
说明:
你不可以将 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
配置文件
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 内核文档。
进一步阅读
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.