Security Context

Pod及容器的安全上下文
◼ 一组用来决定容器是如何创建和运行的约束条件,这些条件代表创建和运行容器时使用的运行时参数
◼ 给了用户为Pod或容器定义特权和访问控制机制
Pod和容器的安全上下文设置主要包括以下几个方面
◼ 自主访问控制DAC
◼ 容器进程运行身份及资源访问权限
◼ Linux Capabilities #开放或关闭内核的某些特权给容器
◼ seccomp #和某些特定的环境相关,和实施的安全策略有关
◼ AppArmor #
◼ SELinux #
◼ Privilged Mode #特权模式,允不允许pod内的容器运行于特权模式,允许就是真管理员,拥有所有的管理权限,很危险一般不允许pod里面的容器具有特权模式
◼ Privilege Escalation #权限升级


Kubernetes支持在Pod及容器级别分别使用安全上下文
#pod级别设定的对pod里面的容器都生效
#容器里面设定就只对当前容器生效
定义pod级别的安全上下文
[root@K8s-master01 chapter4]#kubectl explain pods.spec |less
securityContext <Object>
查看securityContext支持字段的设定
[root@K8s-master01 chapter4]#kubectl explain pods.spec.securityContext
定义容器级别的安全上下文
[root@K8s-master01 chapter4]#kubectl explain pods.spec.containers.securityContext
最为常用的字段有两个
◼ Linux Capabilities   #进程特权
◼ 容器进程运行身份及资源访问权限
实例演示一:
[root@K8s-master01 chapter4]#cat securitycontext-capabilities-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
name: securitycontext-capabilities-demo
namespace: default
spec:
containers:
- name: demo
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c"]
args: ["/sbin/iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py"]
securityContext:
capabilities:
add: ['NET_ADMIN'] #添加能力
drop: ['CHOWN'] #移除能力

启动pod
[root@K8s-master01 chapter4]#kubectl apply -f securitycontext-capabilities-demo.yaml
pod/securitycontext-capabilities-demo created
查看pod
[root@K8s-master01 chapter4]#kubectl get pods
NAME READY STATUS RESTARTS AGE
securitycontext-capabilities-demo 1/1 Running 0 14s

进入交互式进行查看(可查看规则已经加入进来了)
[root@K8s-master01 chapter4]#kubectl exec -it securitycontext-capabilities-demo -- /bin/sh
[root@securitycontext-capabilities-demo /]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 redir ports 80

随便创建文件,更改文件权限
[root@securitycontext-capabilities-demo /]# cp /etc/issue ./
[root@securitycontext-capabilities-demo /]# ls
bin etc issue media opt root sbin sys usr
dev home lib mnt proc run srv tmp var
[root@securitycontext-capabilities-demo /]# ls -l issue
-rw-r--r-- 1 root root 54 Nov 10 14:20 issue

更改该文件的所有者(没有更改权限)
[root@securitycontext-capabilities-demo /]# chown nobody issue
chown: issue: Operation not permitted

如果去掉drop: ['CHOWN'] 这个能力,则将获得权限
先删除原来的pod
[root@K8s-master01 chapter4]#kubectl delete -f securitycontext-capabilities-demo.yaml
pod "securitycontext-capabilities-demo" deleted
修改yaml文件,把drop: ['CHOWN']注释掉
# drop: ['CHOWN']
再次创建这个pod
[root@K8s-master01 chapter4]#kubectl apply -f securitycontext-capabilities-demo.yaml
pod/securitycontext-capabilities-demo created
进入交互式进行修改(可以更改成功)
[root@K8s-master01 chapter4]#kubectl exec -it securitycontext-capabilities-demo -- /bin/sh
[root@securitycontext-capabilities-demo /]# cp /etc/issue ./
[root@securitycontext-capabilities-demo /]# chown nobody issue
[root@securitycontext-capabilities-demo /]# ls -l issue
-rw-r--r-- 1 nobody root 54 Nov 10 14:40 issue
实例演示二:定义系统以哪个用户的身份来运行
[root@K8s-master01 chapter4]#cat securitycontext-runasuser-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
name: securitycontext-runasuser-demo
namespace: default
spec:
containers:
- name: demo
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
env:
- name: PORT
value: "8080"
securityContext:
runAsUser: 1001
runAsGroup: 1001

