Pod security policies provide a framework to ensure that pods and containers run only with the appropriate privileges and access only a finite set of resources. Security policies also provide a way for cluster administrators to control resource creation, by limiting the capabilities available to specific roles, groups or namespaces.
If you haven't already or have been checking email and Slacking for the past 5 labs, please ensure you are cluster-admin
.
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin \
--user $(gcloud config get-value account)
We will create a new Namespace for every lab and switch contexts to ensure it is the default when using kubectl
.
kubectl create ns lab006 && \
kubectl config set-context $(kubectl config current-context) --namespace lab006 && \
echo "Default Namespace Switched:" $(kubectl get sa default -o jsonpath='{.metadata.namespace}')
- In the
manifests/psp
directory, take a look at thepod-security-policy.yaml
file and launch it into our new cluster:
kubectl create -f pod-security-policy.yaml
- Inspect our new PodSecurityPolicy:
kubectl get psp
kubectl describe psp restrict-root
When a PodSecurityPolicy resource is created, it does nothing. In order to use it, the requesting user or target pod’s service account must be authorized to use the policy, by allowing the use verb on the policy.
RBAC is used to create a Role or ClusterRole that grants the desired service accounts access to PodSecurityPolicies. A ClusterRole grants cluster-wide permissions, and a Role grants permissions within a namespace that you define.
For simplicity, we will create a ClusterRole and ClusterRolebinding that applies to all authenticated users in the lab006
namespace.
# in the manifests/role directory run
kubectl create -f .
We need to enable PSP in our GKE cluster. Warning! If you enable the PodSecurityPolicy controller without first defining and authorizing any actual policies, no users, controllers, or service accounts can create or update Pods. If you are working with an existing cluster, you should define and authorize policies before enabling the controller.
In Cloud Shell, run the following command:
# Enable PSP
gcloud beta container clusters update $(gcloud container clusters list --format json | jq -r '.[].name') --enable-pod-security-policy --region=us-west1-a
# Grab a coffee..this will take a few minutes
- Inspect the modified Unshorten API deployment located in the
manifests/root-pod
directory and notice the newrunAsUser
field. This field specifies that for any Containers in the Pod, the first process runs with user ID 0 (root). - Launch the Deployment and service:
# In the manifests/root-pod directory
kubectl create -f .
You will notice that the Pod fails to instantiate:
kubectl get pods
# Inspect the event that occurred to cause the failure
kubectl get events
# Events are in non-sequential order by default - use this to order by timestamp
kubectl get events --sort-by='.metadata.creationTimestamp' -o 'go-template={{range .items}}{{.involvedObject.name}}{{"\t"}}{{.involvedObject.kind}}{{"\t"}}{{.message}}{{"\t"}}{{.reason}}{{"\t"}}{{.type}}{{"\t"}}{{.firstTimestamp}}{{"\n"}}{{end}}'
- Delete the Deployment and Service
# In the manifests/root-pod directory
kubectl delete -f .
Great job! We just stopped a container running as r00t.
- Inspect the modified Unshorten API deployment located in the
manifests/non-root-pod
directory and notice the newrunAsUser
field. This field specifies that for any Containers in the Pod, the first process runs with user ID 999 (non-root). - Launch the Deployment and service:
# In the manifests/non-root-pod directory
kubectl create -f .
You will notice that the Pod launches successfully:
kubectl get pods
If you take a close look at the Deployment manifest in the manifests/non-root-pod
directory you will see that it is requesting to mount a...questionable...directory.
Your task now is to modify the PodSecurityPolicy to whitelist known-valid and safe volume mounts. More info can be found here on writing granular PodSecurityPolicies.
Audit your PodSecurityPolicy using kube-psp-advisor
Kubernetes Pod Security Policy Advisor is an opensource tool from Sysdig that can automatically generate the Pod Security Policy for all the resources in the entire cluster.
More info from Sysdig can be found here.
Note: This is a very new project and at the time of this writing is having problems running in Cloud Shell. You may have to run it on your local machine (proceed with caution).
- In the
manifests
directory:
# psp isn't tied to a namespace so we need to delete manually
kubectl delete psp restrict-root && \
kubectl delete ns lab006 && \
kubectl config set-context $(kubectl config current-context) --namespace default && \
echo "Default Namespace Switched:" $(kubectl get sa default -o jsonpath='{.metadata.namespace}')
- (!!) IMPORTANT (!!) Disable PSP on your cluster
# Disable PSP
gcloud beta container clusters update $(gcloud container clusters list --format json | jq -r '.[].name') --no-enable-pod-security-policy --region=us-west1-a