# 第五题 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来验证.