--- assignees: - eparis - pmorie 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: Annotations: Data ==== game.properties: 121 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 environment variables. As an example, consider the following ConfigMap: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: special-config namespace: default data: special.how: very special.type: charm ``` 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 restartPolicy: Never ``` When this pod is run, its output will include the lines: ```shell SPECIAL_LEVEL_KEY=very SPECIAL_TYPE_KEY=charm ``` ### 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. ## 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. Controllers may be written to tolerate missing configuration data; consult individual components configured via ConfigMap on a case-by-case basis. 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.)