Skip to content

Commit 2a642c1

Browse files
committed
Add docker prereq, mention podman and rearrange sections
1 parent c5a17a1 commit 2a642c1

File tree

1 file changed

+126
-119
lines changed

1 file changed

+126
-119
lines changed

content/en/docs/tutorials/security/seccomp.md

Lines changed: 126 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ profiles that give only the necessary privileges to your container processes.
3939
In order to complete all steps in this tutorial, you must install
4040
[kind](/docs/tasks/tools/#kind) and [kubectl](/docs/tasks/tools/#kubectl).
4141

42+
The commands used in the tutorial assume that you are using
43+
[Docker](https://www.docker.com/) as your container runtime. You could also use
44+
[Podman](https://podman.io/) but in that case, you would have to follow specific
45+
[instructions](https://kind.sigs.k8s.io/docs/user/rootless/) in order to complete the tasks
46+
successfully.
47+
4248
This tutorial shows some examples that are still beta (since v1.25) and
4349
others that use only generally available seccomp functionality. You should
4450
make sure that your cluster is
@@ -154,111 +160,7 @@ audit.json fine-grained.json violation.json
154160
You have verified that these seccomp profiles are available to the kubelet
155161
running within kind.
156162

157-
## Enable the use of `RuntimeDefault` as the default seccomp profile for all workloads
158-
159-
{{< feature-state state="stable" for_k8s_version="v1.27" >}}
160-
161-
To use seccomp profile defaulting, you must run the kubelet with the
162-
`--seccomp-default`
163-
[command line flag](/docs/reference/command-line-tools-reference/kubelet)
164-
enabled for each node where you want to use it.
165-
166-
If enabled, the kubelet will use the `RuntimeDefault` seccomp profile by default, which is
167-
defined by the container runtime, instead of using the `Unconfined` (seccomp disabled) mode.
168-
The default profiles aim to provide a strong set
169-
of security defaults while preserving the functionality of the workload. It is
170-
possible that the default profiles differ between container runtimes and their
171-
release versions, for example when comparing those from CRI-O and containerd.
172-
173-
{{< note >}}
174-
Enabling the feature will neither change the Kubernetes
175-
`securityContext.seccompProfile` API field nor add the deprecated annotations of
176-
the workload. This provides users the possibility to rollback anytime without
177-
actually changing the workload configuration. Tools like
178-
[`crictl inspect`](https://github.com/kubernetes-sigs/cri-tools) can be used to
179-
verify which seccomp profile is being used by a container.
180-
{{< /note >}}
181-
182-
Some workloads may require a lower amount of syscall restrictions than others.
183-
This means that they can fail during runtime even with the `RuntimeDefault`
184-
profile. To mitigate such a failure, you can:
185-
186-
- Run the workload explicitly as `Unconfined`.
187-
- Disable the `SeccompDefault` feature for the nodes. Also making sure that
188-
workloads get scheduled on nodes where the feature is disabled.
189-
- Create a custom seccomp profile for the workload.
190-
191-
If you were introducing this feature into production-like cluster, the Kubernetes project
192-
recommends that you enable this feature gate on a subset of your nodes and then
193-
test workload execution before rolling the change out cluster-wide.
194-
195-
You can find more detailed information about a possible upgrade and downgrade strategy
196-
in the related Kubernetes Enhancement Proposal (KEP):
197-
[Enable seccomp by default](https://github.com/kubernetes/enhancements/tree/9a124fd29d1f9ddf2ff455c49a630e3181992c25/keps/sig-node/2413-seccomp-by-default#upgrade--downgrade-strategy).
198-
199-
Kubernetes {{< skew currentVersion >}} lets you configure the seccomp profile
200-
that applies when the spec for a Pod doesn't define a specific seccomp profile.
201-
However, you still need to enable this defaulting for each node where you would
202-
like to use it.
203-
204-
If you are running a Kubernetes {{< skew currentVersion >}} cluster and want to
205-
enable the feature, either run the kubelet with the `--seccomp-default` command
206-
line flag, or enable it through the [kubelet configuration
207-
file](/docs/tasks/administer-cluster/kubelet-config-file/). To enable the
208-
feature gate in [kind](https://kind.sigs.k8s.io), ensure that `kind` provides
209-
the minimum required Kubernetes version and enables the `SeccompDefault` feature
210-
[in the kind configuration](https://kind.sigs.k8s.io/docs/user/quick-start/#enable-feature-gates-in-your-cluster):
211-
212-
```yaml
213-
kind: Cluster
214-
apiVersion: kind.x-k8s.io/v1alpha4
215-
nodes:
216-
- role: control-plane
217-
image: kindest/node:v1.23.0@sha256:49824ab1727c04e56a21a5d8372a402fcd32ea51ac96a2706a12af38934f81ac
218-
kubeadmConfigPatches:
219-
- |
220-
kind: JoinConfiguration
221-
nodeRegistration:
222-
kubeletExtraArgs:
223-
seccomp-default: "true"
224-
- role: worker
225-
image: kindest/node:v1.23.0@sha256:49824ab1727c04e56a21a5d8372a402fcd32ea51ac96a2706a12af38934f81ac
226-
kubeadmConfigPatches:
227-
- |
228-
kind: JoinConfiguration
229-
nodeRegistration:
230-
kubeletExtraArgs:
231-
seccomp-default: "true"
232-
```
233-
234-
If the cluster is ready, then running a pod:
235-
236-
```shell
237-
kubectl run --rm -it --restart=Never --image=alpine alpine -- sh
238-
```
239-
240-
Should now have the default seccomp profile attached. This can be verified by
241-
using `docker exec` to run `crictl inspect` for the container on the kind
242-
worker:
243-
244-
```shell
245-
docker exec -it kind-worker bash -c \
246-
'crictl inspect $(crictl ps --name=alpine -q) | jq .info.runtimeSpec.linux.seccomp'
247-
```
248-
249-
```json
250-
{
251-
"defaultAction": "SCMP_ACT_ERRNO",
252-
"architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32"],
253-
"syscalls": [
254-
{
255-
"names": ["..."]
256-
}
257-
]
258-
}
259-
```
260-
261-
## Create Pod that uses the container runtime default seccomp profile
163+
## Create a Pod that uses the container runtime default seccomp profile
262164

263165
Most container runtimes provide a sane set of default syscalls that are allowed
264166
or not. You can adopt these defaults for your workload by setting the seccomp
@@ -290,7 +192,7 @@ NAME READY STATUS RESTARTS AGE
290192
default-pod 1/1 Running 0 20s
291193
```
292194

293-
Finally, now that you saw that work OK, clean up:
195+
Delete the Pod before moving to the next section:
294196

295197
```shell
296198
kubectl delete pod default-pod --wait --now
@@ -323,7 +225,7 @@ This profile does not restrict any syscalls, so the Pod should start
323225
successfully.
324226

325227
```shell
326-
kubectl get pod/audit-pod
228+
kubectl get pod audit-pod
327229
```
328230

329231
```
@@ -332,7 +234,7 @@ audit-pod 1/1 Running 0 30s
332234
```
333235

334236
In order to be able to interact with this endpoint exposed by this
335-
container, create a NodePort {{< glossary_tooltip text="Services" term_id="service" >}}
237+
container, create a NodePort {{< glossary_tooltip text="Service" term_id="service" >}}
336238
that allows access to the endpoint from inside the kind control plane container.
337239

338240
```shell
@@ -356,7 +258,7 @@ at the port exposed by this Service. Use `docker exec` to run the `curl` command
356258
container belonging to that control plane container:
357259

358260
```shell
359-
# Change 6a96207fed4b to the control plane container ID you saw from "docker ps"
261+
# Change 6a96207fed4b to the control plane container ID and 32373 to the port number you saw from "docker ps"
360262
docker exec -it 6a96207fed4b curl localhost:32373
361263
```
362264

@@ -366,15 +268,16 @@ just made some syscalls!
366268

367269
You can see that the process is running, but what syscalls did it actually make?
368270
Because this Pod is running in a local cluster, you should be able to see those
369-
in `/var/log/syslog`. Open up a new terminal window and `tail` the output for
271+
in `/var/log/syslog` on your local system. Open up a new terminal window and `tail` the output for
370272
calls from `http-echo`:
371273

372274
```shell
275+
# The log path on your computer might be different from "/var/log/syslog"
373276
tail -f /var/log/syslog | grep 'http-echo'
374277
```
375278

376-
You should already see some logs of syscalls made by `http-echo`, and if you
377-
`curl` the endpoint in the control plane container you will see more written.
279+
You should already see some logs of syscalls made by `http-echo`, and if you run `curl` again inside
280+
the control plane container you will see more output written to the log.
378281

379282
For example:
380283
```
@@ -393,14 +296,14 @@ looking at the `syscall=` entry on each line. While these are unlikely to
393296
encompass all syscalls it uses, it can serve as a basis for a seccomp profile
394297
for this container.
395298

396-
Clean up that Pod and Service before moving to the next section:
299+
Delete the Service and the Pod before moving to the next section:
397300

398301
```shell
399302
kubectl delete service audit-pod --wait
400303
kubectl delete pod audit-pod --wait --now
401304
```
402305

403-
## Create Pod with a seccomp profile that causes violation
306+
## Create a Pod with a seccomp profile that causes violation
404307

405308
For demonstration, apply a profile to the Pod that does not allow for any
406309
syscalls.
@@ -419,7 +322,7 @@ The Pod creates, but there is an issue.
419322
If you check the status of the Pod, you should see that it failed to start.
420323

421324
```shell
422-
kubectl get pod/violation-pod
325+
kubectl get pod violation-pod
423326
```
424327

425328
```
@@ -433,13 +336,13 @@ syscalls. Here seccomp has been instructed to error on any syscall by setting
433336
ability to do anything meaningful. What you really want is to give workloads
434337
only the privileges they need.
435338

436-
Clean up that Pod before moving to the next section:
339+
Delete the Pod before moving to the next section:
437340

438341
```shell
439342
kubectl delete pod violation-pod --wait --now
440343
```
441344

442-
## Create Pod with a seccomp profile that only allows necessary syscalls
345+
## Create a Pod with a seccomp profile that only allows necessary syscalls
443346

444347
If you take a look at the `fine-grained.json` profile, you will notice some of the syscalls
445348
seen in syslog of the first example where the profile set `"defaultAction":
@@ -497,7 +400,7 @@ fine-pod NodePort 10.111.36.142 <none> 5678:32373/TCP 72s
497400
Use `curl` to access that endpoint from inside the kind control plane container:
498401

499402
```shell
500-
# Change 6a96207fed4b to the control plane container ID you saw from "docker ps"
403+
# Change 6a96207fed4b to the control plane container ID and 32373 to the port number you saw from "docker ps"
501404
docker exec -it 6a96207fed4b curl localhost:32373
502405
```
503406

@@ -511,13 +414,117 @@ the list is invoked. This is an ideal situation from a security perspective, but
511414
required some effort in analyzing the program. It would be nice if there was a
512415
simple way to get closer to this security without requiring as much effort.
513416

514-
Clean up that Pod and Service before moving to the next section:
417+
Delete the Service and the Pod before moving to the next section:
515418

516419
```shell
517420
kubectl delete service fine-pod --wait
518421
kubectl delete pod fine-pod --wait --now
519422
```
520423

424+
## Enable the use of `RuntimeDefault` as the default seccomp profile for all workloads
425+
426+
{{< feature-state state="stable" for_k8s_version="v1.27" >}}
427+
428+
To use seccomp profile defaulting, you must run the kubelet with the
429+
`--seccomp-default`
430+
[command line flag](/docs/reference/command-line-tools-reference/kubelet)
431+
enabled for each node where you want to use it.
432+
433+
If enabled, the kubelet will use the `RuntimeDefault` seccomp profile by default, which is
434+
defined by the container runtime, instead of using the `Unconfined` (seccomp disabled) mode.
435+
The default profiles aim to provide a strong set
436+
of security defaults while preserving the functionality of the workload. It is
437+
possible that the default profiles differ between container runtimes and their
438+
release versions, for example when comparing those from CRI-O and containerd.
439+
440+
{{< note >}}
441+
Enabling the feature will neither change the Kubernetes
442+
`securityContext.seccompProfile` API field nor add the deprecated annotations of
443+
the workload. This provides users the possibility to rollback anytime without
444+
actually changing the workload configuration. Tools like
445+
[`crictl inspect`](https://github.com/kubernetes-sigs/cri-tools) can be used to
446+
verify which seccomp profile is being used by a container.
447+
{{< /note >}}
448+
449+
Some workloads may require a lower amount of syscall restrictions than others.
450+
This means that they can fail during runtime even with the `RuntimeDefault`
451+
profile. To mitigate such a failure, you can:
452+
453+
- Run the workload explicitly as `Unconfined`.
454+
- Disable the `SeccompDefault` feature for the nodes. Also making sure that
455+
workloads get scheduled on nodes where the feature is disabled.
456+
- Create a custom seccomp profile for the workload.
457+
458+
If you were introducing this feature into production-like cluster, the Kubernetes project
459+
recommends that you enable this feature gate on a subset of your nodes and then
460+
test workload execution before rolling the change out cluster-wide.
461+
462+
You can find more detailed information about a possible upgrade and downgrade strategy
463+
in the related Kubernetes Enhancement Proposal (KEP):
464+
[Enable seccomp by default](https://github.com/kubernetes/enhancements/tree/9a124fd29d1f9ddf2ff455c49a630e3181992c25/keps/sig-node/2413-seccomp-by-default#upgrade--downgrade-strategy).
465+
466+
Kubernetes {{< skew currentVersion >}} lets you configure the seccomp profile
467+
that applies when the spec for a Pod doesn't define a specific seccomp profile.
468+
However, you still need to enable this defaulting for each node where you would
469+
like to use it.
470+
471+
If you are running a Kubernetes {{< skew currentVersion >}} cluster and want to
472+
enable the feature, either run the kubelet with the `--seccomp-default` command
473+
line flag, or enable it through the [kubelet configuration
474+
file](/docs/tasks/administer-cluster/kubelet-config-file/). To enable the
475+
feature gate in [kind](https://kind.sigs.k8s.io), ensure that `kind` provides
476+
the minimum required Kubernetes version and enables the `SeccompDefault` feature
477+
[in the kind configuration](https://kind.sigs.k8s.io/docs/user/quick-start/#enable-feature-gates-in-your-cluster):
478+
479+
```yaml
480+
kind: Cluster
481+
apiVersion: kind.x-k8s.io/v1alpha4
482+
nodes:
483+
- role: control-plane
484+
image: kindest/node:v1.23.0@sha256:49824ab1727c04e56a21a5d8372a402fcd32ea51ac96a2706a12af38934f81ac
485+
kubeadmConfigPatches:
486+
- |
487+
kind: JoinConfiguration
488+
nodeRegistration:
489+
kubeletExtraArgs:
490+
seccomp-default: "true"
491+
- role: worker
492+
image: kindest/node:v1.23.0@sha256:49824ab1727c04e56a21a5d8372a402fcd32ea51ac96a2706a12af38934f81ac
493+
kubeadmConfigPatches:
494+
- |
495+
kind: JoinConfiguration
496+
nodeRegistration:
497+
kubeletExtraArgs:
498+
seccomp-default: "true"
499+
```
500+
501+
If the cluster is ready, then running a pod:
502+
503+
```shell
504+
kubectl run --rm -it --restart=Never --image=alpine alpine -- sh
505+
```
506+
507+
Should now have the default seccomp profile attached. This can be verified by
508+
using `docker exec` to run `crictl inspect` for the container on the kind
509+
worker:
510+
511+
```shell
512+
docker exec -it kind-worker bash -c \
513+
'crictl inspect $(crictl ps --name=alpine -q) | jq .info.runtimeSpec.linux.seccomp'
514+
```
515+
516+
```json
517+
{
518+
"defaultAction": "SCMP_ACT_ERRNO",
519+
"architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32"],
520+
"syscalls": [
521+
{
522+
"names": ["..."]
523+
}
524+
]
525+
}
526+
```
527+
521528
## {{% heading "whatsnext" %}}
522529

523530
You can learn more about Linux seccomp:

0 commit comments

Comments
 (0)