diff --git a/content/en/docs/concepts/security/cloud-native-security.md b/content/en/docs/concepts/security/cloud-native-security.md index 778dba0c38..d8f4ccdd7b 100644 --- a/content/en/docs/concepts/security/cloud-native-security.md +++ b/content/en/docs/concepts/security/cloud-native-security.md @@ -143,7 +143,7 @@ To protect your compute at runtime, you can: Pods with different trust contexts are run on separate sets of nodes. 1. Use a {{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} that provides security restrictions. -1. On Linux nodes, use a Linux security module such as [AppArmor](/docs/tutorials/security/apparmor/) (beta) +1. On Linux nodes, use a Linux security module such as [AppArmor](/docs/tutorials/security/apparmor/) or [seccomp](/docs/tutorials/security/seccomp/). ### Runtime protection: storage {#protection-runtime-storage} @@ -223,4 +223,3 @@ logs are both tamper-proof and confidential. * [Network policies](/docs/concepts/services-networking/network-policies/) for Pods * [Pod security standards](/docs/concepts/security/pod-security-standards/) * [RuntimeClasses](/docs/concepts/containers/runtime-class) - diff --git a/content/en/docs/concepts/security/pod-security-admission.md b/content/en/docs/concepts/security/pod-security-admission.md index 95a2d6e3f4..c4caa6905d 100644 --- a/content/en/docs/concepts/security/pod-security-admission.md +++ b/content/en/docs/concepts/security/pod-security-admission.md @@ -121,7 +121,7 @@ current policy level: - Any metadata updates **except** changes to the seccomp or AppArmor annotations: - `seccomp.security.alpha.kubernetes.io/pod` (deprecated) - `container.seccomp.security.alpha.kubernetes.io/*` (deprecated) - - `container.apparmor.security.beta.kubernetes.io/*` + - `container.apparmor.security.beta.kubernetes.io/*` (deprecated) - Valid updates to `.spec.activeDeadlineSeconds` - Valid updates to `.spec.tolerations` diff --git a/content/en/docs/concepts/security/pod-security-standards.md b/content/en/docs/concepts/security/pod-security-standards.md index 9757e58159..fb9cab9d15 100644 --- a/content/en/docs/concepts/security/pod-security-standards.md +++ b/content/en/docs/concepts/security/pod-security-standards.md @@ -170,8 +170,21 @@ fail validation. AppArmor -

On supported hosts, the runtime/default AppArmor profile is applied by default. The baseline policy should prevent overriding or disabling the default AppArmor profile, or restrict overrides to an allowed set of profiles.

+

On supported hosts, the RuntimeDefault AppArmor profile is applied by default. The baseline policy should prevent overriding or disabling the default AppArmor profile, or restrict overrides to an allowed set of profiles.

Restricted Fields

+ +

Allowed Values

+ +
@@ -532,4 +545,3 @@ kernel. This allows for workloads requiring heightened permissions to still be i Additionally, the protection of sandboxed workloads is highly dependent on the method of sandboxing. As such, no single recommended profile is recommended for all sandboxed workloads. - diff --git a/content/en/docs/concepts/security/security-checklist.md b/content/en/docs/concepts/security/security-checklist.md index 6987a6b92a..e78b8da0c5 100644 --- a/content/en/docs/concepts/security/security-checklist.md +++ b/content/en/docs/concepts/security/security-checklist.md @@ -177,10 +177,10 @@ Seccomp is only available on Linux nodes. #### AppArmor -[AppArmor](https://apparmor.net/) is a Linux kernel security module that can +[AppArmor](/docs/tutorials/security/apparmor/) is a Linux kernel security module that can provide an easy way to implement Mandatory Access Control (MAC) and better -auditing through system logs. To [enable AppArmor in Kubernetes](/docs/tutorials/security/apparmor/), -at least version 1.4 is required. Like seccomp, AppArmor is also configured +auditing through system logs. A default AppArmor profile is enforced on nodes that support it, or a custom profile can be configured. +Like seccomp, AppArmor is also configured through profiles, where each profile is either running in enforcing mode, which blocks access to disallowed resources or complain mode, which only reports violations. AppArmor profiles are enforced on a per-container basis, with an diff --git a/content/en/docs/reference/labels-annotations-taints/_index.md b/content/en/docs/reference/labels-annotations-taints/_index.md index 7fa82414b9..e525235cfe 100644 --- a/content/en/docs/reference/labels-annotations-taints/_index.md +++ b/content/en/docs/reference/labels-annotations-taints/_index.md @@ -300,7 +300,7 @@ which is used by Kustomize and similar third-party tools. For example, Kustomize removes objects with this annotation from its final build output. -### container.apparmor.security.beta.kubernetes.io/* (beta) {#container-apparmor-security-beta-kubernetes-io} +### container.apparmor.security.beta.kubernetes.io/* (deprecated) {#container-apparmor-security-beta-kubernetes-io} Type: Annotation @@ -309,7 +309,7 @@ Example: `container.apparmor.security.beta.kubernetes.io/my-container: my-custom Used on: Pods This annotation allows you to specify the AppArmor security profile for a container within a -Kubernetes pod. +Kubernetes pod. As of Kubernetes v1.30, this should be set with the `appArmorProfile` field instead. To learn more, see the [AppArmor](/docs/tutorials/security/apparmor/) tutorial. The tutorial illustrates using AppArmor to restrict a container's abilities and access. diff --git a/content/en/docs/tasks/debug/debug-cluster/_index.md b/content/en/docs/tasks/debug/debug-cluster/_index.md index a10b0bdcff..cde6043c03 100644 --- a/content/en/docs/tasks/debug/debug-cluster/_index.md +++ b/content/en/docs/tasks/debug/debug-cluster/_index.md @@ -203,7 +203,7 @@ status: type: PIDPressure - lastHeartbeatTime: "2022-02-17T22:20:15Z" lastTransitionTime: "2022-02-17T22:15:15Z" - message: kubelet is posting ready status. AppArmor enabled + message: kubelet is posting ready status reason: KubeletReady status: "True" type: Ready @@ -330,4 +330,3 @@ This is an incomplete list of things that could go wrong, and how to adjust your * Use `crictl` to [debug Kubernetes nodes](/docs/tasks/debug/debug-cluster/crictl/) * Get more information about [Kubernetes auditing](/docs/tasks/debug/debug-cluster/audit/) * Use `telepresence` to [develop and debug services locally](/docs/tasks/debug/debug-cluster/local-debugging/) - diff --git a/content/en/docs/tutorials/security/apparmor.md b/content/en/docs/tutorials/security/apparmor.md index 49e9f641fd..c7c51d9236 100644 --- a/content/en/docs/tutorials/security/apparmor.md +++ b/content/en/docs/tutorials/security/apparmor.md @@ -8,7 +8,7 @@ weight: 30 -{{< feature-state for_k8s_version="v1.4" state="beta" >}} +{{< feature-state feature_gate_name="AppArmor" >}} [AppArmor](https://apparmor.net/) is a Linux kernel security module that supplements the standard Linux user and group based @@ -54,7 +54,7 @@ Nodes before proceeding: Y ``` - The Kubelet verifies that AppArmor is enabled on the host before admitting a pod with AppArmor + The kubelet verifies that AppArmor is enabled on the host before admitting a pod with AppArmor explicitly configured. 3. Container runtime supports AppArmor -- All common Kubernetes-supported container @@ -64,7 +64,7 @@ Nodes before proceeding: 4. Profile is loaded -- AppArmor is applied to a Pod by specifying an AppArmor profile that each container should be run with. If any of the specified profiles are not loaded in the - kernel, the Kubelet will reject the Pod. You can view which profiles are loaded on a + kernel, the kubelet will reject the Pod. You can view which profiles are loaded on a node by checking the `/sys/kernel/security/apparmor/profiles` file. For example: ```shell @@ -85,25 +85,26 @@ Nodes before proceeding: ## Securing a Pod {{< note >}} -AppArmor is currently in beta, so options are specified as annotations. Once support graduates to -general availability, the annotations will be replaced with first-class fields. +Prior to Kubernetes v1.30, AppArmor was specified through annotations. Use the documentation version +selector to view the documentation with this deprecated API. {{< /note >}} -AppArmor profiles are specified *per-container*. To specify the AppArmor profile to run a Pod -container with, add an annotation to the Pod's metadata: +AppArmor profiles can be specified at the pod level or container level. The container AppArmor +profile takes precedence over the pod profile. ```yaml -container.apparmor.security.beta.kubernetes.io/: +securityContext: + appArmorProfile: + type: ``` -Where `` is the name of the container to apply the profile to, and `` -specifies the profile to apply. The `` can be one of: +Where `` is one of: -* `runtime/default` to apply the runtime's default profile -* `localhost/` to apply the profile loaded on the host with the name `` -* `unconfined` to indicate that no profiles will be loaded +* `RuntimeDefault` to use the runtime's default profile +* `Localhost` to use a profile loaded on the host (see below) +* `Unconfined` to run without AppArmor -See the [API Reference](#api-reference) for the full details on the annotation and profile name formats. +See the [API Reference](#api-reference) for the full details on the AppArmor profile API. To verify that the profile was applied, you can check that the container's root process is running with the correct profile by examining its proc attr: @@ -115,14 +116,14 @@ kubectl exec -- cat /proc/1/attr/current The output should look something like this: ``` -k8s-apparmor-example-deny-write (enforce) +cri-containerd.apparmor.d (enforce) ``` ## Example *This example assumes you have already set up a cluster with AppArmor support.* -First, load the profile you want to use onto your Nodes. This profile denies all file writes: +First, load the profile you want to use onto your Nodes. This profile blocks all file write operations: ``` #include @@ -197,9 +198,11 @@ apiVersion: v1 kind: Pod metadata: name: hello-apparmor-2 - annotations: - container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-allow-write spec: + securityContext: + appArmorProfile: + type: Localhost + localhostProfile: k8s-apparmor-example-allow-write containers: - name: hello image: busybox:1.28 @@ -243,7 +246,7 @@ An Event provides the error message with the reason, the specific wording is run ### Setting up Nodes with profiles -Kubernetes does not currently provide any built-in mechanisms for loading AppArmor profiles onto +Kubernetes {{< skew currentVersion >}} does not provide any built-in mechanisms for loading AppArmor profiles onto Nodes. Profiles can be loaded through custom infrastructure or tools like the [Kubernetes Security Profiles Operator](https://github.com/kubernetes-sigs/security-profiles-operator). @@ -270,29 +273,31 @@ logs or through `journalctl`. More information is provided in [AppArmor failures](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Failures). -## API Reference +## Specifying AppArmor confinement -### Pod Annotation +{{< caution >}} +Prior to Kubernetes v1.30, AppArmor was specified through annotations. Use the documentation version +selector to view the documentation with this deprecated API. +{{< /caution >}} -Specifying the profile a container will run with: +### AppArmor profile within security context {#appArmorProfile} -- **key**: `container.apparmor.security.beta.kubernetes.io/` - Where `` matches the name of a container in the Pod. - A separate profile can be specified for each container in the Pod. -- **value**: a profile reference, described below +You can specify the `appArmorProfile` on either a container's `securityContext` or on a Pod's +`securityContext`. If the profile is set at the pod level, it will be used as the default profile +for all containers in the pod (including init, sidecar, and ephemeral containers). If both a pod & container +AppArmor profile are set, the container's profile will be used. -### Profile Reference +An AppArmor profile has 2 fields: -- `runtime/default`: Refers to the default runtime profile. - - Equivalent to not specifying a profile, except it still requires AppArmor to be enabled. - - In practice, many container runtimes use the same OCI default profile, defined here: - https://github.com/containers/common/blob/main/pkg/apparmor/apparmor_linux_template.go -- `localhost/`: Refers to a profile loaded on the node (localhost) by name. - - The possible profile names are detailed in the - [core policy reference](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference#profile-names-and-attachment-specifications). -- `unconfined`: This effectively disables AppArmor on the container. +`type` _(required)_ - indicates which kind of AppArmor profile will be applied. Valid options are: + - `Localhost` - a profile pre-loaded on the node (specified by `localhostProfile`). + - `RuntimeDefault` - the container runtime's default profile. + - `Unconfined` - no AppArmor enforcement. + +`localhostProfile` - The name of a profile loaded on the node that should be used. +The profile must be preconfigured on the node to work. +This option must be provided if and only if the `type` is `Localhost`. -Any other profile reference format is invalid. ## {{% heading "whatsnext" %}} diff --git a/content/en/examples/pods/security/hello-apparmor.yaml b/content/en/examples/pods/security/hello-apparmor.yaml index 8fe23590be..a434db1d15 100644 --- a/content/en/examples/pods/security/hello-apparmor.yaml +++ b/content/en/examples/pods/security/hello-apparmor.yaml @@ -2,10 +2,11 @@ apiVersion: v1 kind: Pod metadata: name: hello-apparmor - annotations: - # Tell Kubernetes to apply the AppArmor profile "k8s-apparmor-example-deny-write". - container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write spec: + securityContext: + appArmorProfile: + type: Localhost + localhostProfile: k8s-apparmor-example-deny-write containers: - name: hello image: busybox:1.28