Kubernetes securityContext

前言

kubernetes 中的 securityContext 是什么?在什么场景下来使用?第一感觉反正是和安全相关的东西,来自官方定义如下:

安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置。 安全上下文包括但不限于:

  • 自主访问控制(Discretionary Access Control):基于 用户 ID(UID)和组 ID(GID). 来判定对对象(例如文件)的访问权限
  • 安全性增强的 Linux(SELinux): 为对象赋予安全性标签。
  • 以特权模式或者非特权模式运行。
  • Linux 权能: 为进程赋予 root 用户的部分特权而非全部特权。
  • AppArmor:使用程序文件来限制单个程序的权限。
  • Seccomp:限制一个进程访问文件描述符的权限。
  • AllowPrivilegeEscalation:控制进程是否可以获得超出其父进程的特权。 此布尔值直接控制是否为容器进程设置 no_new_privs 标志。 当容器以特权模式运行或者具有 CAP_SYS_ADMIN 权能时,AllowPrivilegeEscalation 总是为 true
  • readOnlyRootFilesystem:以只读方式加载容器的根文件系统。

以上条目不是安全上下文设置的完整列表 – 请参阅 SecurityContext 了解其完整列表。

关于在 Linux 系统中的安全机制的更多信息,可参阅 Linux 内核安全性能力概述

上面的定义有些似懂非懂,能不能更加直白的描述下呢?好吧,下面来给大家来一些实际的应用场景来讲解下。

Security Context 应用场景

场景一:我有个镜像,已非root用户运行,同时我需要挂载一块磁盘,需要将对应权限改成当前运行的用户

有了上面的场景,那我们如何来进行设定呢?假设运行用户对应的 uid为999 gid为999

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sc-demo
spec:
template:
securityContext:
runAsUser: 1000
runAsGroup: 999
fsGroup: 0
containers:
- name: sc-demo
image: xxxxxx
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sc-vol
mountPath: /data/demo
securityContext:
runAsUser: 999
volumeClaimTemplates:
- metadata:
name: sc-vol
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
storageClassName: gp2

这里有两个 securityContext 设定,一个是针对 pod 级别的,另外一个则是针对 container 级别的,那两者的优先级如何定义呢?规则就是:container中的会覆写pod中的定义。了解了优先级后,来讲解下 runAsUser、runAsGroup、fsGroup 这三个参数的意义。

  • runAsUser 字段指定 Pod 中的所有容器内的进程都使用 用户ID 1000 来运行。但这里 sc-demo 容器进行了覆写,如果 sc-demo 容器内的进行使用用户 ID 为999来运行
  • runAsGroup 字段指定所有容器中的进程都以主 组ID 999 来运行。 如果忽略此字段,则容器的 主组ID 将是 root(0)。 当 runAsGroup 被设置时,所有创建的文件也会划归为 用户1000 和 组999。
  • fsGroup 由于 fsGroup 被设置,容器中所有进程也会是附 组ID 0 (root) 的一部分。 卷 /data/demo 及在该卷中创建的任何文件的属主都会是 组ID 0 (root)。

进入容器中查看

1
2
3
4
5
$ id
uid=999(xx) gid=999(xx) groups=999(xx),0(root)

$ ls -l /data/demo
drwxrwsr-x 3 xx root 4096 Sep 8 17:51 test

为 Pod 配置卷访问权限和属主变更策略

FEATURE STATE: Kubernetes v1.18 [alpha]

默认情况下,Kubernetes 在挂载一个卷时,会递归地更改每个卷中的内容的属主和访问权限,使之与 Pod 的 securityContext 中指定的 fsGroup 匹配。 对于较大的数据卷,检查和变更属主与访问权限可能会花费很长时间,降低 Pod 启动速度。 你可以在 securityContext 中使用 fsGroupChangePolicy 字段来控制 Kubernetes 检查和管理卷属主和访问权限的方式。

fsGroupChangePolicy - fsGroupChangePolicy 定义在卷被暴露给 Pod 内部之前对其 内容的属主和访问许可进行变更的行为。此字段仅适用于那些支持使用 fsGroup 来 控制属主与访问权限的卷类型。此字段的取值可以是:

  • OnRootMismatch:只有根目录的属主与访问权限与卷所期望的权限不一致时,才改变其中内容的属主和访问权限。这一设置有助于缩短更改卷的属主与访问权限所需要的时间。
  • Always:在挂载卷时总是更改卷中内容的属主和访问权限。
1
2
3
4
5
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"

这是一个 Alpha 阶段的功能特性。要使用此特性,需要在 kube-apiserver、kube-controller-manager 和 kubelet 上启用 ConfigurableFSGroupPolicy 特性门控

场景二:我需要对启动的容器使用sysctl修改内核参数,比如es这类容器镜像。

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sc-demo
spec:
template:
containers:
- name: sc-demo
image: xxxxxx
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
privileged: true

给予 privileged: true 是一个比较粗的权限,一般不建议如此,可以为权限定义更细粒度的权限,类似需要在容器中使用 perf 命令,则可以进行如下定义:

1
2
3
4
...
securityContext:
capabilities:
add: ["SYS_ADMIN"]

具体 capabilities 的使用规则可参考:在 Kubernetes 中配置 Container Capabilities

场景三:我需要对启动的容器赋予SELinux标签

1
2
3
4
...
securityContext:
seLinuxOptions:
level: "s0:c123,c456"

要指定 SELinux,需要在宿主操作系统中装载 SELinux 安全性模块。seLinuxOptions 字段的取值是一个 SELinuxOptions 对象

参考

微信订阅号

-------------本文结束感谢您的阅读-------------

本文标题:Kubernetes securityContext

文章作者:icyboy

发布时间:2020年09月09日 - 20:00

最后更新:2020年09月09日 - 18:25

原始链接:http://team.jiunile.com/blog/2020/09/k8s-securitycontext.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。