What is PodSecurityPolicy
PodSecurityPolicy is a global resource used to control Pod security-related configuration.
On a kubernetes cluster with RBAC enabled, if users are allowed to use kubectl, then PodSecurityPolicy must be enabled, otherwise users may use some privileged resources (e.g. privileged, hostNetwork, hostPath, etc.) and affect the stability of the node machine.
With PSP turned on, users can only use resources allowed by the administrator. PSP supports the following (see official website for details).
Control Aspect | Field Names |
---|---|
Running of privileged containers | privileged |
Usage of host namespaces | hostPID , hostIPC |
Usage of host networking and ports | hostNetwork , hostPorts |
Usage of volume types | volumes |
Usage of the host filesystem | allowedHostPaths |
White list of Flexvolume drivers | allowedFlexVolumes |
Allocating an FSGroup that owns the pod’s volumes | fsGroup |
Requiring the use of a read only root file system | readOnlyRootFilesystem |
The user and group IDs of the container | runAsUser , runAsGroup , supplementalGroups |
Restricting escalation to root privileges | allowPrivilegeEscalation , defaultAllowPrivilegeEscalation |
Linux capabilities | defaultAddCapabilities , requiredDropCapabilities , allowedCapabilities |
The SELinux context of the container | seLinux |
The Allowed Proc Mount types for the container | allowedProcMountTypes |
The AppArmor profile used by containers | annotations |
The seccomp profile used by containers | annotations |
The sysctl profile used by containers | annotations |
Enabling PodSecurityPolicy
Enabling is simple, just configure apiserver to add the admission plugin PodSecurityPolicy.
|
|
The apiserver will restart after the modification. Since there is no Policy configured here, PSP will prevent all Pod creation after reboot.
Since the PSP API policy/v1beta1/podsecuritypolicy
is independent from the authorization controller, for existing clusters, it is recommended to configure psp and authorization first, and then turn on PS.
Authorization Policy
Policy itself does not produce the actual effect, you need to bind it to the user or serviceaccount to complete the authorization.
Binding method: Create a Role, which can use the PodSecurityPolicy, and then bind the role to the user or serviceaccount.
Example
Here is an example.
1. Create Policy
|
|
2. Create serviceaccount
3. Create Pod
At this point, if you use kubectl-user to create a Pod, you will get the following prompt.
|
|
Because sa fake user does not have the permission of psp example, you can check it by auth.
|
|
So the next step is to create the role, rolebinding.
4. Create a role with psp example use permission and bind to sa hellobaby
|
|
Now go create the above Pod nginx again, and it will be created, and it will be created successfully, because this Pod does not request any special privileges and is a good boy.
What about adding the privileged fields and creating it again?
kubectl-user will return the following.
|
|
The tip is clear: Privileged containers are not allowed
.
PodSecurityPolicy is in effect.
5. Pods not created directly by sa
Most of the time we don’t create Pods directly, but rather we create Deployment.
|
|
The message says that there are no providers to check for Pod requests, but we have already given sa hellobaby:fake-user authorization.
The reason is that this Pod is created by the replicaset controller, and the default kubectl run of the application specifies spec.template.spec.serviceAccount
and spec.template.spec. serviceAccountName
are both default, while the SA of our RBAC binding above is hellobaby:fake-user
, not hellobaby:default
.
How to solve it? The official website gives the method to bind the role psp:unprivileged
to hellobaby:default
again. It is true that this can solve the problem, but this solution does not make sense.
We know that a namespace can create more than one serviceaccount, if I need to grant different psp to different sa under the same namespace, then how should I give sa default authorization? Obviously it is impossible to bind.
In fact, I think this example from the official site doesn’t make sense and the kubectl run
command is going to be eliminated.
A better approach would be to create a deployment and set its spec.template.spec.serviceAccount
and spec.template.spec.serviceAccountName
to the actual sa.
Here is an actual example.
|
|
At this point the replicaset controller will use sa hellobaby:fake-user to create a pod, and since the sa has been bound to the psp example, the Pod can be successfully created.
Ref: