安全上下文(Security Context):
K8s对pod和容器提供的安全机制,可以设置Pod特权和访问控制
安全上下文限制维度:
1.自主访问控制((DiscretionaryAccess Control):
基于用户ID(UID)和组ID(GID),来判定对对象(例如文件)的访问权限
2.安全性增强的Linux(SELinux):
为对象赋予安全性标签
3.以特权模式或者非特权模式运行
4.Linux Capabilities:
为进程赋予root用户的部分特权而非全部特权
5.AppArmor:
定义使用AppArmor限制容器对资源访问限制
6.Seccomp:
定义pod使用Seccomp限制容器进程的系统调用
7. AllowPrivilegeEscalation:
禁止容器中进程(通过 SetUID 或 SetGID 文件模式)获得特权提升。当容器以特权模式运行或者具有CAP_SYS_ADMIN能力时,AllowPrivilegeEscalation总为True。
8. readOnlyRootFilesystem:
以只读方式加载容器的根文件系统。
Linux Capabilities:Capabilities是一个内核级别的权限,它允许对内核调用权 限进行更细粒度的控制,而不是简单地以 root 身份能力授权。 Capabilities 包括更改文件权限、控制网络子系统和执行系统管理等功能。在securityContext 中,可以添加或删除 Capabilities,做到容器精细化权限控制。CAP_可以省略不写
【】capsh --print第一行为当前用户的
capability 名称
描述
CAP_AUDIT_CONTROL
启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则
CAP_AUDIT_READ
允许通过 multicast netlink 套接字读取审计日志
CAP_AUDIT_WRITE
将记录写入内核审计日志
CAP_BLOCK_SUSPEND
使用可以阻止系统挂起的特性
CAP_CHOWN
修改文件所有者的权限
CAP_DAC_OVERRIDE
忽略文件的 DAC 访问限制
CAP_DAC_READ_SEARCH
忽略文件读及目录搜索的 DAC 访问限制
CAP_FOWNER
忽略文件属主 ID 必须和进程用户 ID 相匹配的限制
CAP_FSETID
允许设置文件的 setuid 位
CAP_IPC_LOCK
允许锁定共享内存片段
CAP_IPC_OWNER
忽略 IPC 所有权检查
CAP_KILL
允许对不属于自己的进程发送信号
CAP_LEASE
允许修改文件锁的 FL_LEASE 标志
CAP_LINUX_IMMUTABLE
允许修改文件的 IMMUTABLE 和 APPEND 属性标志
CAP_MAC_ADMIN
允许 MAC 配置或状态更改
CAP_MAC_OVERRIDE
忽略文件的 DAC 访问限制
CAP_MKNOD
允许使用 mknod() 系统调用
CAP_NET_ADMIN
允许执行网络管理任务
CAP_NET_BIND_SERVICE
允许绑定到小于 1024 的端口
CAP_NET_BROADCAST
允许网络广播和多播访问
CAP_NET_RAW
允许使用原始套接字
CAP_SETGID
允许改变进程的 GID
CAP_SETFCAP
允许为文件设置任意的 capabilities
CAP_SETPCAP
参考 capabilities man page
CAP_SETUID
允许改变进程的 UID
CAP_SYS_ADMIN
允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等
CAP_SYS_BOOT
允许重新启动系统
CAP_SYS_CHROOT
允许使用 chroot() 系统调用
CAP_SYS_MODULE
允许插入和删除内核模块
CAP_SYS_NICE
允许提升优先级及设置其他进程的优先级
CAP_SYS_PACCT
允许执行进程的 BSD 式审计
CAP_SYS_PTRACE
允许跟踪任何进程
CAP_SYS_RAWIO
允许直接访问 /devport、/dev/mem、/dev/kmem 及原始块设备
CAP_SYS_RESOURCE
忽略资源限制
CAP_SYS_TIME
允许改变系统时钟
CAP_SYS_TTY_CONFIG
允许配置 TTY 设备
CAP_SYSLOG
允许使用 syslog() 系统调用
CAP_WAKE_ALARM
允许触发一些能唤醒系统的东西(比如 CLOCK_BOOTTIME_ALARM 计时器)
案例1:设置容器以普通用户运行
背景:容器中的应用程序默认以root账号运行的,这个root与宿主机root账号是相同的, 拥有大部分对Linux内核的系统调用权限,这样是不安全的,所以我们应该将容器以普 通用户运行,减少应用程序对权限的使用。 可以通过两种方法设置普通用户:
1 Dockerfile里使用USER指定运行用户
2 K8s里指定spec.securityContext.runAsUser,指定容器默认用户UID
spec:
securityContext:
runAsUser: 1000 # 镜像里必须有这个用户UID
fsGroup: 1000 # 数据卷挂载后的目录属组设置为该组
containers:
-image: flask-demo:root (镜像自制即可)
name: web
securityContext:
allowPrivilegeEscalation: false # 不允许提权
方法1.Dockerfile
1)可以先注释USER看效果
【】cat /root/flask-demo/Dockerfile
FROM python
RUN useradd python
RUN mkdir /data/www -p
COPY . /data/www
RUN chown -R python /data
RUN pip install flask -i https://mirrors.aliyun.com/pypi/simple/&& \
pip install prometheus_client -i https://mirrors.aliyun.com/pypi/simple/
WORKDIR /data/www
#USER python
CMD python main.py
【】docker build -t flask-demo:v1 .
【】docker run -d --name demo-v1 -p 8080:8080 flask-demo:v1
【】docker exec -it demo-v1 bash
在宿主机查看也有该进程且为root
2)以普通账号运行
cat /root/flask-demo/Dockerfile
FROM python
RUN useradd python
RUN mkdir /data/www -p
COPY . /data/www
RUN chown -R python /data
RUN pip install flask -i https://mirrors.aliyun.com/pypi/simple/&& \
pip install prometheus_client -i https://mirrors.aliyun.com/pypi/simple/
WORKDIR /data/www
USER python
CMD python main.py
【】docker build -t flask-demo:v2 .
【】docker run -d --name demo-v2 -p 8081:8080 flask-demo:v1
【】docker exec -it demo-v2 bash
方法2:K8s里指定spec.securityContext.runAsUser,指定容器默认用户UID
【】kubectl create deployment flask-demo --image=nginx --dry-run=client -o yaml >deployment.yaml
【】vim deploymeny.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: flask-demo
name: flask-demo
spec:
replicas: 1
selector:
matchLabels:
app: flask-demo
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: flask-demo
spec:
securityContext:
runAsUser: 1000 # 镜像里必须有这个用户UID
fsGroup: 1000 # 数据卷挂载后的目录属组设置为该组
containers:
- image: flask-demo:v1 #上文创建的镜像,默认root权限
name: nginx
resources: {}
nodeName: "k8s-master1"
进入容器查看id
若使用镜像中不存在的用户则会创建一个普通账号
使用v2版镜像,默认以1000用户则不需要设置上下文即可,默认就是用户id为1000
案列2:避免使用特权容器
背景:容器中有些应用程序可能需要访问宿主机设备、修改内核等需求(容器引擎已经组止了,测不出来),在默认情况下,容器没有这个能力,因此此时会考虑给容器是设置特权模式。
启用特权模式:
containers:
- image:flask-demo:root
name:web
securityContext:
privileged: true#启用特权
启用特权模式就意味着,你要为容器提供了访问linux内核的所有能力,这是很危险的,为了减少系统调用的供给,可以使用Capabilities为容器赋予仅所需的能力。
Linux Capabilities:是一个内核级别的权限,它允许对内核调用权限进行更细粒度的控制,而不是简单的以root身份能力授权。
Capabilities包括更改文件权限、控制网络子系统和执行系统管理等功能。在securityContext中,可以添加或删除Capabilities,做到容器精细化控制。
验证mount权限,默认无,截图为示列
【】cat tequan
apiVersion: v1
kind: Pod
metadata:
name: pod-sc1
spec:
containers:
-name: sc
image: busybox
command:
-sleep
-24h
securityContext:
privileged: true
【】kubectl exec -it pod-sc1 sh
示列1:容器默认没有挂载文件系统能力,添加SYS_ADMIN增加这个能力
容器默认无此能力,容器引擎以默认阻止
-t tmpfs 临时文件系统
apiVersion: v1
kind: Pod
metadata:
name: pod-sc2
spec:
containers:
- name: test
image: busybox
command:
- sleep
- 24h
securityContext:
capabilities:
add: ["SYS_ADMIN"]
#drop:移除特权,可写all
也有这样用的,删除所有,添加指定项,类似于白名单
案列2:以只读挂载文件系统,防止恶意二进制文件创建
普通容器没限制的话可任意增删改查
apiVersion: v1
kind: Pod
metadata:
name: Pod-sc3
spec:
containers:
- name: test
image: busybox
command:
- sleep
- 24h
securityContext:
readOnlyRootFilesystem: true
启动并进入容器
版权归原作者 弓长丿 所有, 如有侵权,请联系我们删除。