Security Context 概述及配置
Security Context 概述
Security Context(安全上下文)用来限制容器对宿主节点的可访问范围,以避免容器非法操作宿主节点的系统级别的内容,使得节点的系统或者节点上其他容器组受到影响。
Security Context可以按照如下几种方式设定:
- 访问权限控制:是否可以访问某个对象(例如文件)是基于 userID(UID)和 groupID(GID)的
- Security Enhanced Linux (SELinux):为对象分配Security标签
- 以 privileged(特权)模式运行
- Linux Capabilities:为容器组(或容器)分配一部分特权,而不是 root 用户的所有特权
- AppArmor:自 Kubernetes v1.4 以来,一直处于 beta 状态
- Seccomp:过滤容器中进程的系统调用(system call)
- AllowPrivilegeEscalation(允许特权扩大):此项配置是一个布尔值,定义了一个进程是否可以比其父进程获得更多的特权,直接效果是,容器的进程上是否被设置 no_new_privs 标记。当出现如下情况时,AllowPrivilegeEscalation 的值始终为 true:
- 容器以 privileged 模式运行
- 容器拥有 CAP_SYS_ADMIN 的 Linux Capability
为Pod设置Security Context
在 Pod 的定义中增加 securityContext 字段,即可为 Pod 指定 Security 相关的设定。 securityContext 字段是一个 PodSecurityContext 对象。通过该字段指定的内容将对该 Pod 中所有的容器生效。
Pod示例:
1 | apiVersion: v1 |
在上面的例子中:
spec.securityContext.runAsUser 字段指定了该 Pod 中所有容器的进程都以UserID 1000 的身份运行,spec.securityContext.runAsGroup 字段指定了该 Pod 中所有容器的进程都以GroupID 3000 的身份运行
- 如果该字段被省略,容器进程的GroupID为 root(0)
- 容器中创建的文件,其所有者为 userID 1000,groupID 3000
spec.securityContext.fsGroup 字段指定了该 Pod 的 fsGroup 为 2000
- 数据卷 (本例中,对应挂载点 /data/demo 的数据卷为 sec-ctx-demo) 的所有者以及在该数据卷下创建的任何文件,其 GroupID 为 2000
执行Pod示例
- 创建 Pod
1 | [root@k8s-master 0425]# kubectl apply -f security-context-1.yaml |
- 验证 Pod 已运行
1 | [root@k8s-master 0425]# kubectl get pod security-context-demo |
- 进入容器的命令行界面
1 | [root@k8s-master 0425]# kubectl exec -it security-context-demo -- sh |
- 在该命令行界面中,查看正在运行的进程,所有的进程都以 user 1000 的身份运行(由 runAsUser 指定)
1 | / $ ps |
- 切换到目录 /data,并查看目录中的文件列表,/data/demo 目录的 groupID 为 2000(由 fsGroup 指定)
1 | / $ cd /data/ |
- 在命令行界面中,切换到目录 /data/demo,并创建一个文件,testfile 的 groupID 为 2000 (由 FSGroup 指定),输出结果如下所示:
1 | / $ cd /data/demo/ |
- 在命令行界面中执行 id 命令,输出结果如下所示:
1 | /data/demo $ id |
- gid 为 3000,与
runAsGroup字段所指定的一致 - 如果
runAsGroup字段被省略,则 gid 取值为 0(即 root),此时容器中的进程将可以操作 root Group 的文件
为容器设置Security Context
容器的定义中包含 securityContext 字段,该字段接受 SecurityContext 对象。通过指定该字段,可以为容器设定安全相关的配置,当该字段的配置与 Pod 级别的 securityContext 配置相冲突时,容器级别的配置将覆盖 Pod 级别的配置。容器级别的 securityContext 不影响 Pod 中的数据卷。
下面的示例中的 Pod 包含一个 Container,且 Pod 和 Container 都有定义 securityContext 字段:
1 | apiVersion: v1 |
- 执行命令以创建 Pod
1 | [root@k8s-master 0426]# kubectl apply -f security-context-demo-2.yaml |
- 执行命令以验证容器已运行
1 | [root@k8s-master 0426]# kubectl get pod security-context-demo-2 |
- 执行命令进入容器的命令行界面:
1 | [root@k8s-master 0426]# kubectl exec -it security-context-demo-2 -- sh |
注意: 容器的进程以 userID 2000 的身份运行。该取值由 spec.containers[*].securityContext.runAsUser 容器组中的字段定义。Pod 中定义的 spec.securityContext.runAsUser 取值 1000 被覆盖。
为容器设置SELinux标签
Pod 或容器定义的 securityContext 中 seLinuxOptions 字段是一个 SELinuxOptions 对象,该字段可用于为容器指定 SELinux 标签。如下所示:
1 | securityContext: |
为容器指定 SELinux 标签时,宿主节点的 SELinux 模块必须加载。
关于数据卷
Pod 的 securityContext 作用于 Pod 中所有的容器,同时对 Pod 的数据卷也同样生效。具体来说,fsGroup 和 seLinuxOptions 将被按照如下方式应用到 Pod 中的数据卷:
fsGroup:对于支持 ownership 管理的数据卷,通过fsGroup指定的 GID 将被设置为该数据卷的 owner,并且可被fsGroup写入。seLinuxOptions:对于支持 SELinux 标签的数据卷,将按照seLinuxOptions的设定重新打标签,以使 Pod 可以访问数据卷内容。通常只需要设置seLinuxOptions中level这一部分内容。该设定为 Pod 中所有容器及数据卷设置 Multi-Category Security (MCS) 标签。