# 第五题 PodSecurityPolicy
###### tags: `真题讲解`
切换集群kubectl config use-context k8s63
**Context**
A PodsecurityPolicy shall prevent the creati on of privileged Pods in a specific namespace.
**Task**
Create a new PodSecurityPolicy named **prevent-psp-policy** , which prevents the creation of privileged Pods.
Create a new ClusterRole named **restrict-access-role**, which uses the newly created PodSecurityPolicy prevent-psp-policy.
Create a new serviceAccount named **psp-denial-sa** in the existing namespace development.
Finally, create a new clusterRoleBinding named **dany-access-bind**, which binds the newly created ClusterRole **restrict-access-role** to the newly created serviceAccount **psp-denial-sa**.
## 解法
[官方参考链接: k8s.io/psp](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#create-a-policy-and-a-pod)
创建一个PSP YAML, 粘入官方文档的示例, 仅仅修改PSP的Name即可, 保存并Apply.
```
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: prevent-psp-policy
spec:
privileged: false # Don't allow privileged pods!
# The rest fills in some required fields.
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'
```
查看已Apply的所有PSP
```
kubectl get psp
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
calico-kube-controllers false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
calico-node true RunAsAny RunAsAny MustRunAs MustRunAs false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim,hostPath
calico-typha false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
gatekeeper-admin false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false configMap,projected,secret,downwardAPI
prevent-psp-policy false RunAsAny RunAsAny RunAsAny RunAsAny false *
tigera-operator false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false hostPath,configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
```
创建Cluster Role: **restrict-access-role**使用该PSP: **prevent-psp-policy**
```
kubectl create clusterrole restrict-access-role --verb use --resource psp --resource-name prevent-psp-policy --dry-run=client -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: restrict-access-role
rules:
- apiGroups:
- policy
resourceNames:
- prevent-psp-policy
resources:
- podsecuritypolicies
verbs:
- use
kubectl create clusterrole restrict-access-role --verb use --resource psp --resource-name prevent-psp-policy
```
在namespace development中创建SA: **psp-denial-sa**, 创建clusterRoleBinding: **dany-access-bind** 绑定至指定的SA.
```
kubectl create -n development sa psp-denial-sa
kubectl create clusterrolebinding dany-access-bind --clusterrole restrict-access-role --serviceaccount development:psp-denial-sa
```
校验SA有权使用该PSP
```
kubectl auth can-i --as system:serviceaccount:development:psp-denial-sa use psp/prevent-psp-policy
Warning: resource 'podsecuritypolicies' is not namespace scoped in group 'policy'
yes
```
**集群开启PSP准入**
编辑Master kube-apiserver YAML, 在准入插件中开启PodSecurityPolicy.
```
--enable-admission-plugins=NodeRestriction,PodSecurityPolicy
```
确保Kube-apiserver正常启动回来.
测试Pod YAML:
```
apiVersion: v1
kind: Pod
metadata:
name: psp-pod
labels:
app: net-tools
spec:
serviceAccount: psp-denial-sa
nodeName: ubuk8s-vm02
containers:
- name: apparmor-c1
image: net-tools:v2
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
privileged: true
```
确保以SA psp-denial-sa身份启动Pod, 即官网中的例子:
```
kubectl --as=system:serviceaccount:development:psp-denial-sa -n development apply -f Pod.PSP.yaml
Error from server (Forbidden): error when creating "Pod.PSP.yaml": pods "psp-pod" is forbidden: PodSecurityPolicy: unable to admit pod: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
```
切勿直接Apply YAML, 否则Pod可以以Kubelet身份启动成功, 当然你可以直接创建Deployment来验证.