Convert site to Hugo (#8316)

This commit converts content and layout to use Hugo.
This commit is contained in:
Bjørn Erik Pedersen
2018-05-05 18:00:51 +02:00
committed by k8s-ci-robot
parent 7745f0e0c5
commit 7f3b633aa0
2327 changed files with 10928 additions and 171503 deletions
+5
View File
@@ -0,0 +1,5 @@
---
title: "Inject Data Into Applications"
weight: 40
---
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: command-demo
labels:
purpose: demonstrate-command
spec:
containers:
- name: command-demo-container
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
@@ -0,0 +1,45 @@
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never
@@ -0,0 +1,38 @@
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
@@ -0,0 +1,54 @@
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox:1.24
command: ["sh", "-c"]
args:
- while true; do
echo -en '\n';
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/podinfo/cpu_request ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/podinfo/mem_limit ]]; then
echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/podinfo/mem_request ]]; then
echo -en '\n'; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
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
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
@@ -0,0 +1,142 @@
---
title: Define a Command and Arguments for a Container
content_template: templates/task
---
{{% capture overview %}}
This page shows how to define commands and arguments when you run a container
in a {{< glossary_tooltip term_id="pod" >}}.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Define a command and arguments when you create a Pod
When you create a Pod, you can define a command and arguments for the
containers that run in the Pod. To define a command, include the `command`
field in the configuration file. To define arguments for the command, include
the `args` field in the configuration file. The command and arguments that
you define cannot be changed after the Pod is created.
The command and arguments that you define in the configuration file
override the default command and arguments provided by the container image.
If you define args, but do not define a command, the default command is used
with your new arguments.
In this exercise, you create a Pod that runs one container. The configuration
file for the Pod defines a command and two arguments:
{{< code file="commands.yaml" >}}
1. Create a Pod based on the YAML configuration file:
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/commands.yaml
1. List the running Pods:
kubectl get pods
The output shows that the container that ran in the command-demo Pod has
completed.
1. To see the output of the command that ran in the container, view the logs
from the Pod:
kubectl logs command-demo
The output shows the values of the HOSTNAME and KUBERNETES_PORT environment
variables:
command-demo
tcp://10.3.240.1:443
## Use environment variables to define arguments
In the preceding example, you defined the arguments directly by
providing strings. As an alternative to providing strings directly,
you can define arguments by using environment variables:
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
This means you can define an argument for a Pod using any of
the techniques available for defining environment variables, including
[ConfigMaps](/docs/tasks/configure-pod-container/configure-pod-configmap/)
and
[Secrets](/docs/concepts/configuration/secret/).
{{< note >}}
**Note:** The environment variable appears in parentheses, `"$(VAR)"`. This is
required for the variable to be expanded in the `command` or `args` field.
{{< /note >}}
## Run a command in a shell
In some cases, you need your command to run in a shell. For example, your
command might consist of several commands piped together, or it might be a shell
script. To run your command in a shell, wrap it like this:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
## Notes
This table summarizes the field names used by Docker and Kubernetes.
| Description | Docker field name | Kubernetes field name |
|----------------------------------------|------------------------|-----------------------|
| The command run by the container | Entrypoint | command |
| The arguments passed to the command | Cmd | args |
When you override the default Entrypoint and Cmd, these rules apply:
* If you do not supply `command` or `args` for a Container, the defaults defined
in the Docker image are used.
* If you supply a `command` but no `args` for a Container, only the supplied
`command` is used. The default EntryPoint and the default Cmd defined in the Docker
image are ignored.
* If you supply only `args` for a Container, the default Entrypoint defined in
the Docker image is run with the `args` that you supplied.
* If you supply a `command` and `args`, the default Entrypoint and the default
Cmd defined in the Docker image are ignored. Your `command` is run with your
`args`.
Here are some examples:
| Image Entrypoint | Image Cmd | Container command | Container args | Command run |
|--------------------|------------------|---------------------|--------------------|------------------|
| `[/ep-1]` | `[foo bar]` | &lt;not set&gt; | &lt;not set&gt; | `[ep-1 foo bar]` |
| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | &lt;not set&gt; | `[ep-2]` |
| `[/ep-1]` | `[foo bar]` | &lt;not set&gt; | `[zoo boo]` | `[ep-1 zoo boo]` |
| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | `[zoo boo]` | `[ep-2 zoo boo]` |
{{% /capture %}}
{{% capture whatsnext %}}
* Learn more about [containers and commands](/docs/user-guide/containers/).
* Learn more about [configuring pods and containers](/docs/tasks/).
* Learn more about [running commands in a container](/docs/tasks/debug-application-cluster/get-shell-running-container/).
* See [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core).
{{% /capture %}}
@@ -0,0 +1,84 @@
---
title: Define Environment Variables for a Container
content_template: templates/task
---
{{% capture overview %}}
This page shows how to define environment variables when you run a container
in a Kubernetes Pod.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Define an environment variable for a container
When you create a Pod, you can set environment variables for the containers
that run in the Pod. To set environment variables, include the `env` or
`envFrom` field in the configuration file.
In this exercise, you create a Pod that runs one container. The configuration
file for the Pod defines an environment variable with name `DEMO_GREETING` and
value `"Hello from the environment"`. Here is the configuration file for the
Pod:
{{< code file="envars.yaml" >}}
1. Create a Pod based on the YAML configuration file:
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/envars.yaml
1. List the running Pods:
kubectl get pods -l purpose=demonstrate-envars
The output is similar to this:
NAME READY STATUS RESTARTS AGE
envar-demo 1/1 Running 0 9s
1. Get a shell to the container running in your Pod:
kubectl exec -it envar-demo -- /bin/bash
1. In your shell, run the `printenv` command to list the environment variables.
root@envar-demo:/# printenv
The output is similar to this:
NODE_VERSION=4.4.2
EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237
HOSTNAME=envar-demo
...
DEMO_GREETING=Hello from the environment
DEMO_FAREWELL=Such a sweet sorrow
1. To exit the shell, enter `exit`.
{{< note >}}
**Note:** The environment variables set using the `env` or `envFrom` field
will override any environment variables specified in the container image.
{{< /note >}}
{{% /capture %}}
{{% capture whatsnext %}}
* Learn more about [environment variables](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/).
* Learn about [using secrets as environment variables](/docs/user-guide/secrets/#using-secrets-as-environment-variables).
* See [EnvVarSource](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvarsource-v1-core).
{{% /capture %}}
@@ -0,0 +1,174 @@
---
title: Distribute Credentials Securely Using Secrets
content_template: templates/task
---
{{% capture overview %}}
This page shows how to securely inject sensitive data, such as passwords and
encryption keys, into Pods.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Convert your secret data to a base-64 representation
Suppose you want to have two pieces of secret data: a username `my-app` and a password
`39528$vdg7Jb`. First, use [Base64 encoding](https://www.base64encode.org/) to
convert your username and password to a base-64 representation. Here's a Linux
example:
echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64
The output shows that the base-64 representation of your username is `bXktYXBw`,
and the base-64 representation of your password is `Mzk1MjgkdmRnN0pi`.
## Create a Secret
Here is a configuration file you can use to create a Secret that holds your
username and password:
{{< code file="secret.yaml" >}}
1. Create the Secret
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret.yaml
{{< note >}}
**Note:** If you want to skip the Base64 encoding step, you can create a Secret
by using the `kubectl create secret` command:
{{< /note >}}
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
1. View information about the Secret:
kubectl get secret test-secret
Output:
NAME TYPE DATA AGE
test-secret Opaque 2 1m
1. View more detailed information about the Secret:
kubectl describe secret test-secret
Output:
Name: test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 13 bytes
username: 7 bytes
## Create a Pod that has access to the secret data through a Volume
Here is a configuration file you can use to create a Pod:
{{< code file="secret-pod.yaml" >}}
1. Create the Pod:
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-pod.yaml
1. Verify that your Pod is running:
kubectl get pod secret-test-pod
Output:
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 42m
1. Get a shell into the Container that is running in your Pod:
kubectl exec -it secret-test-pod -- /bin/bash
1. The secret data is exposed to the Container through a Volume mounted under
`/etc/secret-volume`. In your shell, go to the directory where the secret data
is exposed:
root@secret-test-pod:/# cd /etc/secret-volume
1. In your shell, list the files in the `/etc/secret-volume` directory:
root@secret-test-pod:/etc/secret-volume# ls
The output shows two files, one for each piece of secret data:
password username
1. In your shell, display the contents of the `username` and `password` files:
root@secret-test-pod:/etc/secret-volume# cat username; echo; cat password; echo
The output is your username and password:
my-app
39528$vdg7Jb
## Create a Pod that has access to the secret data through environment variables
Here is a configuration file you can use to create a Pod:
{{< code file="secret-envars-pod.yaml" >}}
1. Create the Pod:
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-envars-pod.yaml
1. Verify that your Pod is running:
kubectl get pod secret-envars-test-pod
Output:
NAME READY STATUS RESTARTS AGE
secret-envars-test-pod 1/1 Running 0 4m
1. Get a shell into the Container that is running in your Pod:
kubectl exec -it secret-envars-test-pod -- /bin/bash
1. In your shell, display the environment variables:
root@secret-envars-test-pod:/# printenv
The output includes your username and password:
...
SECRET_USERNAME=my-app
...
SECRET_PASSWORD=39528$vdg7Jb
{{% /capture %}}
{{% capture whatsnext %}}
* Learn more about [Secrets](/docs/concepts/configuration/secret/).
* Learn about [Volumes](/docs/concepts/storage/volumes/).
### Reference
* [Secret](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#secret-v1-core)
* [Volume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core)
* [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)
{{% /capture %}}
@@ -0,0 +1,259 @@
---
title: Expose Pod Information to Containers Through Files
content_template: templates/task
---
{{% capture overview %}}
This page shows how a Pod can use a DownwardAPIVolumeFile to expose information
about itself to Containers running in the Pod. A DownwardAPIVolumeFile can expose
Pod fields and Container fields.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## The Downward API
There are two ways to expose Pod and Container fields to a running Container:
* [Environment variables](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/)
* DownwardAPIVolumeFiles
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:
{{< code file="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`.
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).
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`
field should be stored in a file named `annotations`.
{{< note >}}
**Note:** The fields in this example are Pod fields. They are not
fields of the Container in the Pod.
{{< /note >}}
Create the Pod:
```shell
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/dapi-volume.yaml
```
Verify that Container in the Pod is running:
```shell
kubectl get pods
```
View the Container's logs:
```shell
kubectl logs kubernetes-downwardapi-volume-example
```
The output shows the contents of the `labels` file and the `annotations` file:
```shell
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
```
Get a shell into the Container that is running in your Pod:
```
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
```
In your shell, view the `labels` file:
```shell
/# cat /etc/podinfo/labels
```
The output shows that all of the Pod's labels have been written
to the `labels` file:
```shell
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
```
Similarly, view the `annotations` file:
```shell
/# cat /etc/podinfo/annotations
```
View the files in the `/etc/podinfo` directory:
```shell
/# ls -laR /etc/podinfo
```
In the output, you can see that the `labels` and `annotations` files
are in a temporary subdirectory: in this example,
`..2982_06_02_21_47_53.299460680`. In the `/etc/podinfo` directory, `..data` is
a symbolic link to the temporary subdirectory. Also in the `/etc/podinfo` directory,
`labels` and `annotations` are symbolic links.
```
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
```
Using symbolic links enables dynamic atomic refresh of the metadata; updates are
written to a new temporary directory, and the `..data` symlink is updated
atomically using
[rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html).
{{< note >}}
**Note:** A container using Downward API as a
[subPath](/docs/concepts/storage/volumes/#using-subpath) volume mount will not
receive Downward API updates.
{{< /note >}}
Exit the shell:
```shell
/# exit
```
## Store Container fields
The preceding exercise, you stored Pod fields in a DownwardAPIVolumeFile.
In this next exercise, you store Container fields. Here is the configuration
file for a Pod that has one Container:
{{< code file="dapi-volume-resources.yaml" >}}
In the configuration file, 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.
The first element specifies that in the Container named `client-container`,
the value of the `limits.cpu` field
should be stored in a file named `cpu_limit`.
Create the Pod:
```shell
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/dapi-volume-resources.yaml
```
Get a shell into the Container that is running in your Pod:
```
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
```
In your shell, view the `cpu_limit` file:
```shell
/# cat /etc/podinfo/cpu_limit
```
You can use similar commands to view the `cpu_request`, `mem_limit` and
`mem_request` files.
{{% /capture %}}
{{% capture discussion %}}
## Capabilities of the Downward API
The following information is available to containers through environment
variables and `downwardAPI` volumes:
* Information available via `fieldRef`:
* `spec.nodeName` - the nodes name
* `status.hostIP` - the node's IP
* `metadata.name` - the pods name
* `metadata.namespace` - the pods namespace
* `status.podIP` - the pods IP address
* `spec.serviceAccountName` - the pods service account name
* `metadata.uid` - the pods UID
* `metadata.labels['<KEY>']` - the value of the pods label `<KEY>` (for example, `metadata.labels['mylabel']`); available in Kubernetes 1.9+
* `metadata.annotations['<KEY>']` - the value of the pods annotation `<KEY>` (for example, `metadata.annotations['myannotation']`); available in Kubernetes 1.9+
* Information available via `resourceFieldRef`:
* A Containers CPU limit
* A Containers CPU request
* A Containers memory limit
* A Containers memory request
In addition, the following information is available through
`downwardAPI` volume `fieldRef`:
* `metadata.labels` - all of the pods labels, formatted as `label-key="escaped-label-value"` with one label per line
* `metadata.annotations` - all of the pods annotations, formatted as `annotation-key="escaped-annotation-value"` with one annotation per line
{{< note >}}
**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.
{{% /capture %}}
{{% capture whatsnext %}}
* [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)
* [Volume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core)
* [DownwardAPIVolumeSource](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumesource-v1-core)
* [DownwardAPIVolumeFile](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core)
* [ResourceFieldSelector](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcefieldselector-v1-core)
{{% /capture %}}
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
@@ -0,0 +1,172 @@
---
title: Expose Pod Information to Containers Through Environment Variables
content_template: templates/task
---
{{% capture overview %}}
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.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## The Downward API
There are two ways to expose Pod and Container fields to a running Container:
* Environment variables
* [DownwardAPIVolumeFiles](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core)
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:
{{< code file="dapi-envars-pod.yaml" >}}
In the configuration file, you can see five environment variables. The `env`
field is an array of
[EnvVars](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvar-v1-core).
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 >}}
**Note:** The fields in this example are Pod fields. They are not fields of the
Container in the Pod.
{{< /note >}}
Create the Pod:
```shell
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/dapi-envars-pod.yaml
```
Verify that the Container in the Pod is running:
```
kubectl get pods
```
View the Container's logs:
```
kubectl logs dapi-envars-fieldref
```
The output shows the values of selected environment variables:
```
minikube
dapi-envars-fieldref
default
172.17.0.4
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
five environment variables to stdout. It repeats this every ten seconds.
Next, get a shell into the Container that is running in your Pod:
```
kubectl exec -it dapi-envars-fieldref -- sh
```
In your shell, view the environment variables:
```
/# printenv
```
The output shows that certain environment variables have been assigned the
values of Pod fields:
```
MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref
```
## 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:
{{< code file="dapi-envars-container.yaml" >}}
In the configuration file, you can see four environment variables. The `env`
field is an array of
[EnvVars](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#envvar-v1-core).
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
`test-container`. Similarly, the other environment variables get their values
from Container fields.
Create the Pod:
```shell
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/dapi-envars-container.yaml
```
Verify that the Container in the Pod is running:
```
kubectl get pods
```
View the Container's logs:
```
kubectl logs dapi-envars-resourcefieldref
```
The output shows the values of selected environment variables:
```
1
1
33554432
67108864
```
{{% /capture %}}
{{% capture whatsnext %}}
* [Defining Environment Variables for a Container](/docs/tasks/inject-data-application/define-environment-variable-container/)
* [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)
{{% /capture %}}
@@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/app/config.json
readOnly: true
name: secret-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
- name: duplicate_key
value: FROM_ENV
- name: expansion
value: $(REPLACE_ME)
envFrom:
- configMapRef:
name: etcd-env-config
volumes:
- name: cache-volume
emptyDir: {}
- name: secret-volume
secret:
secretName: config-details
@@ -0,0 +1,30 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
- name: duplicate_key
value: FROM_ENV
- name: expansion
value: $(REPLACE_ME)
envFrom:
- configMapRef:
name: etcd-env-config
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/app/config.json
readOnly: true
name: secret-volume
volumes:
- name: cache-volume
emptyDir: {}
- name: secret-volume
secret:
secretName: config-details
@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: etcd-env-config
data:
number_of_members: "1"
initial_cluster_state: new
initial_cluster_token: DUMMY_ETCD_INITIAL_CLUSTER_TOKEN
discovery_token: DUMMY_ETCD_DISCOVERY_TOKEN
discovery_url: http://etcd_discovery:2379
etcdctl_peers: http://etcd:2379
duplicate_key: FROM_CONFIG_MAP
REPLACE_ME: "a value"
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
ports:
- containerPort: 80
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,18 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: other-volume
volumes:
- name: other-volume
emptyDir: {}
@@ -0,0 +1,25 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,29 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
podpreset.admission.kubernetes.io/podpreset-proxy: "resource version"
spec:
containers:
- name: website
image: nginx
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/proxy/configs
name: proxy-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
volumes:
- name: cache-volume
emptyDir: {}
- name: proxy-volume
emptyDir: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: nginx
ports:
- containerPort: 80
@@ -0,0 +1,17 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,14 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: proxy
spec:
selector:
matchLabels:
role: frontend
volumeMounts:
- mountPath: /etc/proxy/configs
name: proxy-volume
volumes:
- name: proxy-volume
emptyDir: {}
@@ -0,0 +1,31 @@
apiVersion: v1
kind: Pod
metadata:
name: frontend
labels:
app: guestbook
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- mountPath: /cache
name: cache-volume
env:
- name: GET_HOSTS_FROM
value: dns
- name: DB_PORT
value: "6379"
ports:
- containerPort: 80
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,29 @@
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
role: frontend
matchExpressions:
- {key: role, operator: In, values: [frontend]}
template:
metadata:
labels:
app: guestbook
role: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
@@ -0,0 +1,163 @@
---
reviewers:
- jessfraz
title: Inject Information into Pods Using a PodPreset
---
You can use a `podpreset` object to inject information like secrets, volume
mounts, and environment variables etc into pods at creation time.
This task shows some examples on using the `PodPreset` resource.
You can get an overview of PodPresets at
[Understanding Pod Presets](/docs/concepts/workloads/pods/podpreset/).
{{< toc >}}
## Create a Pod Preset
### Simple Pod Spec Example
This is a simple example to show how a Pod spec is modified by the Pod
Preset.
{{< code file="podpreset-preset.yaml" >}}
Create the PodPreset:
```shell
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/podpreset-preset.yaml
```
Examine the created PodPreset:
```shell
$ kubectl get podpreset
NAME AGE
allow-database 1m
```
The new PodPreset will act upon any pod that has label `role: frontend`.
{{< code file="podpreset-pod.yaml" >}}
Create a pod:
```shell
$ kubectl create -f https://k8s.io/docs/tasks/inject-data-application/podpreset-pod.yaml
```
List the running Pods:
```shell
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
website 1/1 Running 0 4m
```
**Pod spec after admission controller:**
{{< code file="podpreset-merged.yaml" >}}
To see above output, run the following command:
```shell
$ kubectl get pod website -o yaml
```
### Pod Spec with `ConfigMap` Example
This is an example to show how a Pod spec is modified by the Pod Preset
that defines a `ConfigMap` for Environment Variables.
**User submitted pod spec:**
{{< code file="podpreset-pod.yaml" >}}
**User submitted `ConfigMap`:**
{{< code file="podpreset-configmap.yaml" >}}
**Example Pod Preset:**
{{< code file="podpreset-allow-db.yaml" >}}
**Pod spec after admission controller:**
{{< code file="podpreset-allow-db-merged.yaml" >}}
### ReplicaSet with Pod Spec Example
The following example shows that only the pod spec is modified by the Pod
Preset.
**User submitted ReplicaSet:**
{{< code file="podpreset-replicaset.yaml" >}}
**Example Pod Preset:**
{{< code file="podpreset-preset.yaml" >}}
**Pod spec after admission controller:**
Note that the ReplicaSet spec was not changed, users have to check individual pods
to validate that the PodPreset has been applied.
{{< code file="podpreset-replicaset-merged.yaml" >}}
### Multiple PodPreset Example
This is an example to show how a Pod spec is modified by multiple Pod
Injection Policies.
**User submitted pod spec:**
{{< code file="podpreset-pod.yaml" >}}
**Example Pod Preset:**
{{< code file="podpreset-preset.yaml" >}}
**Another Pod Preset:**
{{< code file="podpreset-proxy.yaml" >}}
**Pod spec after admission controller:**
{{< code file="podpreset-multi-merged.yaml" >}}
### Conflict Example
This is an example to show how a Pod spec is not modified by the Pod Preset
when there is a conflict.
**User submitted pod spec:**
{{< code file="podpreset-conflict-pod.yaml" >}}
**Example Pod Preset:**
{{< code file="podpreset-conflict-preset.yaml" >}}
**Pod spec after admission controller will not change because of the conflict:**
{{< code file="podpreset-conflict-pod.yaml" >}}
**If we run `kubectl describe...` we can see the event:**
```shell
$ kubectl describe ...
....
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Feb 2017 16:56:12 -0700 Tue, 07 Feb 2017 16:56:12 -0700 1 {podpreset.admission.kubernetes.io/podpreset-allow-database } conflict Conflict on pod preset. Duplicate mountPath /cache.
```
## Deleting a Pod Preset
Once you don't need a pod preset anymore, you can delete it with `kubectl`:
```shell
$ kubectl delete podpreset allow-database
podpreset "allow-database" deleted
```
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: secret-envars-test-pod
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: test-secret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: test-secret
key: password
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# name must match the volume name below
- name: secret-volume
mountPath: /etc/secret-volume
# The secret data is exposed to Containers in the Pod through a Volume.
volumes:
- name: secret-volume
secret:
secretName: test-secret
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi