Document examples of downward API exposing container resources via

environment variables and volumes.
This commit is contained in:
Avesh Agarwal 2016-06-01 16:15:50 -04:00
parent ee396b4439
commit d45e0ce4df
5 changed files with 194 additions and 11 deletions

View File

@ -1,5 +1,5 @@
Following this example, you will create a pod with a container that consumes the pod's name and
namespace using the [downward API](http://kubernetes.io/docs/user-guide/downward-api/).
Following these examples, you will create a pod with a container that consumes the pod's name,
namespace, and resource values using the [downward API](http://kubernetes.io/docs/user-guide/downward-api/).
## Step Zero: Prerequisites
@ -29,4 +29,25 @@ $ kubectl logs dapi-test-pod | grep POD_
2015-04-30T20:22:18.568024817Z MY_POD_NAME=dapi-test-pod
2015-04-30T20:22:18.568087688Z MY_POD_NAMESPACE=default
2015-04-30T20:22:18.568092435Z MY_POD_IP=10.0.1.6
```
```
## Example of environment variables with container resources
Use the [`dapi-container-resources.yaml`](dapi-container-resources.yaml) file to create a Pod
with a container that consumes the downward API exposing the container's resources.
```shell
$ kubectl create -f docs/user-guide/downward-api/dapi-container-resources.yaml
```
### Examine the logs
Grep through the pod logs to see that the pod was injected with the correct values:
```shell
$ kubectl logs dapi-test-pod | grep MY_
MY_MEM_LIMIT=67108864
MY_CPU_LIMIT=1
MY_MEM_REQUEST=33554432
MY_CPU_REQUEST=1
```

View File

@ -0,0 +1,34 @@
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox:1.24
command: [ "/bin/sh", "-c", "env" ]
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
restartPolicy: Never

View File

@ -21,6 +21,10 @@ The following information is available to a `Pod` through the downward API:
* The pod's name
* The pod's namespace
* The pod's IP
* A container's cpu limit
* A container's cpu request
* A container's memory limit
* A container's memory request
More information will be exposed through this same API over time.
@ -31,13 +35,15 @@ Containers consume information from the downward API using environment
variables or using a volume plugin.
### Environment variables
## Environment variables
Most environment variables in the Kubernetes API use the `value` field to carry
simple values. However, the alternate `valueFrom` field allows you to specify
a `fieldRef` to select fields from the pod's definition. The `fieldRef` field
is a structure that has an `apiVersion` field and a `fieldPath` field. The
`fieldPath` field is an expression designating a field of the pod. The
a `fieldRef` to select fields from the pod's definition, and a `resourceFieldRef`
to select fields from one of its container's definition.
The `fieldRef` field is a structure that has an `apiVersion` field and a `fieldPath`
field. The `fieldPath` field is an expression designating a field of the pod. The
`apiVersion` field is the version of the API schema that the `fieldPath` is
written in terms of. If the `apiVersion` field is not specified it is
defaulted to the API version of the enclosing object.
@ -46,20 +52,39 @@ The `fieldRef` is evaluated and the resulting value is used as the value for
the environment variable. This allows users to publish their pod's name in any
environment variable they want.
The `resourceFieldRef` is a structure that has a `containerName` field, a `resource`
field, and a `divisor` field. The `containerName` is the name of a container,
whose resource (cpu or memory) information is to be exposed. The `containerName` is
optional for environment variables and defaults to the current container. The
`resource` field is an expression designating a resource in a container, and the `divisor`
field specifies an output format of the resource being exposed. If the `divisor`
is not specified, it defaults to "1" for cpu and memory. The table shows possible
values for cpu and memory resources for `resource` and `divisor` settings:
## Example
| Setting | Cpu | Memory |
| ------------- |-------------| -----|
| resource | limits.cpu, requests.cpu| limits.memory, requests.memory|
| divisor | 1(cores), 1m(millicores) | 1(bytes), 1k(kilobytes), 1M(megabytes), 1G(gigabytes), 1T(terabytes), 1P(petabytes), 1E(exabytes), 1Ki(kibibyte), 1Mi(mebibyte), 1Gi(gibibyte), 1Ti(tebibyte), 1Pi(pebibyte), 1Ei(exbibyte)|
### Example
This is an example of a pod that consumes its name and namespace via the
downward API:
{% include code.html language="yaml" file="dapi-pod.yaml" ghlink="/docs/user-guide/downward-api/dapi-pod.yaml" %}
This is an example of a pod that consumes its container's resources via the downward API:
### Downward API volume
{% include code.html language="yaml" file="dapi-container-resources.yaml" ghlink="/docs/user-guide/downward-api/dapi-container-resources.yaml" %}
## Downward API volume
Using a similar syntax it's possible to expose pod information to containers using plain text files.
Downward API are dumped to a mounted volume. This is achieved using a `downwardAPI`
volume type and the different items represent the files to be created. `fieldPath` references the field to be exposed.
For exposing a container's resources limits and requests, `containerName` must be specified with `resourceFieldRef`.
Downward API volume permits to store more complex data like [`metadata.labels`](/docs/user-guide/labels) and [`metadata.annotations`](/docs/user-guide/annotations). Currently key/value pair set fields are saved using `key="value"` format:
@ -76,19 +101,30 @@ Downward API volumes can expose:
* The pod's namespace
* The pod's labels
* The pod's annotations
* A container's cpu limit
* A container's cpu request
* A container's memory limit
* A container's memory request
The downward API volume refreshes its data in step with the kubelet refresh loop. When labels will be modifiable on the fly without respawning the pod containers will be able to detect changes through mechanisms such as [inotify](https://en.wikipedia.org/wiki/Inotify).
In future, it will be possible to specify a specific annotation or label.
## Example
### Example
This is an example of a pod that consumes its labels and annotations via the downward API volume, labels and annotations are dumped in `/etc/labels` and in `/etc/annotations`, respectively:
{% include code.html language="yaml" file="volume/dapi-volume.yaml" ghlink="/docs/user-guide/downward-api/volume/dapi-volume.yaml" %}
This is an example of a pod that consumes its container's resources via the downward API volume.
{% include code.html language="yaml" file="volume/dapi-volume-resources.yaml" ghlink="/docs/user-guide/downward-api/volume/dapi-volume-resources.yaml" %}
Some more thorough examples:
* [environment variables](/docs/user-guide/environment-guide/)
* [downward API](/docs/user-guide/downward-api/)
## Default values for container resource limits
If cpu and memory limits are not specified for a container, the downward API will default to node's cpu and memory capacities.

View File

@ -0,0 +1,40 @@
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
spec:
containers:
- name: client-container
image: gcr.io/google_containers/busybox:1.24
command: ["sh", "-c", "while true; do echo; if [[ -e /etc/cpu_limit ]]; then cat /etc/cpu_limit; fi; if [[ -e /etc/cpu_request ]]; then cat /etc/cpu_request; fi; if [[ -e /etc/mem_limit ]]; then cat /etc/mem_limit; fi; if [[ -e /etc/mem_request ]]; then cat /etc/mem_request; fi; sleep 5; done"]
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory

View File

@ -2,7 +2,7 @@
---
Following this example, you will create a pod with a downward API volume.
A downward API volume is a k8s volume plugin with the ability to save some pod information in a plain text file. The pod information can be for example some [metadata](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#metadata).
A downward API volume is a k8s volume plugin with the ability to save some pod information in a plain text file. The pod information can be for example some [metadata](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md#metadata) or a container's [resources](/docs/user-guide/compute-resources).
Supported metadata fields:
@ -11,6 +11,13 @@ Supported metadata fields:
3. `metadata.name`
4. `metadata.labels`
Supported container's resources:
1. `limits.cpu`
2. `limits.memory`
3. `requests.cpu`
4. `requests.memory`
### Step Zero: Prerequisites
This example assumes you have a Kubernetes cluster installed and running, and the `kubectl` command line tool somewhere in your path. Please see the [gettingstarted](/docs/getting-started-guides/) for installation instructions for your platform.
@ -64,3 +71,48 @@ drwxrwxrwt 3 0 0 120 Jun 1 19:55 ..
```
The file `labels` is stored in a temporary directory (`..6986_01_06_15_55_10.473583074` in the example above) which is symlinked to by `..data`. Symlinks for annotations and labels in `/etc` point to files containing the actual metadata through the `..data` indirection.  This structure allows for dynamic atomic refresh of the metadata: updates are written to a new temporary directory, and the `..data` symlink is updated atomically using `rename(2)`.
## Example of downward API volume with container resources
Use the `docs/user-guide/downward-api/volume/dapi-volume-resources.yaml` file to create a Pod with a downward API volume which stores its container's limits and requests in /etc.
```shell
$ kubectl create -f docs/user-guide/downward-api/volume/dapi-volume-resources.yaml
```
### Examine pod/container output
In pod's `/etc` directory one may find the files created by the plugin:
```shell
$ kubectl exec kubernetes-downwardapi-volume-example -i -t -- sh
/ # ls -alR /etc
/etc:
total 4
drwxrwxrwt 3 0 0 160 Jun 1 19:47 .
drwxr-xr-x 17 0 0 4096 Jun 1 19:48 ..
drwxr-xr-x 2 0 0 120 Jun 1 19:47 ..6986_01_06_15_47_23.076909525
lrwxrwxrwx 1 0 0 31 Jun 1 19:47 ..data -> ..6986_01_06_15_47_23.076909525
lrwxrwxrwx 1 0 0 16 Jun 1 19:47 cpu_limit -> ..data/cpu_limit
lrwxrwxrwx 1 0 0 18 Jun 1 19:47 cpu_request -> ..data/cpu_request
lrwxrwxrwx 1 0 0 16 Jun 1 19:47 mem_limit -> ..data/mem_limit
lrwxrwxrwx 1 0 0 18 Jun 1 19:47 mem_request -> ..data/mem_request
/etc/..6986_01_06_15_47_23.076909525:
total 16
drwxr-xr-x 2 0 0 120 Jun 1 19:47 .
drwxrwxrwt 3 0 0 160 Jun 1 19:47 ..
-rw-r--r-- 1 0 0 1 Jun 1 19:47 cpu_limit
-rw-r--r-- 1 0 0 1 Jun 1 19:47 cpu_request
-rw-r--r-- 1 0 0 8 Jun 1 19:47 mem_limit
-rw-r--r-- 1 0 0 8 Jun 1 19:47 mem_request
/ # cat /etc/cpu_limit
1
/ # cat /etc/mem_limit
67108864
/ # cat /etc/cpu_request
1
/ # cat /etc/mem_request
33554432
```