Skip to content

Commit 7f51c15

Browse files
committed
copy tutorials/security/cluster-level-pss
1 parent 97dd452 commit 7f51c15

File tree

1 file changed

+333
-0
lines changed

1 file changed

+333
-0
lines changed
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
---
2+
title: Apply Pod Security Standards at the Cluster Level
3+
content_type: tutorial
4+
weight: 10
5+
---
6+
7+
{{% alert title="Note" %}}
8+
This tutorial applies only for new clusters.
9+
{{% /alert %}}
10+
11+
Pod Security admission (PSA) is enabled by default in v1.23 and later, as it has
12+
[graduated to beta](/blog/2021/12/09/pod-security-admission-beta/).
13+
Pod Security
14+
is an admission controller that carries out checks against the Kubernetes
15+
[Pod Security Standards](/docs/concepts/security/pod-security-standards/) when new pods are
16+
created. This tutorial shows you how to enforce the `baseline` Pod Security
17+
Standard at the cluster level which applies a standard configuration
18+
to all namespaces in a cluster.
19+
20+
To apply Pod Security Standards to specific namespaces, refer to
21+
[Apply Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss).
22+
23+
If you are running a version of Kubernetes other than v{{< skew currentVersion >}},
24+
check the documentation for that version.
25+
26+
## {{% heading "prerequisites" %}}
27+
28+
Install the following on your workstation:
29+
30+
- [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)
31+
- [kubectl](/docs/tasks/tools/)
32+
33+
This tutorial demonstrates what you can configure for a Kubernetes cluster that you fully
34+
control. If you are learning how to configure Pod Security Admission for a managed cluster
35+
where you are not able to configure the control plane, read
36+
[Apply Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss).
37+
38+
## Choose the right Pod Security Standard to apply
39+
40+
[Pod Security Admission](/docs/concepts/security/pod-security-admission/)
41+
lets you apply built-in [Pod Security Standards](/docs/concepts/security/pod-security-standards/)
42+
with the following modes: `enforce`, `audit`, and `warn`.
43+
44+
To gather information that helps you to choose the Pod Security Standards
45+
that are most appropriate for your configuration, do the following:
46+
47+
1. Create a cluster with no Pod Security Standards applied:
48+
49+
```shell
50+
kind create cluster --name psa-wo-cluster-pss
51+
```
52+
The output is similar to:
53+
```
54+
Creating cluster "psa-wo-cluster-pss" ...
55+
✓ Ensuring node image (kindest/node:v{{< skew currentVersion >}}.0) 🖼
56+
✓ Preparing nodes 📦
57+
✓ Writing configuration 📜
58+
✓ Starting control-plane 🕹️
59+
✓ Installing CNI 🔌
60+
✓ Installing StorageClass 💾
61+
Set kubectl context to "kind-psa-wo-cluster-pss"
62+
You can now use your cluster with:
63+
64+
kubectl cluster-info --context kind-psa-wo-cluster-pss
65+
66+
Thanks for using kind! 😊
67+
```
68+
69+
1. Set the kubectl context to the new cluster:
70+
71+
```shell
72+
kubectl cluster-info --context kind-psa-wo-cluster-pss
73+
```
74+
The output is similar to this:
75+
76+
```
77+
Kubernetes control plane is running at https://127.0.0.1:61350
78+
79+
CoreDNS is running at https://127.0.0.1:61350/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
80+
81+
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
82+
```
83+
84+
1. Get a list of namespaces in the cluster:
85+
86+
```shell
87+
kubectl get ns
88+
```
89+
The output is similar to this:
90+
```
91+
NAME STATUS AGE
92+
default Active 9m30s
93+
kube-node-lease Active 9m32s
94+
kube-public Active 9m32s
95+
kube-system Active 9m32s
96+
local-path-storage Active 9m26s
97+
```
98+
99+
1. Use `--dry-run=server` to understand what happens when different Pod Security Standards
100+
are applied:
101+
102+
1. Privileged
103+
```shell
104+
kubectl label --dry-run=server --overwrite ns --all \
105+
pod-security.kubernetes.io/enforce=privileged
106+
```
107+
108+
The output is similar to:
109+
```
110+
namespace/default labeled
111+
namespace/kube-node-lease labeled
112+
namespace/kube-public labeled
113+
namespace/kube-system labeled
114+
namespace/local-path-storage labeled
115+
```
116+
2. Baseline
117+
```shell
118+
kubectl label --dry-run=server --overwrite ns --all \
119+
pod-security.kubernetes.io/enforce=baseline
120+
```
121+
122+
The output is similar to:
123+
```
124+
namespace/default labeled
125+
namespace/kube-node-lease labeled
126+
namespace/kube-public labeled
127+
Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest"
128+
Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes
129+
Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes
130+
Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged
131+
namespace/kube-system labeled
132+
namespace/local-path-storage labeled
133+
```
134+
135+
3. Restricted
136+
```shell
137+
kubectl label --dry-run=server --overwrite ns --all \
138+
pod-security.kubernetes.io/enforce=restricted
139+
```
140+
141+
The output is similar to:
142+
```
143+
namespace/default labeled
144+
namespace/kube-node-lease labeled
145+
namespace/kube-public labeled
146+
Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest"
147+
Warning: coredns-7bb9c7b568-hsptc (and 1 other pod): unrestricted capabilities, runAsNonRoot != true, seccompProfile
148+
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
149+
Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
150+
Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
151+
namespace/kube-system labeled
152+
Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest"
153+
Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
154+
namespace/local-path-storage labeled
155+
```
156+
157+
From the previous output, you'll notice that applying the `privileged` Pod Security Standard shows no warnings
158+
for any namespaces. However, `baseline` and `restricted` standards both have
159+
warnings, specifically in the `kube-system` namespace.
160+
161+
## Set modes, versions and standards
162+
163+
In this section, you apply the following Pod Security Standards to the `latest` version:
164+
165+
* `baseline` standard in `enforce` mode.
166+
* `restricted` standard in `warn` and `audit` mode.
167+
168+
The `baseline` Pod Security Standard provides a convenient
169+
middle ground that allows keeping the exemption list short and prevents known
170+
privilege escalations.
171+
172+
Additionally, to prevent pods from failing in `kube-system`, you'll exempt the namespace
173+
from having Pod Security Standards applied.
174+
175+
When you implement Pod Security Admission in your own environment, consider the
176+
following:
177+
178+
1. Based on the risk posture applied to a cluster, a stricter Pod Security
179+
Standard like `restricted` might be a better choice.
180+
1. Exempting the `kube-system` namespace allows pods to run as
181+
`privileged` in this namespace. For real world use, the Kubernetes project
182+
strongly recommends that you apply strict RBAC
183+
policies that limit access to `kube-system`, following the principle of least
184+
privilege.
185+
To implement the preceding standards, do the following:
186+
1. Create a configuration file that can be consumed by the Pod Security
187+
Admission Controller to implement these Pod Security Standards:
188+
189+
```
190+
mkdir -p /tmp/pss
191+
cat <<EOF > /tmp/pss/cluster-level-pss.yaml
192+
apiVersion: apiserver.config.k8s.io/v1
193+
kind: AdmissionConfiguration
194+
plugins:
195+
- name: PodSecurity
196+
configuration:
197+
apiVersion: pod-security.admission.config.k8s.io/v1
198+
kind: PodSecurityConfiguration
199+
defaults:
200+
enforce: "baseline"
201+
enforce-version: "latest"
202+
audit: "restricted"
203+
audit-version: "latest"
204+
warn: "restricted"
205+
warn-version: "latest"
206+
exemptions:
207+
usernames: []
208+
runtimeClasses: []
209+
namespaces: [kube-system]
210+
EOF
211+
```
212+
213+
{{< note >}}
214+
`pod-security.admission.config.k8s.io/v1` configuration requires v1.25+.
215+
For v1.23 and v1.24, use [v1beta1](https://v1-24.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/).
216+
For v1.22, use [v1alpha1](https://v1-22.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/).
217+
{{< /note >}}
218+
219+
220+
1. Configure the API server to consume this file during cluster creation:
221+
222+
```
223+
cat <<EOF > /tmp/pss/cluster-config.yaml
224+
kind: Cluster
225+
apiVersion: kind.x-k8s.io/v1alpha4
226+
nodes:
227+
- role: control-plane
228+
kubeadmConfigPatches:
229+
- |
230+
kind: ClusterConfiguration
231+
apiServer:
232+
extraArgs:
233+
admission-control-config-file: /etc/config/cluster-level-pss.yaml
234+
extraVolumes:
235+
- name: accf
236+
hostPath: /etc/config
237+
mountPath: /etc/config
238+
readOnly: false
239+
pathType: "DirectoryOrCreate"
240+
extraMounts:
241+
- hostPath: /tmp/pss
242+
containerPath: /etc/config
243+
# optional: if set, the mount is read-only.
244+
# default false
245+
readOnly: false
246+
# optional: if set, the mount needs SELinux relabeling.
247+
# default false
248+
selinuxRelabel: false
249+
# optional: set propagation mode (None, HostToContainer or Bidirectional)
250+
# see https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation
251+
# default None
252+
propagation: None
253+
EOF
254+
```
255+
256+
{{<note>}}
257+
If you use Docker Desktop with KinD on macOS, you can
258+
add `/tmp` as a Shared Directory under the menu item
259+
**Preferences > Resources > File Sharing**.
260+
{{</note>}}
261+
262+
1. Create a cluster that uses Pod Security Admission to apply
263+
these Pod Security Standards:
264+
265+
```shell
266+
kind create cluster --name psa-with-cluster-pss --config /tmp/pss/cluster-config.yaml
267+
```
268+
The output is similar to this:
269+
```
270+
Creating cluster "psa-with-cluster-pss" ...
271+
✓ Ensuring node image (kindest/node:v{{< skew currentVersion >}}.0) 🖼
272+
✓ Preparing nodes 📦
273+
✓ Writing configuration 📜
274+
✓ Starting control-plane 🕹️
275+
✓ Installing CNI 🔌
276+
✓ Installing StorageClass 💾
277+
Set kubectl context to "kind-psa-with-cluster-pss"
278+
You can now use your cluster with:
279+
280+
kubectl cluster-info --context kind-psa-with-cluster-pss
281+
282+
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
283+
```
284+
285+
1. Point kubectl to the cluster:
286+
```shell
287+
kubectl cluster-info --context kind-psa-with-cluster-pss
288+
```
289+
The output is similar to this:
290+
```
291+
Kubernetes control plane is running at https://127.0.0.1:63855
292+
CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
293+
294+
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
295+
```
296+
297+
1. Create a Pod in the default namespace:
298+
299+
```shell
300+
kubectl apply -f https://k8s.io/examples/security/example-baseline-pod.yaml
301+
```
302+
303+
The pod is started normally, but the output includes a warning:
304+
```
305+
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")
306+
pod/nginx created
307+
```
308+
309+
## Clean up
310+
311+
Now delete the clusters which you created above by running the following command:
312+
313+
```shell
314+
kind delete cluster --name psa-with-cluster-pss
315+
```
316+
```shell
317+
kind delete cluster --name psa-wo-cluster-pss
318+
```
319+
320+
## {{% heading "whatsnext" %}}
321+
322+
- Run a
323+
[shell script](/examples/security/kind-with-cluster-level-baseline-pod-security.sh)
324+
to perform all the preceding steps at once:
325+
1. Create a Pod Security Standards based cluster level Configuration
326+
2. Create a file to let API server consume this configuration
327+
3. Create a cluster that creates an API server with this configuration
328+
4. Set kubectl context to this new cluster
329+
5. Create a minimal pod yaml file
330+
6. Apply this file to create a Pod in the new cluster
331+
- [Pod Security Admission](/docs/concepts/security/pod-security-admission/)
332+
- [Pod Security Standards](/docs/concepts/security/pod-security-standards/)
333+
- [Apply Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss/)

0 commit comments

Comments
 (0)