This the multi-page printable view of this section. Click here to print.
Inject Data Into Applications
- 1: Define a Command and Arguments for a Container
- 2: Define Dependent Environment Variables
- 3: Define Environment Variables for a Container
- 4: Expose Pod Information to Containers Through Environment Variables
- 5: Expose Pod Information to Containers Through Files
- 6: Distribute Credentials Securely Using Secrets
1 - Define a Command and Arguments for a Container
This page shows how to define commands and arguments when you run a container in a Pod.
Before you begin
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:
To check the version, enterkubectl version
.
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.
Note: Thecommand
field corresponds toentrypoint
in some container runtimes. Refer to the Notes below.
In this exercise, you create a Pod that runs one container. The configuration file for the Pod defines a command and two arguments:
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
-
Create a Pod based on the YAML configuration file:
kubectl apply -f https://k8s.io/examples/pods/commands.yaml
-
List the running Pods:
kubectl get pods
The output shows that the container that ran in the command-demo Pod has completed.
-
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 and Secrets.
Note: The environment variable appears in parentheses,"$(VAR)"
. This is required for the variable to be expanded in thecommand
orargs
field.
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
orargs
for a Container, the defaults defined in the Docker image are used. -
If you supply a
command
but noargs
for a Container, only the suppliedcommand
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 theargs
that you supplied. -
If you supply a
command
andargs
, the default Entrypoint and the default Cmd defined in the Docker image are ignored. Yourcommand
is run with yourargs
.
Here are some examples:
Image Entrypoint | Image Cmd | Container command | Container args | Command run |
---|---|---|---|---|
[/ep-1] |
[foo bar] |
<not set> | <not set> | [ep-1 foo bar] |
[/ep-1] |
[foo bar] |
[/ep-2] |
<not set> | [ep-2] |
[/ep-1] |
[foo bar] |
<not set> | [zoo boo] |
[ep-1 zoo boo] |
[/ep-1] |
[foo bar] |
[/ep-2] |
[zoo boo] |
[ep-2 zoo boo] |
What's next
- Learn more about configuring pods and containers.
- Learn more about running commands in a container.
- See Container.
2 - Define Dependent Environment Variables
This page shows how to define dependent environment variables for a container in a Kubernetes Pod.
Before you begin
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:
Define an environment dependent variable for a container
When you create a Pod, you can set dependent environment variables for the containers that run in the Pod. To set dependent environment variables, you can use $(VAR_NAME) in the value
of env
in the configuration file.
In this exercise, you create a Pod that runs one container. The configuration file for the Pod defines an dependent environment variable with common usage defined. Here is the configuration manifest for the Pod:
apiVersion: v1
kind: Pod
metadata:
name: dependent-envars-demo
spec:
containers:
- name: dependent-envars-demo
args:
- while true; do echo -en '\n'; printf UNCHANGED_REFERENCE=$UNCHANGED_REFERENCE'\n'; printf SERVICE_ADDRESS=$SERVICE_ADDRESS'\n';printf ESCAPED_REFERENCE=$ESCAPED_REFERENCE'\n'; sleep 30; done;
command:
- sh
- -c
image: busybox
env:
- name: SERVICE_PORT
value: "80"
- name: SERVICE_IP
value: "172.17.0.1"
- name: UNCHANGED_REFERENCE
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: PROTOCOL
value: "https"
- name: SERVICE_ADDRESS
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: ESCAPED_REFERENCE
value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
-
Create a Pod based on that manifest:
kubectl apply -f https://k8s.io/examples/pods/inject/dependent-envars.yaml
pod/dependent-envars-demo created
-
List the running Pods:
kubectl get pods dependent-envars-demo
NAME READY STATUS RESTARTS AGE dependent-envars-demo 1/1 Running 0 9s
-
Check the logs for the container running in your Pod:
kubectl logs pod/dependent-envars-demo
UNCHANGED_REFERENCE=$(PROTOCOL)://172.17.0.1:80 SERVICE_ADDRESS=https://172.17.0.1:80 ESCAPED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
As shown above, you have defined the correct dependency reference of SERVICE_ADDRESS
, bad dependency reference of UNCHANGED_REFERENCE
and skip dependent references of ESCAPED_REFERENCE
.
When an environment variable is already defined when being referenced,
the reference can be correctly resolved, such as in the SERVICE_ADDRESS
case.
When the environment variable is undefined or only includes some variables, the undefined environment variable is treated as a normal string, such as UNCHANGED_REFERENCE
. Note that incorrectly parsed environment variables, in general, will not block the container from starting.
The $(VAR_NAME)
syntax can be escaped with a double $
, ie: $$(VAR_NAME)
.
Escaped references are never expanded, regardless of whether the referenced variable
is defined or not. This can be seen from the ESCAPED_REFERENCE
case above.
What's next
- Learn more about environment variables.
- See EnvVarSource.
3 - Define Environment Variables for a Container
This page shows how to define environment variables for a container in a Kubernetes Pod.
Before you begin
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:
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 manifest for the
Pod:
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"
-
Create a Pod based on that manifest:
kubectl apply -f https://k8s.io/examples/pods/inject/envars.yaml
-
List the running Pods:
kubectl get pods -l purpose=demonstrate-envars
The output is similar to:
NAME READY STATUS RESTARTS AGE envar-demo 1/1 Running 0 9s
-
List the Pod's container environment variables:
kubectl exec 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
Note: The environment variables set using theenv
orenvFrom
field override any environment variables specified in the container image.
Note: Environment variables may reference each other, however ordering is important. Variables making use of others defined in the same context must come later in the list. Similarly, avoid circular references.
Using environment variables inside of your config
Environment variables that you define in a Pod's configuration can be used
elsewhere in the configuration, for example in commands and arguments that
you set for the Pod's containers.
In the example configuration below, the GREETING
, HONORIFIC
, and
NAME
environment variables are set to Warm greetings to
, The Most Honorable
, and Kubernetes
, respectively. Those environment variables
are then used in the CLI arguments passed to the env-print-demo
container.
apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: bash
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
command: ["echo"]
args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
Upon creation, the command echo Warm greetings to The Most Honorable Kubernetes
is run on the container.
What's next
- Learn more about environment variables.
- Learn about using secrets as environment variables.
- See EnvVarSource.
4 - Expose Pod Information to Containers Through Environment Variables
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.
Before you begin
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:
To check the version, enterkubectl version
.
The Downward API
There are two ways to expose Pod and Container fields to a running Container:
- Environment variables
- Volume Files
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:
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
In the configuration file, you can see five environment variables. The env
field is an array of
EnvVars.
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.
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:
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:
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
In the configuration file, you can see four environment variables. The env
field is an array of
EnvVars.
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:
kubectl apply -f https://k8s.io/examples/pods/inject/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
What's next
5 - Expose Pod Information to Containers Through Files
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.
Before you begin
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:
To check the version, enterkubectl version
.
The Downward API
There are two ways to expose Pod and Container fields to a running Container:
- Environment variables
- 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:
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
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
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 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: The fields in this example are Pod fields. They are not fields of the Container in the Pod.
Create the Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
Verify that the Container in the Pod is running:
kubectl get pods
View the Container's logs:
kubectl logs kubernetes-downwardapi-volume-example
The output shows the contents of the labels
file and the annotations
file:
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:
/# cat /etc/podinfo/labels
The output shows that all of the Pod's labels have been written
to the labels
file:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
Similarly, view the annotations
file:
/# cat /etc/podinfo/annotations
View the files in the /etc/podinfo
directory:
/# 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).
Note: A container using Downward API as a subPath volume mount will not receive Downward API updates.
Exit the 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:
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
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
divisor: 1m
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
divisor: 1m
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
divisor: 1Mi
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
divisor: 1Mi
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 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.
Create the Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/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:
/# cat /etc/podinfo/cpu_limit
You can use similar commands to view the cpu_request
, mem_limit
and
mem_request
files.
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 namemetadata.namespace
- the pod's namespacemetadata.uid
- the pod's UIDmetadata.labels['<KEY>']
- the value of the pod's label<KEY>
(for example,metadata.labels['mylabel']
)metadata.annotations['<KEY>']
- the value of the pod's annotation<KEY>
(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 (providing that the
DownwardAPIHugePages
feature gate is enabled) - A Container's hugepages request (providing that the
DownwardAPIHugePages
feature gate 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 aslabel-key="escaped-label-value"
with one label per linemetadata.annotations
- all of the pod's annotations, formatted asannotation-key="escaped-annotation-value"
with one annotation per line
The following information is available through environment variables:
status.podIP
- the pod's IP addressspec.serviceAccountName
- the pod's service account name, available since v1.4.0-alpha.3spec.nodeName
- the node's name, available since v1.4.0-alpha.3status.hostIP
- the node's IP, available since v1.7.0-alpha.1
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.
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.
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.
What's next
6 - Distribute Credentials Securely Using Secrets
This page shows how to securely inject sensitive data, such as passwords and encryption keys, into Pods.
Before you begin
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:
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 a base64 encoding tool to convert your username and password to a base64 representation. Here's an example using the commonly available base64 program:
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
.
Caution: Use a local tool trusted by your OS to decrease the security risks of external tools.
Create a Secret
Here is a configuration file you can use to create a Secret that holds your username and password:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
-
Create the Secret
kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
-
View information about the Secret:
kubectl get secret test-secret
Output:
NAME TYPE DATA AGE test-secret Opaque 2 1m
-
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 Secret directly with kubectl
If you want to skip the Base64 encoding step, you can create the
same Secret using the kubectl create secret
command. For example:
kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'
This is more convenient. The detailed approach shown earlier runs through each step explicitly to demonstrate what is happening.
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:
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
-
Create the Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
-
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
-
Get a shell into the Container that is running in your Pod:
kubectl exec -i -t secret-test-pod -- /bin/bash
-
The secret data is exposed to the Container through a Volume mounted under
/etc/secret-volume
.In your shell, list the files in the
/etc/secret-volume
directory:# Run this in the shell inside the container ls /etc/secret-volume
The output shows two files, one for each piece of secret data:
password username
-
In your shell, display the contents of the
username
andpassword
files:# Run this in the shell inside the container echo "$( cat /etc/secret-volume/username )" echo "$( cat /etc/secret-volume/password )"
The output is your username and password:
my-app 39528$vdg7Jb
Define container environment variables using Secret data
Define a container environment variable with data from a single Secret
-
Define an environment variable as a key-value pair in a Secret:
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
-
Assign the
backend-username
value defined in the Secret to theSECRET_USERNAME
environment variable in the Pod specification.apiVersion: v1 kind: Pod metadata: name: env-single-secret spec: containers: - name: envars-test-container image: nginx env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: backend-user key: backend-username
-
Create the Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
-
In your shell, display the content of
SECRET_USERNAME
container environment variablekubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
The output is
backend-admin
Define container environment variables with data from multiple Secrets
-
As with the previous example, create the Secrets first.
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin' kubectl create secret generic db-user --from-literal=db-username='db-admin'
-
Define the environment variables in the Pod specification.
apiVersion: v1 kind: Pod metadata: name: envvars-multiple-secrets spec: containers: - name: envars-test-container image: nginx env: - name: BACKEND_USERNAME valueFrom: secretKeyRef: name: backend-user key: backend-username - name: DB_USERNAME valueFrom: secretKeyRef: name: db-user key: db-username
-
Create the Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
-
In your shell, display the container environment variables
kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
The output is
DB_USERNAME=db-admin BACKEND_USERNAME=backend-admin
Configure all key-value pairs in a Secret as container environment variables
Note: This functionality is available in Kubernetes v1.6 and later.
-
Create a Secret containing multiple key-value pairs
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
-
Use envFrom to define all of the Secret's data as container environment variables. The key from the Secret becomes the environment variable name in the Pod.
apiVersion: v1 kind: Pod metadata: name: envfrom-secret spec: containers: - name: envars-test-container image: nginx envFrom: - secretRef: name: test-secret
-
Create the Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
-
In your shell, display
username
andpassword
container environment variableskubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
The output is
username: my-app password: 39528$vdg7Jb