Move Guide topic: ConfigMap. (#3333)
This commit is contained in:
parent
2e9ceea926
commit
2954d2b337
|
|
@ -29,6 +29,7 @@ toc:
|
|||
- docs/tasks/configure-pod-container/configure-pod-initialization.md
|
||||
- docs/tasks/configure-pod-container/attach-handler-lifecycle-event.md
|
||||
- docs/tasks/configure-pod-container/configure-pod-disruption-budget.md
|
||||
- docs/tasks/configure-pod-container/configmap.md
|
||||
- docs/tasks/configure-pod-container/declare-network-policy.md
|
||||
- docs/tasks/configure-pod-container/calico-network-policy.md
|
||||
- docs/tasks/configure-pod-container/romana-network-policy.md
|
||||
|
|
|
|||
|
|
@ -0,0 +1,624 @@
|
|||
---
|
||||
assignees:
|
||||
- eparis
|
||||
- pmorie
|
||||
title: Configure Containers Using a ConfigMap
|
||||
---
|
||||
|
||||
Many applications require configuration via some combination of config files, command line
|
||||
arguments, and environment variables. These configuration artifacts should be decoupled from image
|
||||
content in order to keep containerized applications portable. The ConfigMap API resource provides
|
||||
mechanisms to inject containers with configuration data while keeping containers agnostic of
|
||||
Kubernetes. ConfigMap can be used to store fine-grained information like individual properties or
|
||||
coarse-grained information like entire config files or JSON blobs.
|
||||
|
||||
|
||||
## Overview of ConfigMap
|
||||
|
||||
The ConfigMap API resource holds key-value pairs of configuration data that can be consumed in pods
|
||||
or used to store configuration data for system components such as controllers. ConfigMap is similar
|
||||
to [Secrets](/docs/user-guide/secrets/), but designed to more conveniently support working with strings that do not
|
||||
contain sensitive information.
|
||||
|
||||
Note: ConfigMaps are not intended to act as a replacement for a properties file. ConfigMaps are intended to act as a reference to multiple properties files. You can think of them as way to represent something similar to the /etc directory, and the files within, on a Linux computer. One example of this model is creating Kubernetes Volumes from ConfigMaps, where each data item in the ConfigMap becomes a new file.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T19:14:38Z
|
||||
name: example-config
|
||||
namespace: default
|
||||
data:
|
||||
example.property.1: hello
|
||||
example.property.2: world
|
||||
example.property.file: |-
|
||||
property.1=value-1
|
||||
property.2=value-2
|
||||
property.3=value-3
|
||||
```
|
||||
|
||||
The `data` field contains the configuration data. As you can see, ConfigMaps can be used to hold
|
||||
fine-grained information like individual properties or coarse-grained information like the contents
|
||||
of configuration files.
|
||||
|
||||
Configuration data can be consumed in pods in a variety of ways. ConfigMaps can be used to:
|
||||
|
||||
1. Populate the values of environment variables
|
||||
2. Set command-line arguments in a container
|
||||
3. Populate config files in a volume
|
||||
|
||||
Both users and system components may store configuration data in ConfigMap.
|
||||
|
||||
## Creating ConfigMaps
|
||||
|
||||
You can use the `kubectl create configmap` command to create configmaps easily from literal values,
|
||||
files, or directories.
|
||||
|
||||
Let's take a look at some different ways to create a ConfigMap:
|
||||
|
||||
### Creating from directories
|
||||
|
||||
Say that we have a directory with some files that already contain the data we want to populate a ConfigMap with:
|
||||
|
||||
```shell
|
||||
$ ls docs/user-guide/configmap/kubectl/
|
||||
game.properties
|
||||
ui.properties
|
||||
|
||||
$ cat docs/user-guide/configmap/kubectl/game.properties
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
|
||||
$ cat docs/user-guide/configmap/kubectl/ui.properties
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
how.nice.to.look=fairlyNice
|
||||
```
|
||||
|
||||
The `kubectl create configmap` command can be used to create a ConfigMap holding the content of each
|
||||
file in this directory:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl
|
||||
```
|
||||
|
||||
When `--from-file` points to a directory, each file directly in that directory is used to populate a
|
||||
key in the ConfigMap, where the name of the key is the filename, and the value of the key is the
|
||||
content of the file.
|
||||
|
||||
Let's take a look at the ConfigMap that this command created:
|
||||
|
||||
```shell
|
||||
$ kubectl describe configmaps game-config
|
||||
Name: game-config
|
||||
Namespace: default
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
|
||||
Data
|
||||
====
|
||||
game.properties: 158 bytes
|
||||
ui.properties: 83 bytes
|
||||
```
|
||||
|
||||
You can see the two keys in the map are created from the filenames in the directory we pointed
|
||||
kubectl to. Since the content of those keys may be large, in the output of `kubectl describe`,
|
||||
you'll see only the names of the keys and their sizes.
|
||||
|
||||
If we want to see the values of the keys, we can simply `kubectl get` the resource:
|
||||
|
||||
```shell
|
||||
$ kubectl get configmaps game-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
game.properties: |
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
ui.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
how.nice.to.look=fairlyNice
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T18:34:05Z
|
||||
name: game-config
|
||||
namespace: default
|
||||
resourceVersion: "407"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/game-config
|
||||
uid: 30944725-d66e-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
### Creating from files
|
||||
|
||||
We can also pass `--from-file` a specific file, and pass it multiple times to kubectl. The
|
||||
following command yields equivalent results to the above example:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties
|
||||
|
||||
$ kubectl get configmaps game-config-2 -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
game.properties: |
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
ui.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
how.nice.to.look=fairlyNice
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T18:52:05Z
|
||||
name: game-config-2
|
||||
namespace: default
|
||||
resourceVersion: "516"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/game-config-2
|
||||
uid: b4952dc3-d670-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
We can also set the key to use for an individual file with `--from-file` by passing an expression
|
||||
of `key=value`: `--from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties`:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap game-config-3 --from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties
|
||||
|
||||
$ kubectl get configmaps game-config-3 -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
game-special-key: |
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T18:54:22Z
|
||||
name: game-config-3
|
||||
namespace: default
|
||||
resourceVersion: "530"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/game-config-3
|
||||
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
### Creating from literal values
|
||||
|
||||
It is also possible to supply literal values for ConfigMaps using `kubectl create configmap`. The
|
||||
`--from-literal` option takes a `key=value` syntax that allows literal values to be supplied
|
||||
directly on the command line:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
|
||||
|
||||
$ kubectl get configmaps special-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T19:14:38Z
|
||||
name: special-config
|
||||
namespace: default
|
||||
resourceVersion: "651"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/special-config
|
||||
uid: dadce046-d673-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
## Consuming ConfigMap in pods
|
||||
|
||||
### Use-Case: Consume ConfigMap in environment variables
|
||||
|
||||
ConfigMaps can be used to populate individual environment variables or be used in
|
||||
its entirety. As an example, consider the following ConfigMaps:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: special-config
|
||||
namespace: default
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: env-config
|
||||
namespace: default
|
||||
data:
|
||||
log_level: INFO
|
||||
```
|
||||
|
||||
We can consume the keys of this ConfigMap in a pod like so:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "env" ]
|
||||
env:
|
||||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.how
|
||||
- name: SPECIAL_TYPE_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.type
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: env-config
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, its output will include the lines:
|
||||
|
||||
```shell
|
||||
SPECIAL_LEVEL_KEY=very
|
||||
SPECIAL_TYPE_KEY=charm
|
||||
log_level=INFO
|
||||
```
|
||||
|
||||
#### Optional ConfigMap in environment variables
|
||||
|
||||
There might be situations where environment variables are not
|
||||
always required. These environment variables can be marked as optional in a
|
||||
pod like so:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "env" ]
|
||||
env:
|
||||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: a-config
|
||||
key: akey
|
||||
optional: true
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be empty.
|
||||
|
||||
### Use-Case: Set command-line arguments with ConfigMap
|
||||
|
||||
ConfigMaps can also be used to set the value of the command or arguments in a container. This is
|
||||
accomplished using the Kubernetes substitution syntax `$(VAR_NAME)`. Consider the ConfigMap:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: special-config
|
||||
namespace: default
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
```
|
||||
|
||||
In order to inject values into the command line, we must consume the keys we want to use as
|
||||
environment variables, as in the last example. Then we can refer to them in a container's command
|
||||
using the `$(VAR_NAME)` syntax.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
|
||||
env:
|
||||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.how
|
||||
- name: SPECIAL_TYPE_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.type
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output from the `test-container` container will be:
|
||||
|
||||
```shell
|
||||
very charm
|
||||
```
|
||||
|
||||
### Use-Case: Consume ConfigMap via volume plugin
|
||||
|
||||
ConfigMaps can also be consumed in volumes. Returning again to our example ConfigMap:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: special-config
|
||||
namespace: default
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
```
|
||||
|
||||
We have a couple different options for consuming this ConfigMap in a volume. The most basic
|
||||
way is to populate the volume with files where the key is the filename and the content of the file
|
||||
is the value of the key:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/config
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: special-config
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be:
|
||||
|
||||
```shell
|
||||
very
|
||||
```
|
||||
|
||||
We can also control the paths within the volume where ConfigMap keys are projected:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ]
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/config
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: special-config
|
||||
items:
|
||||
- key: special.how
|
||||
path: path/to/special-key
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be:
|
||||
|
||||
```shell
|
||||
very
|
||||
```
|
||||
|
||||
#### Projecting keys to specific paths and file permissions
|
||||
|
||||
You can project keys to specific paths and specific permissions on a per-file
|
||||
basis. The [Secrets](/docs/user-guide/secrets/) user guide explains the syntax.
|
||||
|
||||
#### Optional ConfigMap via volume plugin
|
||||
|
||||
Volumes and files provided by a ConfigMap can be also be marked as optional.
|
||||
The ConfigMap or the key specified does not have to exist. The mount path for
|
||||
such items will always be created.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "ls /etc/config" ]
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/config
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: no-config
|
||||
optional: true
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be:
|
||||
|
||||
```shell
|
||||
```
|
||||
|
||||
## Real World Example: Configuring Redis
|
||||
|
||||
Let's take a look at a real-world example: configuring redis using ConfigMap. Say that we want to inject
|
||||
redis with the recommendation configuration for using redis as a cache. The redis config file
|
||||
should contain:
|
||||
|
||||
```conf
|
||||
maxmemory 2mb
|
||||
maxmemory-policy allkeys-lru
|
||||
```
|
||||
|
||||
Such a file is in `docs/user-guide/configmap/redis`; we can use the following command to create a
|
||||
ConfigMap instance with it:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap example-redis-config --from-file=docs/user-guide/configmap/redis/redis-config
|
||||
|
||||
$ kubectl get configmap example-redis-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
redis-config: |
|
||||
maxmemory 2mb
|
||||
maxmemory-policy allkeys-lru
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-03-30T18:14:41Z
|
||||
name: example-redis-config
|
||||
namespace: default
|
||||
resourceVersion: "24686"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
|
||||
uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002
|
||||
```
|
||||
|
||||
Now, let's create a pod that uses this config:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: kubernetes/redis:v1
|
||||
env:
|
||||
- name: MASTER
|
||||
value: "true"
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
resources:
|
||||
limits:
|
||||
cpu: "0.1"
|
||||
volumeMounts:
|
||||
- mountPath: /redis-master-data
|
||||
name: data
|
||||
- mountPath: /redis-master
|
||||
name: config
|
||||
volumes:
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
- name: config
|
||||
configMap:
|
||||
name: example-redis-config
|
||||
items:
|
||||
- key: redis-config
|
||||
path: redis.conf
|
||||
```
|
||||
|
||||
Notice that this pod has a ConfigMap volume that places the `redis-config` key of the
|
||||
`example-redis-config` ConfigMap into a file called `redis.conf`. This volume is mounted into the
|
||||
`/redis-master` directory in the redis container, placing our config file at
|
||||
`/redis-master/redis.conf`, which is where the image looks for the redis config file for the master.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/user-guide/configmap/redis/redis-pod.yaml
|
||||
```
|
||||
|
||||
If we `kubectl exec` into this pod and run the `redis-cli` tool, we can check that our config was
|
||||
applied correctly:
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis redis-cli
|
||||
127.0.0.1:6379> CONFIG GET maxmemory
|
||||
1) "maxmemory"
|
||||
2) "2097152"
|
||||
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
||||
1) "maxmemory-policy"
|
||||
2) "allkeys-lru"
|
||||
```
|
||||
|
||||
## Restrictions
|
||||
|
||||
ConfigMaps must be created before they are consumed in pods unless they are
|
||||
marked as optional. References to ConfigMaps that do not exist will prevent
|
||||
the pod from starting. Controllers may be written to tolerate missing
|
||||
configuration data; consult individual components configured via ConfigMap on
|
||||
a case-by-case basis.
|
||||
|
||||
References via `configMapKeyRef` to keys that do not exist in a named ConfigMap
|
||||
will prevent the pod from starting.
|
||||
|
||||
ConfigMaps used to populate environment variables via `envFrom` that have keys
|
||||
that are considered invalid environment variable names will have those keys
|
||||
skipped. The pod will be allowed to start. There will be an event whose
|
||||
reason is `InvalidVariableNames` and the message will contain the list of
|
||||
invalid keys that were skipped. The example shows a pod which refers to the
|
||||
default/myconfig ConfigMap that contains 2 invalid keys, 1badkey and 2alsobad.
|
||||
|
||||
```shell
|
||||
$ kubectl.sh get events
|
||||
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
|
||||
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
|
||||
```
|
||||
|
||||
ConfigMaps reside in a namespace. They can only be referenced by pods in the same namespace.
|
||||
|
||||
Quota for ConfigMap size is a planned feature.
|
||||
|
||||
Kubelet only supports use of ConfigMap for pods it gets from the API server. This includes every pod
|
||||
created using kubectl, or indirectly via a replication controller. It does not include pods created
|
||||
via the Kubelet's `--manifest-url` flag, its `--config` flag, or its REST API (these are not common
|
||||
ways to create pods.)
|
||||
|
||||
|
|
@ -5,620 +5,6 @@ assignees:
|
|||
title: Using ConfigMap
|
||||
---
|
||||
|
||||
Many applications require configuration via some combination of config files, command line
|
||||
arguments, and environment variables. These configuration artifacts should be decoupled from image
|
||||
content in order to keep containerized applications portable. The ConfigMap API resource provides
|
||||
mechanisms to inject containers with configuration data while keeping containers agnostic of
|
||||
Kubernetes. ConfigMap can be used to store fine-grained information like individual properties or
|
||||
coarse-grained information like entire config files or JSON blobs.
|
||||
|
||||
|
||||
## Overview of ConfigMap
|
||||
|
||||
The ConfigMap API resource holds key-value pairs of configuration data that can be consumed in pods
|
||||
or used to store configuration data for system components such as controllers. ConfigMap is similar
|
||||
to [Secrets](/docs/user-guide/secrets/), but designed to more conveniently support working with strings that do not
|
||||
contain sensitive information.
|
||||
|
||||
Note: ConfigMaps are not intended to act as a replacement for a properties file. ConfigMaps are intended to act as a reference to multiple properties files. You can think of them as way to represent something similar to the /etc directory, and the files within, on a Linux computer. One example of this model is creating Kubernetes Volumes from ConfigMaps, where each data item in the ConfigMap becomes a new file.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T19:14:38Z
|
||||
name: example-config
|
||||
namespace: default
|
||||
data:
|
||||
example.property.1: hello
|
||||
example.property.2: world
|
||||
example.property.file: |-
|
||||
property.1=value-1
|
||||
property.2=value-2
|
||||
property.3=value-3
|
||||
```
|
||||
|
||||
The `data` field contains the configuration data. As you can see, ConfigMaps can be used to hold
|
||||
fine-grained information like individual properties or coarse-grained information like the contents
|
||||
of configuration files.
|
||||
|
||||
Configuration data can be consumed in pods in a variety of ways. ConfigMaps can be used to:
|
||||
|
||||
1. Populate the values of environment variables
|
||||
2. Set command-line arguments in a container
|
||||
3. Populate config files in a volume
|
||||
|
||||
Both users and system components may store configuration data in ConfigMap.
|
||||
|
||||
## Creating ConfigMaps
|
||||
|
||||
You can use the `kubectl create configmap` command to create configmaps easily from literal values,
|
||||
files, or directories.
|
||||
|
||||
Let's take a look at some different ways to create a ConfigMap:
|
||||
|
||||
### Creating from directories
|
||||
|
||||
Say that we have a directory with some files that already contain the data we want to populate a ConfigMap with:
|
||||
|
||||
```shell
|
||||
$ ls docs/user-guide/configmap/kubectl/
|
||||
game.properties
|
||||
ui.properties
|
||||
|
||||
$ cat docs/user-guide/configmap/kubectl/game.properties
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
|
||||
$ cat docs/user-guide/configmap/kubectl/ui.properties
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
how.nice.to.look=fairlyNice
|
||||
```
|
||||
|
||||
The `kubectl create configmap` command can be used to create a ConfigMap holding the content of each
|
||||
file in this directory:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl
|
||||
```
|
||||
|
||||
When `--from-file` points to a directory, each file directly in that directory is used to populate a
|
||||
key in the ConfigMap, where the name of the key is the filename, and the value of the key is the
|
||||
content of the file.
|
||||
|
||||
Let's take a look at the ConfigMap that this command created:
|
||||
|
||||
```shell
|
||||
$ kubectl describe configmaps game-config
|
||||
Name: game-config
|
||||
Namespace: default
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
|
||||
Data
|
||||
====
|
||||
game.properties: 158 bytes
|
||||
ui.properties: 83 bytes
|
||||
```
|
||||
|
||||
You can see the two keys in the map are created from the filenames in the directory we pointed
|
||||
kubectl to. Since the content of those keys may be large, in the output of `kubectl describe`,
|
||||
you'll see only the names of the keys and their sizes.
|
||||
|
||||
If we want to see the values of the keys, we can simply `kubectl get` the resource:
|
||||
|
||||
```shell
|
||||
$ kubectl get configmaps game-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
game.properties: |
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
ui.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
how.nice.to.look=fairlyNice
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T18:34:05Z
|
||||
name: game-config
|
||||
namespace: default
|
||||
resourceVersion: "407"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/game-config
|
||||
uid: 30944725-d66e-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
### Creating from files
|
||||
|
||||
We can also pass `--from-file` a specific file, and pass it multiple times to kubectl. The
|
||||
following command yields equivalent results to the above example:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties
|
||||
|
||||
$ kubectl get configmaps game-config-2 -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
game.properties: |
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
ui.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
how.nice.to.look=fairlyNice
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T18:52:05Z
|
||||
name: game-config-2
|
||||
namespace: default
|
||||
resourceVersion: "516"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/game-config-2
|
||||
uid: b4952dc3-d670-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
We can also set the key to use for an individual file with `--from-file` by passing an expression
|
||||
of `key=value`: `--from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties`:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap game-config-3 --from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties
|
||||
|
||||
$ kubectl get configmaps game-config-3 -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
game-special-key: |
|
||||
enemies=aliens
|
||||
lives=3
|
||||
enemies.cheat=true
|
||||
enemies.cheat.level=noGoodRotten
|
||||
secret.code.passphrase=UUDDLRLRBABAS
|
||||
secret.code.allowed=true
|
||||
secret.code.lives=30
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T18:54:22Z
|
||||
name: game-config-3
|
||||
namespace: default
|
||||
resourceVersion: "530"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/game-config-3
|
||||
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
### Creating from literal values
|
||||
|
||||
It is also possible to supply literal values for ConfigMaps using `kubectl create configmap`. The
|
||||
`--from-literal` option takes a `key=value` syntax that allows literal values to be supplied
|
||||
directly on the command line:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
|
||||
|
||||
$ kubectl get configmaps special-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-02-18T19:14:38Z
|
||||
name: special-config
|
||||
namespace: default
|
||||
resourceVersion: "651"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/special-config
|
||||
uid: dadce046-d673-11e5-8cd0-68f728db1985
|
||||
```
|
||||
|
||||
## Consuming ConfigMap in pods
|
||||
|
||||
### Use-Case: Consume ConfigMap in environment variables
|
||||
|
||||
ConfigMaps can be used to populate individual environment variables or be used in
|
||||
its entirety. As an example, consider the following ConfigMaps:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: special-config
|
||||
namespace: default
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: env-config
|
||||
namespace: default
|
||||
data:
|
||||
log_level: INFO
|
||||
```
|
||||
|
||||
We can consume the keys of this ConfigMap in a pod like so:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "env" ]
|
||||
env:
|
||||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.how
|
||||
- name: SPECIAL_TYPE_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.type
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: env-config
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, its output will include the lines:
|
||||
|
||||
```shell
|
||||
SPECIAL_LEVEL_KEY=very
|
||||
SPECIAL_TYPE_KEY=charm
|
||||
log_level=INFO
|
||||
```
|
||||
|
||||
#### Optional ConfigMap in environment variables
|
||||
|
||||
There might be situations where environment variables are not
|
||||
always required. These environment variables can be marked as optional in a
|
||||
pod like so:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "env" ]
|
||||
env:
|
||||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: a-config
|
||||
key: akey
|
||||
optional: true
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be empty.
|
||||
|
||||
### Use-Case: Set command-line arguments with ConfigMap
|
||||
|
||||
ConfigMaps can also be used to set the value of the command or arguments in a container. This is
|
||||
accomplished using the Kubernetes substitution syntax `$(VAR_NAME)`. Consider the ConfigMap:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: special-config
|
||||
namespace: default
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
```
|
||||
|
||||
In order to inject values into the command line, we must consume the keys we want to use as
|
||||
environment variables, as in the last example. Then we can refer to them in a container's command
|
||||
using the `$(VAR_NAME)` syntax.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
|
||||
env:
|
||||
- name: SPECIAL_LEVEL_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.how
|
||||
- name: SPECIAL_TYPE_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: special-config
|
||||
key: special.type
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output from the `test-container` container will be:
|
||||
|
||||
```shell
|
||||
very charm
|
||||
```
|
||||
|
||||
### Use-Case: Consume ConfigMap via volume plugin
|
||||
|
||||
ConfigMaps can also be consumed in volumes. Returning again to our example ConfigMap:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: special-config
|
||||
namespace: default
|
||||
data:
|
||||
special.how: very
|
||||
special.type: charm
|
||||
```
|
||||
|
||||
We have a couple different options for consuming this ConfigMap in a volume. The most basic
|
||||
way is to populate the volume with files where the key is the filename and the content of the file
|
||||
is the value of the key:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/config
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: special-config
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be:
|
||||
|
||||
```shell
|
||||
very
|
||||
```
|
||||
|
||||
We can also control the paths within the volume where ConfigMap keys are projected:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ]
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/config
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: special-config
|
||||
items:
|
||||
- key: special.how
|
||||
path: path/to/special-key
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be:
|
||||
|
||||
```shell
|
||||
very
|
||||
```
|
||||
|
||||
#### Projecting keys to specific paths and file permissions
|
||||
|
||||
You can project keys to specific paths and specific permissions on a per-file
|
||||
basis. The [Secrets](/docs/user-guide/secrets/) user guide explains the syntax.
|
||||
|
||||
#### Optional ConfigMap via volume plugin
|
||||
|
||||
Volumes and files provided by a ConfigMap can be also be marked as optional.
|
||||
The ConfigMap or the key specified does not have to exist. The mount path for
|
||||
such items will always be created.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dapi-test-pod
|
||||
spec:
|
||||
containers:
|
||||
- name: test-container
|
||||
image: gcr.io/google_containers/busybox
|
||||
command: [ "/bin/sh", "-c", "ls /etc/config" ]
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/config
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: no-config
|
||||
optional: true
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
When this pod is run, the output will be:
|
||||
|
||||
```shell
|
||||
```
|
||||
|
||||
## Real World Example: Configuring Redis
|
||||
|
||||
Let's take a look at a real-world example: configuring redis using ConfigMap. Say that we want to inject
|
||||
redis with the recommendation configuration for using redis as a cache. The redis config file
|
||||
should contain:
|
||||
|
||||
```conf
|
||||
maxmemory 2mb
|
||||
maxmemory-policy allkeys-lru
|
||||
```
|
||||
|
||||
Such a file is in `docs/user-guide/configmap/redis`; we can use the following command to create a
|
||||
ConfigMap instance with it:
|
||||
|
||||
```shell
|
||||
$ kubectl create configmap example-redis-config --from-file=docs/user-guide/configmap/redis/redis-config
|
||||
|
||||
$ kubectl get configmap example-redis-config -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
redis-config: |
|
||||
maxmemory 2mb
|
||||
maxmemory-policy allkeys-lru
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: 2016-03-30T18:14:41Z
|
||||
name: example-redis-config
|
||||
namespace: default
|
||||
resourceVersion: "24686"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
|
||||
uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002
|
||||
```
|
||||
|
||||
Now, let's create a pod that uses this config:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: kubernetes/redis:v1
|
||||
env:
|
||||
- name: MASTER
|
||||
value: "true"
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
resources:
|
||||
limits:
|
||||
cpu: "0.1"
|
||||
volumeMounts:
|
||||
- mountPath: /redis-master-data
|
||||
name: data
|
||||
- mountPath: /redis-master
|
||||
name: config
|
||||
volumes:
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
- name: config
|
||||
configMap:
|
||||
name: example-redis-config
|
||||
items:
|
||||
- key: redis-config
|
||||
path: redis.conf
|
||||
```
|
||||
|
||||
Notice that this pod has a ConfigMap volume that places the `redis-config` key of the
|
||||
`example-redis-config` ConfigMap into a file called `redis.conf`. This volume is mounted into the
|
||||
`/redis-master` directory in the redis container, placing our config file at
|
||||
`/redis-master/redis.conf`, which is where the image looks for the redis config file for the master.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/user-guide/configmap/redis/redis-pod.yaml
|
||||
```
|
||||
|
||||
If we `kubectl exec` into this pod and run the `redis-cli` tool, we can check that our config was
|
||||
applied correctly:
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis redis-cli
|
||||
127.0.0.1:6379> CONFIG GET maxmemory
|
||||
1) "maxmemory"
|
||||
2) "2097152"
|
||||
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
||||
1) "maxmemory-policy"
|
||||
2) "allkeys-lru"
|
||||
```
|
||||
|
||||
## Restrictions
|
||||
|
||||
ConfigMaps must be created before they are consumed in pods unless they are
|
||||
marked as optional. References to ConfigMaps that do not exist will prevent
|
||||
the pod from starting. Controllers may be written to tolerate missing
|
||||
configuration data; consult individual components configured via ConfigMap on
|
||||
a case-by-case basis.
|
||||
|
||||
References via `configMapKeyRef` to keys that do not exist in a named ConfigMap
|
||||
will prevent the pod from starting.
|
||||
|
||||
ConfigMaps used to populate environment variables via `envFrom` that have keys
|
||||
that are considered invalid environment variable names will have those keys
|
||||
skipped. The pod will be allowed to start. There will be an event whose
|
||||
reason is `InvalidVariableNames` and the message will contain the list of
|
||||
invalid keys that were skipped. The example shows a pod which refers to the
|
||||
default/myconfig ConfigMap that contains 2 invalid keys, 1badkey and 2alsobad.
|
||||
|
||||
```shell
|
||||
$ kubectl.sh get events
|
||||
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
|
||||
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
|
||||
```
|
||||
|
||||
ConfigMaps reside in a namespace. They can only be referenced by pods in the same namespace.
|
||||
|
||||
Quota for ConfigMap size is a planned feature.
|
||||
|
||||
Kubelet only supports use of ConfigMap for pods it gets from the API server. This includes every pod
|
||||
created using kubectl, or indirectly via a replication controller. It does not include pods created
|
||||
via the Kubelet's `--manifest-url` flag, its `--config` flag, or its REST API (these are not common
|
||||
ways to create pods.)
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
[Configure Containers Using a ConfigMap](/docs/tasks/configure-pod-container/configmap/)
|
||||
|
|
|
|||
Loading…
Reference in New Issue