diff --git a/content/en/docs/concepts/storage/volumes.md b/content/en/docs/concepts/storage/volumes.md index 739773cfbe..369afe5dc0 100644 --- a/content/en/docs/concepts/storage/volumes.md +++ b/content/en/docs/concepts/storage/volumes.md @@ -303,15 +303,17 @@ keyed with `log_level`. ### downwardAPI {#downwardapi} -A `downwardAPI` volume makes downward API data available to applications. -It mounts a directory and writes the requested data in plain text files. +A `downwardAPI` volume makes {{< glossary_tooltip term_id="downward-api" text="downward API" >}} +data available to applications. Within the volume, you can find the exposed +data as read-only files in plain text format. {{< note >}} -A container using the downward API as a [`subPath`](#using-subpath) volume mount will not -receive downward API updates. +A container using the downward API as a [`subPath`](#using-subpath) volume mount does not +receive updates when field values change. {{< /note >}} -See the [downward API example](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) for more details. +See [Expose Pod Information to Containers Through Files](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) +to learn more. ### emptyDir {#emptydir} diff --git a/content/en/docs/concepts/workloads/pods/downward-api.md b/content/en/docs/concepts/workloads/pods/downward-api.md new file mode 100644 index 0000000000..40b2362959 --- /dev/null +++ b/content/en/docs/concepts/workloads/pods/downward-api.md @@ -0,0 +1,131 @@ +--- +title: Downward API +content_type: concept +description: > + There are two ways to expose Pod and container fields to a running container: + environment variables, and as files that are populated by a special volume type. + Together, these two ways of exposing Pod and container fields are called the downward API. +--- + + + +It is sometimes useful for a container to have information about itself, without +being overly coupled to Kubernetes. The _downward API_ allows containers to consume +information about themselves or the cluster without using the Kubernetes client +or API server. + +An example is an existing application that assumes a particular well-known +environment variable holds a unique identifier. One possibility is to wrap the +application, but that is tedious and error prone, and it violates the goal of low +coupling. A better option would be to use the Pod's name as an identifier, and +inject the Pod's name into the well-known environment variable. + +In Kubernetes, there are two ways to expose Pod and container fields to a running container: + +* as [environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/#the-downward-api) +* as [files in a `downwardAPI` volume](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) + +Together, these two ways of exposing Pod and container fields are called the +_downward API_. + + + +## Available fields + +Only some Kubernetes API fields are available through the downward API. This +section lists which fields you can make available. + +You can pass information from available Pod-level fields using `fieldRef`. +At the API level, the `spec` for a Pod always defines at least one +[Container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container). +You can pass information from available Container-level fields using +`resourceFieldRef`. + +### Information available via `fieldRef` {#downwardapi-fieldRef} + +For most Pod-level fields, you can provide them to a container either as +an environment variable or using a `downwardAPI` volume. The fields available +via either mechanism are: + +`metadata.name` +: the pod's name + +`metadata.namespace` +: the pod's {{< glossary_tooltip text="namespace" term_id="namespace" >}} + +`metadata.uid` +: the pod's unique ID + +`metadata.annotations['']` +: the value of the pod's {{< glossary_tooltip text="annotation" term_id="annotation" >}} named `` (for example, `metadata.annotations['myannotation']`) + +`metadata.labels['']` +: the text value of the pod's {{< glossary_tooltip text="label" term_id="label" >}} named `` (for example, `metadata.labels['mylabel']`) + +`spec.serviceAccountName` +: the name of the pod's {{< glossary_tooltip text="service account" term_id="service-account" >}} + +`spec.nodeName` +: the name of the {{< glossary_tooltip term_id="node" text="node">}} where the Pod is executing + +`status.hostIP` +: the primary IP address of the node to which the Pod is assigned + +`status.podIP` +: the pod's primary IP address (usually, its IPv4 address) + +In addition, the following information is available through +a `downwardAPI` volume `fieldRef`, but **not as environment variables**: + +`metadata.labels` +: all of the pod's labels, formatted as `label-key="escaped-label-value"` with one label per line + +`metadata.annotations` +: all of the pod's annotations, formatted as `annotation-key="escaped-annotation-value"` with one annotation per line + +### Information available via `resourceFieldRef` {#downwardapi-resourceFieldRef} + +These container-level fields allow you to provide information about +[requests and limits](/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) +for resources such as CPU and memory. + + +`resource: limits.cpu` +: A container's CPU limit + +`resource: requests.cpu` +: A container's CPU request + +`resource: limits.memory` +: A container's memory limit + +`resource: requests.memory` +: A container's memory request + +`resource: limits.hugepages-*` +: A container's hugepages limit (provided that the `DownwardAPIHugePages` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled) + +`resource: requests.hugepages-*` +: A container's hugepages request (provided that the `DownwardAPIHugePages` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled) + +`resource: limits.ephemeral-storage` +: A container's ephemeral-storage limit + +`resource: requests.ephemeral-storage` +: A container's ephemeral-storage request + +#### Fallback information for resource limits + +If CPU and memory limits are not specified for a container, and you use the +downward API to try to expose that information, then the +kubelet defaults to exposing the maximum allocatable value for CPU and memory +(based on the [node allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) +calculation). + +## {{% heading "whatsnext" %}} + +You can read about [`downwardAPI` volumes](/docs/concepts/storage/volumes/#downwardapi). + +You can try using the downward API to expose container- or Pod-level information: +* as [environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/#the-downward-api) +* as [files in `downwardAPI` volume](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) diff --git a/content/en/docs/reference/glossary/downward-api.md b/content/en/docs/reference/glossary/downward-api.md new file mode 100644 index 0000000000..a3d9a46336 --- /dev/null +++ b/content/en/docs/reference/glossary/downward-api.md @@ -0,0 +1,28 @@ +--- +title: Downward API +id: downward-api +date: 2022-03-21 +short_description: > + A mechanism to expose Pod and container field values to code running in a container. +aka: +full_link: /docs/concepts/workloads/pods/downward-api/ +tags: +- architecture +--- +Kubernetes' mechanism to expose Pod and container field values to code running in a container. + +It is sometimes useful for a container to have information about itself, without +needing to make changes to the container code that directly couple it to Kubernetes. + +The Kubernetes downward API allows containers to consume information about themselves +or their context in a Kubernetes cluster. Applications in containers can have +access to that information, without the application needing to act as a client of +the Kubernetes API. + +There are two ways to expose Pod and container fields to a running container: + +- using [environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/) +- using [a `downwardAPI` volume](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) + +Together, these two ways of exposing Pod and container fields are called the _downward API_. + diff --git a/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md b/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md index fb6085980b..42302467c1 100644 --- a/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md +++ b/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md @@ -7,38 +7,38 @@ weight: 40 This page shows how a Pod can use a -[`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core) -to expose information about itself to Containers running in the Pod. -A `DownwardAPIVolumeFile` can expose Pod fields and Container fields. +[`downwardAPI` volume](/docs/concepts/storage/volumes/#downwardapi), +to expose information about itself to containers running in the Pod. +A `downwardAPI` volume can expose Pod fields and container fields. + +In Kubernetes, there are two ways to expose Pod and container fields to a running container: + +* [Environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/#the-downward-api) +* Volume files, as explained in this task + +Together, these two ways of exposing Pod and container fields are called the +_downward API_. ## {{% heading "prerequisites" %}} -{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} +{{< include "task-tutorial-prereqs.md" >}} + -## The Downward API - -There are two ways to expose Pod and Container fields to a running Container: - -* [Environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/#the-downward-api) -* Volume files - -Together, these two ways of exposing Pod and Container fields are called the -"Downward API". - ## Store Pod fields -In this exercise, you create a Pod that has one Container. -Here is the configuration file for the Pod: +In this part of exercise, you create a Pod that has one container, and you +project Pod-level fields into the running container as files. +Here is the manifest for the Pod: {{< codenew file="pods/inject/dapi-volume.yaml" >}} -In the configuration file, you can see that the Pod has a `downwardAPI` Volume, -and the Container mounts the Volume at `/etc/podinfo`. +In the manifest, you can see that the Pod has a `downwardAPI` Volume, +and the container mounts the volume at `/etc/podinfo`. -Look at the `items` array under `downwardAPI`. Each element of the array is a -[DownwardAPIVolumeFile](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core). +Look at the `items` array under `downwardAPI`. Each element of the array +defines a `downwardAPI` volume. The first element specifies that the value of the Pod's `metadata.labels` field should be stored in a file named `labels`. The second element specifies that the value of the Pod's `annotations` @@ -46,7 +46,7 @@ field should be stored in a file named `annotations`. {{< note >}} The fields in this example are Pod fields. They are not -fields of the Container in the Pod. +fields of the container in the Pod. {{< /note >}} Create the Pod: @@ -145,26 +145,30 @@ Exit the shell: /# exit ``` -## Store Container fields +## Store container fields -The preceding exercise, you stored Pod fields in a -[`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core).. -In this next exercise, you store Container fields. Here is the configuration -file for a Pod that has one Container: +The preceding exercise, you made Pod-level fields accessible using the +downward API. +In this next exercise, you are going to pass fields that are part of the Pod +definition, but taken from the specific +[container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container) +rather than from the Pod overall. Here is a manifest for a Pod that again has +just one container: {{< codenew file="pods/inject/dapi-volume-resources.yaml" >}} -In the configuration file, you can see that the Pod has a +In the manifest, you can see that the Pod has a [`downwardAPI` volume](/docs/concepts/storage/volumes/#downwardapi), -and the Container mounts the volume at `/etc/podinfo`. +and that the single container in that Pod mounts the volume at `/etc/podinfo`. -Look at the `items` array under `downwardAPI`. Each element of the array is a -[`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core). +Look at the `items` array under `downwardAPI`. Each element of the array +defines a file in the downward API volume. -The first element specifies that in the Container named `client-container`, +The first element specifies that in the container named `client-container`, the value of the `limits.cpu` field in the format specified by `1m` should be -stored in a file named `cpu_limit`. The `divisor` field is optional and has the -default value of `1` which means cores for cpu and bytes for memory. +published as a file named `cpu_limit`. The `divisor` field is optional and has the +default value of `1`. A divisor of 1 means cores for `cpu` resources, or +bytes for `memory` resources. Create the Pod: @@ -181,7 +185,8 @@ kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh In your shell, view the `cpu_limit` file: ```shell -/# cat /etc/podinfo/cpu_limit +# Run this in a shell inside the container +cat /etc/podinfo/cpu_limit ``` You can use similar commands to view the `cpu_request`, `mem_limit` and @@ -189,79 +194,20 @@ You can use similar commands to view the `cpu_request`, `mem_limit` and - -## Capabilities of the Downward API - -The following information is available to containers through environment -variables and `downwardAPI` volumes: - -* Information available via `fieldRef`: - - * `metadata.name` - the pod's name - * `metadata.namespace` - the pod's namespace - * `metadata.uid` - the pod's UID - * `metadata.labels['']` - the value of the pod's label `` - (for example, `metadata.labels['mylabel']`) - * `metadata.annotations['']` - the value of the pod's annotation `` - (for example, `metadata.annotations['myannotation']`) - -* Information available via `resourceFieldRef`: - - * A Container's CPU limit - * A Container's CPU request - * A Container's memory limit - * A Container's memory request - * A Container's hugepages limit (provided that the `DownwardAPIHugePages` - [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled) - * A Container's hugepages request (provided that the `DownwardAPIHugePages` - [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled) - * A Container's ephemeral-storage limit - * A Container's ephemeral-storage request - -In addition, the following information is available through -`downwardAPI` volume `fieldRef`: - -* `metadata.labels` - all of the pod's labels, formatted as `label-key="escaped-label-value"` - with one label per line -* `metadata.annotations` - all of the pod's annotations, formatted as - `annotation-key="escaped-annotation-value"` with one annotation per line - -The following information is available through environment variables: - -* `status.podIP` - the pod's IP address -* `spec.serviceAccountName` - the pod's service account name -* `spec.nodeName` - the name of the node to which the scheduler always attempts to - schedule the pod -* `status.hostIP` - the IP of the node to which the Pod is assigned - -{{< note >}} -If CPU and memory limits are not specified for a Container, the -Downward API defaults to the node allocatable value for CPU and memory. -{{< /note >}} - ## Project keys to specific paths and file permissions You can project keys to specific paths and specific permissions on a per-file basis. For more information, see [Secrets](/docs/concepts/configuration/secret/). -## Motivation for the Downward API - -It is sometimes useful for a container to have information about itself, without -being overly coupled to Kubernetes. The Downward API allows containers to consume -information about themselves or the cluster without using the Kubernetes client -or API server. - -An example is an existing application that assumes a particular well-known -environment variable holds a unique identifier. One possibility is to wrap the -application, but that is tedious and error prone, and it violates the goal of low -coupling. A better option would be to use the Pod's name as an identifier, and -inject the Pod's name into the well-known environment variable. - ## {{% heading "whatsnext" %}} -* Check the [`PodSpec`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core) - API definition which defines the desired state of a Pod. +* Read the [`spec`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec) + API definition for Pod. This includes the definition of Container (part of Pod). +* Read the list of [available fields](/docs/concepts/workloads/pods/downward-api/#available-fields) that you + can expose using the downward API. + +Read about volumes in the legacy API reference: * Check the [`Volume`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core) API definition which defines a generic volume in a Pod for containers to access. * Check the [`DownwardAPIVolumeSource`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumesource-v1-core) @@ -271,4 +217,3 @@ inject the Pod's name into the well-known environment variable. populating a file in the Downward API volume. * Check the [`ResourceFieldSelector`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcefieldselector-v1-core) API definition which specifies the container resources and their output format. - diff --git a/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md b/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md index 2b59921c6e..163b3498dc 100644 --- a/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md +++ b/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md @@ -7,50 +7,40 @@ weight: 30 This page shows how a Pod can use environment variables to expose information -about itself to Containers running in the Pod. Environment variables can expose -Pod fields and Container fields. +about itself to containers running in the Pod, using the _downward API_. +You can use environment variables to expose Pod fields, container fields, or both. +In Kubernetes, there are two ways to expose Pod and container fields to a running container: +* _Environment variables_, as explained in this task +* [Volume files](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) +Together, these two ways of exposing Pod and container fields are called the +downward API. ## {{% heading "prerequisites" %}} - -{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - - - +{{< include "task-tutorial-prereqs.md" >}} -## The Downward API - -There are two ways to expose Pod and Container fields to a running Container: - -* Environment variables -* [Volume Files](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#the-downward-api) - -Together, these two ways of exposing Pod and Container fields are called the -*Downward API*. - - ## Use Pod fields as values for environment variables -In this exercise, you create a Pod that has one Container. Here is the -configuration file for the Pod: +In this part of exercise, you create a Pod that has one container, and you +project Pod-level fields into the running container as environment variables. {{< codenew file="pods/inject/dapi-envars-pod.yaml" >}} -In the configuration file, you can see five environment variables. The `env` +In that manifest, you can see five environment variables. The `env` field is an array of -[EnvVars](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvar-v1-core). +environment variable definitions. The first element in the array specifies that the `MY_NODE_NAME` environment variable gets its value from the Pod's `spec.nodeName` field. Similarly, the other environment variables get their names from Pod fields. {{< note >}} The fields in this example are Pod fields. They are not fields of the -Container in the Pod. +container in the Pod. {{< /note >}} Create the Pod: @@ -59,13 +49,14 @@ Create the Pod: kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-pod.yaml ``` -Verify that the Container in the Pod is running: +Verify that the container in the Pod is running: ```shell +# If the new Pod isn't yet healthy, rerun this command a few times. kubectl get pods ``` -View the Container's logs: +View the container's logs: ```shell kubectl logs dapi-envars-fieldref @@ -82,10 +73,10 @@ default ``` To see why these values are in the log, look at the `command` and `args` fields -in the configuration file. When the Container starts, it writes the values of +in the configuration file. When the container starts, it writes the values of five environment variables to stdout. It repeats this every ten seconds. -Next, get a shell into the Container that is running in your Pod: +Next, get a shell into the container that is running in your Pod: ```shell kubectl exec -it dapi-envars-fieldref -- sh @@ -94,7 +85,8 @@ kubectl exec -it dapi-envars-fieldref -- sh In your shell, view the environment variables: ```shell -/# printenv +# Run this in a shell inside the container +printenv ``` The output shows that certain environment variables have been assigned the @@ -111,22 +103,26 @@ MY_NODE_NAME=minikube MY_POD_NAME=dapi-envars-fieldref ``` -## Use Container fields as values for environment variables +## Use container fields as values for environment variables -In the preceding exercise, you used Pod fields as the values for environment -variables. In this next exercise, you use Container fields as the values for -environment variables. Here is the configuration file for a Pod that has one -container: +In the preceding exercise, you used information from Pod-level fields as the values +for environment variables. +In this next exercise, you are going to pass fields that are part of the Pod +definition, but taken from the specific +[container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container) +rather than from the Pod overall. + +Here is a manifest for another Pod that again has just one container: {{< codenew file="pods/inject/dapi-envars-container.yaml" >}} -In the configuration file, you can see four environment variables. The `env` +In this manifest, you can see four environment variables. The `env` field is an array of -[EnvVars](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvar-v1-core). +environment variable definitions. The first element in the array specifies that the `MY_CPU_REQUEST` environment -variable gets its value from the `requests.cpu` field of a Container named +variable gets its value from the `requests.cpu` field of a container named `test-container`. Similarly, the other environment variables get their values -from Container fields. +from fields that are specific to this container. Create the Pod: @@ -134,13 +130,14 @@ Create the Pod: kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml ``` -Verify that the Container in the Pod is running: +Verify that the container in the Pod is running: ```shell +# If the new Pod isn't yet healthy, rerun this command a few times. kubectl get pods ``` -View the Container's logs: +View the container's logs: ```shell kubectl logs dapi-envars-resourcefieldref @@ -155,18 +152,20 @@ The output shows the values of selected environment variables: 67108864 ``` - - ## {{% heading "whatsnext" %}} -* [Defining Environment Variables for a Container](/docs/tasks/inject-data-application/define-environment-variable-container/) +* Read [Defining Environment Variables for a Container](/docs/tasks/inject-data-application/define-environment-variable-container/) +* Read the [`spec`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec) + API definition for Pod. This includes the definition of Container (part of Pod). +* Read the list of [available fields](/docs/concepts/workloads/pods/downward-api/#available-fields) that you + can expose using the downward API. + +Read about Pods, containers and environment variables in the legacy API reference: + * [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core) * [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) * [EnvVar](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvar-v1-core) * [EnvVarSource](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvarsource-v1-core) * [ObjectFieldSelector](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#objectfieldselector-v1-core) * [ResourceFieldSelector](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcefieldselector-v1-core) - - -