Added shell script examples

Fixed nits, broken links and numbering

Co-authored-by: Tim Bannister <tim@scalefactory.com>
Co-authored-by: Shannon Kularathna <ax3shannonkularathna@gmail.com>
Co-authored-by: Jim Angel <jimangel@users.noreply.github.com>
This commit is contained in:
Pushkar Joglekar
2021-12-07 03:42:39 +05:30
committed by Pushkar Joglekar
parent d29e93acbb
commit d1e25451d3
5 changed files with 286 additions and 184 deletions
@@ -1,5 +1,5 @@
---
title: Applying Pod Security Standards at the cluster level
title: Apply Pod Security Standards at the Cluster Level
content_type: tutorial
weight: 10
---
@@ -8,15 +8,16 @@ weight: 10
This tutorial applies only for new clusters.
{{% /alert %}}
Pod Security admission (PSA) is enabled by default in v1.23 and later, as it [graduated
to beta](/blog/2021/12/15/pod-security-admission-beta/). Pod Security Admission
is an admission controller that applies Pod Security Standards when pods are
created. This tutorial shows you how to enforce the `baseline` Pod Security
Standard at the cluster level which applies a standard configuration
Pod Security admission (PSA) is enabled by default in v1.23 and later, as it has
[graduated to beta](/blog/2021/12/09/pod-security-admission-beta/).
Pod Security
is an admission controller that carries out checks against the Kubernetes
[Pod Security Standards](docs/concepts/security/pod-security-standards/) when new pods are
created. This tutorial shows you how to enforce the `baseline` Pod Security
Standard at the cluster level which applies a standard configuration
to all namespaces in a cluster.
For applying pod security standards one namespace at a time, please [follow this
tutorial](/docs/tutorials/security/ns-level-pss).
To apply Pod Security Standards to specific namespaces, refer to [Apply Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss).
## {{% heading "prerequisites" %}}
@@ -37,12 +38,12 @@ that are most appropriate for your configuration, do the following:
1. Create a cluster with no Pod Security Standards applied:
```shell
kind create cluster --name psa-wo-cluster-pss --image kindest/node:latest
kind create cluster --name psa-wo-cluster-pss --image kindest/node:v1.23.0
```
The output is similar to this:
The output is similar to this:
```
Creating cluster "psa-wo-cluster-pss" ...
✓ Ensuring node image (kindest/node:latest) 🖼
✓ Ensuring node image (kindest/node:v1.23.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
@@ -57,12 +58,12 @@ that are most appropriate for your configuration, do the following:
```
2. Set the kubectl context to the new cluster:
1. Set the kubectl context to the new cluster:
```shell
kubectl cluster-info --context kind-psa-wo-cluster-pss
```
The output is similar to this:
The output is similar to this:
```
Kubernetes control plane is running at https://127.0.0.1:61350
@@ -72,7 +73,7 @@ that are most appropriate for your configuration, do the following:
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```
3. Get a list of namespaces in the cluster:
1. Get a list of namespaces in the cluster:
```shell
kubectl get ns
@@ -87,60 +88,60 @@ that are most appropriate for your configuration, do the following:
local-path-storage Active 9m26s
```
4. Use `--dry-run=server` to understand what happens when different Pod Security Standards
are applied:
1. Use `--dry-run=server` to understand what happens when different Pod Security Standards
are applied:
1. Privileged
```shell
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=privileged
```
The output is similar to this:
```
namespace/default labeled
namespace/kube-node-lease labeled
namespace/kube-public labeled
namespace/kube-system labeled
namespace/local-path-storage labeled
```
```shell
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=privileged
```
The output is similar to this:
```
namespace/default labeled
namespace/kube-node-lease labeled
namespace/kube-public labeled
namespace/kube-system labeled
namespace/local-path-storage labeled
```
2. Baseline
```shell
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=baseline
```
The output is similar to this:
```
namespace/default labeled
namespace/kube-node-lease labeled
namespace/kube-public labeled
Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest"
Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes
Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes
Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged
namespace/kube-system labeled
namespace/local-path-storage labeled
```
```shell
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=baseline
```
The output is similar to this:
```
namespace/default labeled
namespace/kube-node-lease labeled
namespace/kube-public labeled
Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest"
Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes
Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes
Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged
namespace/kube-system labeled
namespace/local-path-storage labeled
```
3. Restricted
```shell
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=restricted
```
The output is similar to this:
```
namespace/default labeled
namespace/kube-node-lease labeled
namespace/kube-public labeled
Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest"
Warning: coredns-7bb9c7b568-hsptc (and 1 other pod): unrestricted capabilities, runAsNonRoot != true, seccompProfile
Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true
Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
namespace/kube-system labeled
Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest"
Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
namespace/local-path-storage labeled
```
```shell
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=restricted
```
The output is similar to this:
```
namespace/default labeled
namespace/kube-node-lease labeled
namespace/kube-public labeled
Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest"
Warning: coredns-7bb9c7b568-hsptc (and 1 other pod): unrestricted capabilities, runAsNonRoot != true, seccompProfile
Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true
Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
namespace/kube-system labeled
Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest"
Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
namespace/local-path-storage labeled
```
From the previous output, you'll notice that applying the `privileged` Pod Security Standard shows no warnings
for any namespaces. However, `baseline` and `restricted` standards both have
@@ -148,10 +149,10 @@ warnings, specifically in the `kube-system` namespace.
## Set modes, versions and standards
In this tutorial, you apply the following Pod Security Standards to the `latest` version:
In this section, you apply the following Pod Security Standards to the `latest` version:
* `baseline` standard in `enforce` mode.
* `restricted` standard in `warn` and `audit` mode.
* `baseline` standard in `enforce` mode.
* `restricted` standard in `warn` and `audit` mode.
The `baseline` Pod Security Standard provides a convenient
middle ground that allows keeping the exemption list short and prevents known
@@ -166,37 +167,37 @@ following:
1. Based on the risk posture applied to a cluster, a stricter Pod Security
Standard like `restricted` might be a better choice.
1. Exempting the `kube-system` namespace allows pods to run as
`privileged` in this namespace. We recommend that you apply strict RBAC
`privileged` in this namespace. For real world use, the Kubernetes project
strongly recommends that you apply strict RBAC
policies that limit access to `kube-system`, following the principle of least
privilege.
To implement the preceding standards, do the following:
1. Create a configuration file that can be consumed by the Pod Security
Admission Controller to implement these Pod Security Standards:
```
mkdir -p /tmp/pss
cat <<EOF > /tmp/pss/cluster-level-pss.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces: [kube-system]
EOF
```
Admission Controller to implement these Pod Security Standards:
```
mkdir -p /tmp/pss
cat <<EOF > /tmp/pss/cluster-level-pss.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces: [kube-system]
EOF
```
1. Configure the API server to consume this file during cluster creation:
@@ -234,22 +235,22 @@ EOF
EOF
```
{{<note>}}
If you use Docker Desktop with KinD, the `/tmp`
directory is added as a Shared Directory under
**Preferences > Resources > File Sharing** on Mac OS.
{{</note>}}
{{<note>}}
If you use Docker Desktop with KinD on macOS, you can
add `/tmp` as a Shared Directory under the menu item
**Preferences > Resources > File Sharing**.
{{</note>}}
2. Create a cluster that uses Pod Security Admission to apply
1. Create a cluster that uses Pod Security Admission to apply
these Pod Security Standards:
```shell
kind create cluster --name psa-with-cluster-pss --image kindest/node:latest --config /tmp/pss/cluster-config.yaml
kind create cluster --name psa-with-cluster-pss --image kindest/node:v1.23.0 --config /tmp/pss/cluster-config.yaml
```
The output is similar to this:
```
Creating cluster "psa-with-cluster-pss" ...
✓ Ensuring node image (kindest/node:latest) 🖼
✓ Ensuring node image (kindest/node:v1.23.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
@@ -261,17 +262,20 @@ EOF
kubectl cluster-info --context kind-psa-with-cluster-pss
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
3. Point kubectl to the cluster
```shell
kubectl cluster-info --context kind-psa-with-cluster-pss
Kubernetes control plane is running at https://127.0.0.1:63855
CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```
4. Create a Pod with minimal configuration in the default namespace:
1. Point kubectl to the cluster
```shell
kubectl cluster-info --context kind-psa-with-cluster-pss
```
The output is similar to this:
```
Kubernetes control plane is running at https://127.0.0.1:63855
CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```
1. Create the following Pod specification for a minimal configuration in the default namespace:
```
cat <<EOF > /tmp/pss/nginx-pod.yaml
@@ -287,8 +291,8 @@ EOF
- containerPort: 80
EOF
```
5. Create Pod after pod security is enabled at cluster level:
1. Create the Pod in the cluster:
```shell
kubectl apply -f /tmp/pss/nginx-pod.yaml
```
@@ -296,24 +300,25 @@ EOF
```
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
pod/nginx created
```
```
## Clean up
Run `kind delete cluster -name psa-with-cluster-pss` and
`kind delete cluster -name psa-wo-cluster-pss` to delete the clusters you
Run `kind delete cluster -name psa-with-cluster-pss` and
`kind delete cluster -name psa-wo-cluster-pss` to delete the clusters you
created.
## {{% heading "whatsnext" %}}
- Run a
[gist](https://gist.github.com/PushkarJ/9f7a0045f4bec31097bdd1e9db0f2f6e)
- Run a
[shell script](/examples/security/kind-with-cluster-level-baseline-pod-security.sh)
to perform all the preceding steps at once:
1. Create a Pod Security Standards based cluster level Configuration
2. Create a file to let API server consumes this configuration
3. Create a cluster that creates an API server with this configuration
4. Set kubectl context to this new cluster
5. Create a minimal pod yaml file
6. Apply this file to create a Pod in the new cluster
1. Create a Pod Security Standards based cluster level Configuration
2. Create a file to let API server consumes this configuration
3. Create a cluster that creates an API server with this configuration
4. Set kubectl context to this new cluster
5. Create a minimal pod yaml file
6. Apply this file to create a Pod in the new cluster
- [Pod Security Admission](/docs/concepts/security/pod-security-admission/)
- [Pod Security Standards](/docs/concepts/security/pod-security-standards/)
- [Applying Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss/)
- [Apply Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss/)