创建此pod
[root@K8s-master01 chapter4]#kubectl apply -f securitycontext-runasuser-demo.yaml
pod/securitycontext-runasuser-demo created
查看你此pod
[root@K8s-master01 chapter4]#kubectl get pods
NAME READY STATUS RESTARTS AGE
securitycontext-runasuser-demo 1/1 Running 0 10s
交互式查看运行此容器的用户
[root@K8s-master01 chapter4]#kubectl exec -it securitycontext-runasuser-demo -- ps aux
PID USER TIME COMMAND
1 1001 0:00 python3 /usr/local/bin/demo.py
8 1001 0:00 ps aux
运行者身份不在是默认的管理员帐号,变为了1001,此用户再/etc/passwd不一定存在

同时其8080端口也正常监听起来了
[root@K8s-master01 chapter4]#kubectl exec -it securitycontext-runasuser-demo -- netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
给容器添加 NET_BIND_SERVICE能力,使普通用户也能绑定1024以内的特权端口
浏览器搜索 https://article.itxueyuan.com/rxpJw0 可查看Linux capabilities相关的权限修改策略
[root@K8s-master01 chapter4]#cat securitycontext-runasuser-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: securitycontext-runasuser-demo
namespace: default
spec:
containers:
- name: demo
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
env: #端口的变量可不加,默认为80
- name: PORT
value: "80"
securityContext:
runAsUser: 1001
runAsGroup: 1001
capabilities:
add: ['NET_BIND_SERVICE']
创建pod
[root@K8s-master01 chapter4]#kubectl apply -f securitycontext-runasuser-demo.yaml
pod/securitycontext-runasuser-demo created
查看普通用户是否能监听特权端口
[root@K8s-master01 chapter4]#kubectl exec -it securitycontext-runasuser-demo -- netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
[root@K8s-master01 chapter4]#kubectl exec -it securitycontext-runasuser-demo -- ps aux
PID USER TIME COMMAND
1 1001 0:00 python3 /usr/local/bin/demo.py
22 1001 0:00 ps aux
如何修改pod上的资源需求(requests)和限制(limits)
资源需求和资源限制
◼ 资源需求(requests)
◆定义需要系统预留给该容器使用的资源最小可用值
◆容器运行时可能用不到这些额度的资源,但用到时必须确保有相应数量的资源可用
◆资源需求的定义会影响调度器的决策
◼ 资源限制(limits)
◆定义该容器可以申请使用的资源最大可用值,超出该额度的资源使用请求将被拒绝
◆该限制需要大于等于requests的值,但系统在其某项资源紧张时,会从容器那里回收其使用的超出其requests值的那部分
requests和limits定义在容器级别,使用Resouece主要围绕cpu、memory和hugepages三种资源
requests和limits
requests:资源需求,影响调度器的调度决策,最少满足条件
limits:资源限制,绝不允许超出使用的资源范围

cpu 1 core = 1000m core

范例:对CPU和内存各自启动一个进程同时做压力测试

[root@K8s-master01 chapter4]#cat pod-resources-demo.yaml 
# Maintainer: MageEdu <mage@magedu.com>
# URL: http://www.magedu.com
# ---
apiVersion: v1
kind: Pod
metadata:
name: stress-pod
spec:
containers:
- name: stress
image: ikubernetes/stress-ng
command: ["/usr/bin/stress-ng", "-c 1", "-m 1", "--metrics-brief"]
resources:
requests:
memory: "128Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "400m"