kubernetes安全上下文
kubernetes 安全上下文
kubernetes为安全运行pod及容器运行设计了安全上下文机制,该机制允许用户和管理员定义pod或容器的特权与访问控制,已配置容器与主机以及主机之上的其它容器间的隔离级别。安全上下文就是一组用来决定容器时如何创建和运行的约束条件,这些条件代表创建和运行容器时使用的运行时参数。需要提升容器权限时,用户通常只应授予容器执行其工作所需的访问权限,以最小权限法则来抑制容器对基础架构及其它容器产生的负面影响。
kubernetes支持用户在pod及容器级别配置安全上下文,并允许管理员通过pod安全策略在集群全局级别限制用户在创建和运行pod时可设定安全上下文。安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置。 安全上下文包括但不限于:
自主访问控制(DAC):传统UNIX的访问控制机制,它允许对象的所有者基于UUID和GID设定对象的访问权限。
Linux功能:Linux为突破系统上传统的两级用户(root和普通用户)授权模型,而将内核管理权限打散成多个不同维度或级别的权限子集,每个子集称为一种功能或能力,例如CAP_NET_ADMIN、CAP_SYS_TIME、CAP_SYS_PTRACE和CAP_SYS_ADMIN等,从而允许进程仅具有一部分内核管理功能就能完成必要的管理任务。
seccomp:全称为secure computing mode,是linux内核的安全模型,用于为默认可发起的任何系统调用进程施加控制机制,人为地禁止它能够发起的系统调用,有效降低了程序被劫持的危害级别。
AppArmor:全称为Application Armor,意为应用盔甲,是linux内核的一个安全模块,通过加载带内核的配置文件来定义对程序的约束与控制。
SELinux:全称为Security-Enhanced Linux,意为安全加强的Linux,是linux内核的一个安全模块,提供了包括强制访问控制在内的访问控制安全策略机制。
Privileged模式:即特权模式容器,该模式下容器中的root用户拥有所有的内核功能,即具有真正的管理员权限,它能看到主机上的所有设备,能够挂载文件系统,甚至可以在容器中运行容器;容器默认运行于非特权模式。 AllowPrivilegeEscalation:控制是否允许特权升级,及进程是否能够获取比父进程更多的特权;运行于特权模式或具有CAP_SYS_ADMIN能力的容器默认允许特权升级。
这些安全上下文相关的特性多数嵌套定义在pod或容器的securityContext字段中,而且有些特性对应的嵌套字段还不止一个。而seccomp和AppArmor的安全上下文则需要以资源注解的方式进行定义,而且技能由管理员在集群级别进行pod安全策略配置。
配置格式
apiVersion: v1
kind: Pod
metadata:
name: securitycontext-capabilities-demo
namespace: default
spec:
securityContext: #pod级别的安全上下文,对内部多有容器均有效
runAsUer <integer> #以指定的用户身份运行容器进程,默认由镜像中的USER指定
runAsGroup <integer> #以指定的用户组运行容器进程,默认使用的组随容器运行时设定
supplementalGroups <[] integer> #为容器中1号进程的用户添加的附加组
fsGroup <integer> #为容器中的1号进程附加一个专用组,其功能类似于sgid
runAsNonRoot <boolean> #是否以非root身份运行
seLinuxOptions <object> #SELINUX的相关配置
sysctl <[] object> #应用到当前pod名称空间级别的sysctl参数设置列表
windowsOptions <object> #windows容器专用配置
containers:
- name: ...
image: ...
securityContext: #容器级别的安全上下文,仅在当前容器生效
runAsUer <integer> #以指定的用户身份运行容器进程,默认由镜像中的USER指定
runAsGroup <integer> #以指定的用户组运行容器进程,默认使用的组随容器运行时设定
runAsNonRoot <boolean> #是否以非root身份运行
allowPrivilegeEscalation <boolean> #是否允许特权升级
capabilities <object> #为当前容器添加或删除内核能力
add <[] string> #添加由列表定义的各项内核能力
drop <[] string> #移除由列表定义的各项内核能力
privileged <boolean> #是否允许为特权容器
procMount <string> #设置容器procMount类型,默认为DefaultProcMount
readOnlyRootFilesystem <boolean> #是否将根文件系统设置为只读模式
seLinuxOptions <object> #selinux相关配置
windowsOptions <object> #windows相关配置
内核功能
传统linux仅实现了特权和非特权两类进程,前者是指以0号UID身份运行的进程,而后者则是从属非0号UID用户的进程。linux内核从2.2版本开始将附加在超级用户的权限分割为多个独立单元,这些单元是线程级别的,它们可配置在每个线程之上为其赋予特定的管理能力。linux内核常用的功能包括但不限于如下这些:
CAP_CHOWN:改变文件的UID和GID。
CAP_MKNOD:借助系统调用mknod()创建设备文件。
CAP_NET_ADMIN:网络管理相关的操作,可用于管理网络接口、netfilter上的iptables规则、路由表、透明代理、TOS、清空驱动统计数据、设计混杂模式和启动多播功能等。
CAP_NET_BIND_SERVICE:绑定小于1024的特权端口,但该功能在重新映射用户后可能会失效。 CAP_NET_RAW:使用RAW或PACKET类型的套接字,并可绑定任何地址进行透明代理。
CAP_SYS_ADMIN:支持内核上的很大一部分管理功能。
CAP_SYS_BOOT:重启系统
CAP_SYS_CHROOT:使用chroot()进行根文件系统切换,并能够调用setns()修改Mount名称空间
CAP_SYS_MODULE:转载内核模块
CAP_SYS_TIME:设定系统时钟和硬件时钟
CAP_SYSLOG:调用syslog()执行日志相关的特权操作。
内核功能示例
apiVersion: v1
kind: Pod
metadata:
name: securitycontext-capabilities-demo
namespace: default
spec:
containers:
- name: demo
image: myapp:v1.0
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
add: ['NET_ADMIN']
drop: ['CHOWN']
特权容器
kubernetes集群中,kube-proxy中的容器就运行在特权模式
例如:
#查看kube-proxy yaml
kubectl get pods -n kube-system kube-proxy-ggdx8 -o yaml
apiVersion: v1
kind: Pod
metadata:
...
namespace: kube-system
...
containers:
- command:
- /usr/local/bin/kube-proxy
- --config=/var/lib/kube-proxy/config.conf
- --hostname-override=$(NODE_NAME)
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: registry.aliyuncs.com/google_containers/kube-proxy:v1.28.5
imagePullPolicy: IfNotPresent
name: kube-proxy
resources: {}
securityContext:
privileged: true
...
在pod中使用sysctl
kubernetes允许在pod中独立安全地设置支持名称空间级别的内核参数,它们默认处于启动状态,而节点级别内核参数则被认为是不安全地,它们默认处于禁用状态。kernel.shm_rmid_force、net.ipv4.ip_local_range和net.ipv4.tcp_sysncookies这3个内核参数被kubernetes视为安全参数,它们在pod安全上下文的sysctl参数内嵌套使用,而余下的绝大多数的内核参数都是非安全参数,需要管理员手动在每个节点上通过kubelet选项逐个启用后才能配置到pod上。例如在各工作节点上编辑/etc/default/kubelet文件加入KUBELET_EXTRA_ARGS='--allowed-unsafe-sysctls=net.core.somaxconn,net.ipv4.ip_unprivileged_port_start',添加以下内容允许在pod上使用指定的两个非安全地内核参数,并重启kubelet服务使之生效。
例如:
apiVersion: v1
kind: Pod
metadata:
name: securitycontext-sysctls-demo
namespace: default
spec:
securityContext:
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
containers:
- name: demo
image: myapp:v1.0
imagePullPolicy: IfNotPresent
securityContext:
runAsUser: 1001
runAsGroup: 1001
官方文档
Configure a Security Context for a Pod or Container | Kubernetes