pod安全策略PSP-3
runAsUser
刚刚创建了pod1,那么我们先进入到pod1里去之后执行whoami命令。
root@vms61:~/demo5# kubectl exec -it pod1 -- bash
root@vms63:/# whoami
root
root@vms63:/# exit
exit
root@vms61:~/demo5#
可以看到容器里的进程是以root身份运行的,然后删除pod1。
root@vms61:~/demo5# kuser delete pod pod1
pod "pod1" deleted
root@vms61:~/demo5#
root@vms61:~/demo5# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
securityContext:
runAsUser: 1000
hostNetwork: false
...输出...
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl apply -f pod1.yaml
pod/pod1 created
root@vms61:~/demo5# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 4s
root@vms61:~/demo5# kubectl exec -it pod1 -- bash
I have no name!@pod1:/$ whoami
whoami: cannot find name for user ID 1000
I have no name!@pod1:/$ exit
exit
command terminated with exit code 1
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl delete pod pod1
pod "pod1" deleted
root@vms61:~/demo5#
root@vms61:~/demo5# cat mypsp1.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: mypsp1
spec:
privileged: false #不允许创建特权pod
hostNetwork: true #允许pod使用hostNetwork
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
#rule: RunAsAny
rule: 'MustRunAs'
ranges:
- min: 1500
max: 2000
...输出...
root@vms61:~/demo5#
再次创建pod1。
root@vms61:~/demo5# kubectl apply -f pod1.yaml
Error from server (Forbidden): error when creating "pod1.yaml": pods "pod1" is forbidden: PodSecurityPolicy: unable to admit pod: [spec.containers[0].securityContext.runAsUser: Invalid value: 1000: must be in the ranges: [{1500 2000}]]
root@vms61:~/demo5#
这里创建失败了,因为在mypsp1里指定运行pod时,pod里进程必须是以1500~2000的UID来运行,但是pod1里的UID指定的是1000,所以运行失败。
修改pod1.yaml的内容,让容器里的进程以uid=1800来运行如下并创建pod1,查看pod1正常之后删除pod1。
root@vms61:~/demo5# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
securityContext:
runAsUser: 1800
hostNetwork: false
...输出...
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl apply -f pod1.yaml
pod/pod1 created
root@vms61:~/demo5# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 2s
root@vms61:~/demo5# kubectl delete pod pod1
pod "pod1" deleted
root@vms61:~/demo5#
可以看到pod1是可以正常运行的,然后把pod1删除。
修改mypsp1.yaml,仍然把 runAsUser:设置为rule: RunAsAny,并设置可以使用所有类型的卷并让其生效。
root@vms61:~/demo5# cat mypsp1.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: mypsp1
spec:
privileged: false #不允许创建特权pod
hostNetwork: true #允许pod使用hostNetwork
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
...输出...
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl apply -f mypsp1.yaml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/mypsp1 configured
root@vms61:~/demo5#
deployment
root@vms61:~/demo5# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web1
name: web1
spec:
replicas: 2
selector:
matchLabels:
app: web1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web1
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
resources: {}
status: {}
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
web1 0/2 0 0 12s
root@vms61:~/demo5# kubectl get pods
No resources found in default namespace.
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl get ev
LAST SEEN TYPE REASON OBJECT MESSAGE
2s Warning FailedCreate replicaset/web1-665f6b46cb Error creating: pods "web1-665f6b46cb-" is forbidden: PodSecurityPolicy: unable to admit pod: []
4s Normal ScalingReplicaSet deployment/web1 Scaled up replica set web1-665f6b46cb to 2
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl delete -f web1.yaml
deployment.apps "web1" deleted
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl get sa -n kube-system | grep replicaset
replicaset-controller 1 58d
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl create clusterrolebinding cbind3 --clusterrole=crole2 --serviceaccount=kube-system:replicaset-controller
clusterrolebinding.rbac.authorization.k8s.io/cbind3 created
root@vms61:~/demo5#
再次创建deploy。
root@vms61:~/demo5# kubectl apply -f web1.yaml
deployment.apps/web1 created
root@vms61:~/demo5# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
web1 2/2 2 2 3s
root@vms61:~/demo5# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1-665f6b46cb-792c2 1/1 Running 0 5s
web1-665f6b46cb-wppv5 1/1 Running 0 5s
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl delete -f web1.yaml
deployment.apps "web1" deleted
root@vms61:~/demo5#
两个PSP规则冲突谁生效
如果两个PSP规则且配置冲突的话,那么允许的优先级要高于拒绝的优先级。比如再创建一个PSP规则mypsp2允许创建特权pod,对应的yaml文件如下。
root@vms61:~/demo5# cat mypsp2.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: mypsp2
spec:
privileged: true
...输出...
root@vms61:~/demo5#
然后创建此PSP规则。
root@vms61:~/demo5# kubectl apply -f mypsp2.yaml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/mypsp2 created
root@vms61:~/demo5# kubectl get psp
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP
mypsp1 false RunAsAny RunAsAny RunAsAny RunAsAny ...
mypsp2 true RunAsAny RunAsAny RunAsAny RunAsAny ...
root@vms61:~/demo5#
凡是能访问到mypsp1和mypsp2的用户是都能创建出来特权pod的,比如管理员可以访问到所有的psp规则,所以管理员能够创建出来特权pod。修改pod1.yaml内容如下。
root@vms61:~/demo5# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 1000000"]
name: pod1
resources: {}
securityContext:
privileged: true
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl apply -f pod1.yaml
pod/pod1 created
root@vms61:~/demo5# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 3s
root@vms61:~/demo5#
删除pod1。
root@vms61:~/demo5# kubectl delete pod pod1
pod "pod1" deleted
root@vms61:~/demo5#
下面使用lduan用户创建pod1。
root@vms61:~/demo5# kuser apply -f pod1.yaml
Error from server (Forbidden): error when creating "pod1.yaml": pods "pod1" is forbidden: PodSecurityPolicy: unable to admit pod: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
root@vms61:~/demo5#
发现是创建不了特权pod的,因为lduan用户只能访问mypsp1而访问不了mypsp2。
如果打算让lduan用户只能在命名空间ns1里创建特权pod,在其他命名空间里不能创建特权pod的话,那么我们可以通过在ns1命名空间里创建一个集群角色crole3可以使用mypsp2的权限,然后在ns1里创建一个rolebinding(不是clusterrolebinding)把crole3授权给lduan,用户如下图。
crole2是通过clusterrolebinding授权给lduan用户的,那么lduan用户在任何命名空间都能访问到mypsp1,所以不能创建特权pod。crole3通过在ns1命名空间里通过rolebinding授权lduan用户,所以lduan用户只在ns1命名空间能访问mypsp2,在ns1里lduan既能访问mypsp1又能访问mypsp2,允许优先级高于拒绝优先级,所以lduan用户在ns1命名空间里能创建特权pod。
创建crole3让其具备使用mypsp2的权限。
root@vms61:~/demo5# kubectl create clusterrole crole3 --verb=use --resource=psp --resource-name=mypsp2
clusterrole.rbac.authorization.k8s.io/crole3 created
root@vms61:~/demo5#
在ns1命名空间里创建名字为rbind1的rolebinding,让lduan用户可以使用crole3的权限。
root@vms61:~/demo5# kubectl create rolebinding rbind1 --clusterrole=crole3 --user=lduan -n ns1
rolebinding.rbac.authorization.k8s.io/rbind1 created
root@vms61:~/demo5#
然后测试
root@vms61:~/demo5# kuser apply -f pod1.yaml
Error from server (Forbidden): error when creating "pod1.yaml": pods "pod1" is forbidden: PodSecurityPolicy: unable to admit pod: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
root@vms61:~/demo5#
发现在当前命名空间(default)空间里创建不出来特权pod,然后在ns1里创建pod1。
root@vms61:~/demo5# kuser apply -f pod1.yaml -n ns1
pod/pod1 created
root@vms61:~/demo5# kuser get pods -n ns1
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 4s
root@vms61:~/demo5#
这里是可以正常创建出来的,然后删除pod1。
root@vms61:~/demo5# kuser delete pod pod1 -n ns1
pod "pod1" deleted
root@vms61:~/demo5#
还原环境
现在一共用到的角色如下。
删除cbind2,cbind3,rbind1 和crole2,crole3
root@vms61:~/demo5# kubectl delete clusterrolebinding cbind{2,3}
clusterrolebinding.rbac.authorization.k8s.io "cbind2" deleted
clusterrolebinding.rbac.authorization.k8s.io "cbind3" deleted
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl delete clusterrole crole{2,3}
clusterrole.rbac.authorization.k8s.io "crole2" deleted
clusterrole.rbac.authorization.k8s.io "crole3" deleted
root@vms61:~/demo5#
root@vms61:~/demo5# kubectl delete rolebinding rbind1 -n ns1
rolebinding.rbac.authorization.k8s.io "rbind1" deleted
root@vms61:~/demo5#
删除mypsp1和mypsp2
root@vms61:~/demo5# kubectl delete psp mypsp{1,2}
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy "mypsp1" deleted
podsecuritypolicy.policy "mypsp2" deleted
root@vms61:~/demo5#
关闭PSP
编辑/etc/kubernetes/manifests/kube-apiserver.yaml,把
- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy修改为
- --enable-admission-plugins=NodeRestriction
保存退出之后,重启kubelet。