Getting Started with Kubernetes: A Brief Introduction to Kubernetes Pod Security Policies
Tags: kubernetes, beginners, security, containers
Published: 2020-12-05 04:23:29

*As a new user of Kubernetes, I want to understand how to create a pod security policy, so I can secure a Kubernetes cluster.*
________________________________________________________

Kubernetes is a powerful container management and orchestration platform that automates many of the manual processes involved in deploying, managing, and scaling containerized applications. When using Kubernetes (or really any container-centric management platform), security must take a central role in the deployment of your applications and services. 

Container security is the process of implementing security tools and policies that help you protect the infrastructure of your container and add the needed assurance that everything in your container is running as you intend. 

Because containers encapsulate all their dependencies and automation has shifted security across the software development lifecycle, securing containers has become a prominent issue in container management. Manually creating and maintaining security rules for each entity is impractical, so integrating security into CI/CD workflows and implementing DevSecOps best practices provides incredible security advantages in the world of containers.

*Kubernetes pod security policies* provide an efficient way to enforce security settings across a cluster. You can use [Pod Security Policies](https://medium.com/better-programming/secure-your-kubernetes-cluster-with-pod-security-policies-bd511ec6d034) to keep Kubernetes and the containers running in it, secured.

Read on to find out more about Kubernetes pod security policies and the following:

* [What is a Pod?](#what-is-a-pod-?)
* [Creating a Kubernetes Pod Security Policy](#creating-a kubernetes-pod-security-policy)
* [Understanding the structure of a Kubernetes Pod Security Policy](#understanding-the-structure-of-a-kubernetes-pod-security-policy)
* [Example: Create a Kubernetes Pod Security Policy that Prevents the Creation of Privileged Pods](#example-:-create-a-kubernetes-pod-security-policy-that-prevents-the-creation-of-privileged-pods)
* [Verification](#verification)
* [Delete the policy](#delete-the-policy)
* [The Takeaway](#the-takeaway)


# What is a Pod?

A [pod](https://kubernetes.io/docs/concepts/workloads/pods/) is the basic (and smallest) building block of Kubernetes [Objects](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/). Within a cluster, a pod represents a process that is running. The inside of a pod can have one container or can have a co-located group of containers with shared resources, and specifications. Containers within a single pod share the following:

* A unique network IP
* Network credentials
* Storage resources
* Specifications applied to the pod that govern how the container should run

You can scale your application by adding or removing pods. 

Now that we have introduced the concept of pods in Kubernetes, let's review how to craft a security policy.




![Kubernetes logo and lock](https://anchore.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-01-at-4.32.42-PM.png)


# Creating a Kubernetes Pod Security Policy

*Pod security policies* (PSP) are specified in [YAML]( https://rollout.io/blog/yaml-tutorial-everything-you-need-get-started/) files. Note that YAML files are based on indentation with spaces, not with tabs.

> **NOTE:** You can use `.yml` or `.yaml` extension for YAML files. Although the `.yaml` extension is recommended, many code bases and documentation use `.yml`.

The following is an example of a pod security policy YAML file:

```
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: example
spec:
  privileged: false
  runAsUser:
    rule: MustRunAsNonRoot
  seLinux:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
  - 'nfs'
```

The above `PodSecurityPolicy` implements the following security rules:

* Disallows containers running in privileged mode.
* Disallows containers that require root privileges
* Disallows containers that access volumes apart from `NFS` volumes

Let’s take a closer look at the fields in a pod security policy. 

------------------------------------------------------------

## Understanding the structure of a Kubernetes Pod Security Policy

* The `metadata` section of the policy specifies the name and basic information.
* The `spec` section of the policy outlines the key criteria a pod must fulfill in order to be allowed to run.


## Required Fields

In the YAML file for the Kubernetes object you want to create, you'll need to set values for the following fields:

* `apiVersion` - version of the Kubernetes API you're using to create this object
* `kind` - kind of object you want to create
* `metadata` - data that helps uniquely identify the object
* `spec` - the state you desire for the object
 

#### Definitions of fields that you should understand to get started
* `privileged` - indicates whether to allow containers 
that use *privileged mode*.
* `runAsUser` - defines which users a container can run as. Most commonly, it is used to prevent pods from running as the root user.
* `seLinux`- defines the Security-Enhanced Linux (SELinux) security context for containers and only allows containers that match that context. 
* `supplementalGroups`- defines which group IDs containers add.
* `fsGroup` - defines the user groups or fsGroup-owned volumes that a container may access. 
* `volumes` - defines the type(s) of volumes a container may access. 
* `hostPorts` - together with related fields like `hostNetwork`, `hostPID`, and `hostIPC`, restrict the ports (and other networking capabilities) that a container may access on the host system.


To learn more about configuring these fields, please read the [Kubernetes documentation](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#policy-reference).

-------------------------------------------------------------

### Assumptions for Creating a Pod Security Policy

When a Kubernetes cluster is started with pod security policy support, Kubernetes follows a *default-deny* approach. This means that, by default, pods are not allowed to run unless they match the criteria outlined in a pod security policy. This also means that if your cluster does not have at least one pod security policy in place, not a single pod will run and Kubernetes will let you know that you should activate a pod security policy. You should see an error message that reads the following:

```
no providers available to validate pod request.
```

The Kubernetes API is intent-based. Each API call allows you to specify the desired-state for one of Kubernetes’ many objects. To send this desired state to Kubernetes, use [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/), the CLI for running commands against Kubernetes clusters. Use kubectl to apply the YAML file to your Kubernetes' cluster.
You can use the following command to activate the newly created YAML file. 

```
kubectl create -f <policy-name>.yaml
```

> **NOTE:** `<policy-name>.yaml` denotes the policy file you created and plan to implement.

--------------------------------------------------------

####Prerequisites

> * You have a Kubernetes cluster running. 
> * You have kubectl command-line tool installed. 
> * You have enabled support for pod security policies. You can only use pod security policies if they are enabled in your Kubernetes cluster's admission controller.
> * You should have some knowledge of Kubernetes and how things work in your cluster. Use the [Getting Started](https://kubernetes.io/docs/setup/) documentation as a resource. 


To better explain how pod security policies work in practice, the following example walks you through creating a security policy.

------------------------------------------------------------


### Example: Create a Kubernetes Pod Security Policy that Prevents the Creation of Privileged Pods 

In a Kubernetes pod, containers can optionally run in *privileged* mode, which means that the processes inside the container have almost unrestricted access to resources on the host system. Although there are some use cases where this level of access is necessary, in general, it’s a security risk to let your containers do this.

You can create a Kubernetes pod security policy that prevents the creation of privileged pods and controls access to volumes. To do this, create the YAML file that defines the specifications of your policy. 

You can prevent privileged containers from running by including the following in your Kubernetes pod security policy:

```
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name:no-privileged-containers
spec:
  privileged: false
  runAsUser:
    rule: MustRunAsNonRoot
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny  
  volumes:
  - '*'
```

In the file, you are preventing privileged pods with the line:

```
privileged: false
```

The following is also allowed in this pod security policy:

* Allows any user to control `SELinux` within pods
* Allows users to run container entry points only as a non-root user
* Volumes support ownership management

Next, activate the policy by executing the following command, which creates the new policy from the file:

```
kubectl create -f no-privileged-containers.yaml
```

Check that the policy has been installed with the following command, which lists all active policies in the cluster:

```
kubectl get psp
```
You should see the policy listed, along with its specifications. 


### Verification

After you activate the policy, you should test it. Try running a container that contradicts the rules established in the policy. This provides a way to check that your specifications are in place and working. 

In the `no-privileged-containers.yaml`, since the pod security policy explicitly disallows pods or containers with root privileges, a request to do the opposite should be rejected. You should see an error output similar to the following example when you check the pod's status.

> If you enter the command: 
  `kubectl get pods` 
 
> The output, if unsuccessful, should be similar to:

 ```
 container has runAsNonRoot and image will run as root
 ```


### Delete the Policy 

You can delete the `no-privileged-containers` pod security policy with the following command:

```
kubectl delete psp no-privileged-containers
```

# The Takeaway

In this article, we've looked at creating a pod security policy and addressed the various fields included in the YAML file of the policy. You should now be able to create, check the status, verify and delete a Kubernetes pod security policy. 

**Remember:**

* Pod security policy is a cluster-level resource that controls security sensitive aspects of the pod specification.
* YAML files are pretty specific, but also quite easy to create.
* If ever in doubt, check out the official [Kubernetes](https://kubernetes.io/docs/home/) documentation for helpful tips and examples.

So now...go forth and start securing your cluster.