Creating and using config maps

The following sections define config maps and how to create and use them.

Understanding config maps

Many applications require configuration using some combination of configuration files, command line arguments, and environment variables. In OKD, these configuration artifacts are decoupled from image content to keep containerized applications portable.

The ConfigMap object provides mechanisms to inject containers with configuration data while keeping containers agnostic of OKD. A config map can be used to store fine-grained information like individual properties or coarse-grained information like entire configuration files or JSON blobs.

The ConfigMap API object 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. For example:

ConfigMap Object Definition

  1. kind: ConfigMap
  2. apiVersion: v1
  3. metadata:
  4. creationTimestamp: 2016-02-18T19:14:38Z
  5. name: example-config
  6. namespace: default
  7. data: (1)
  8. example.property.1: hello
  9. example.property.2: world
  10. example.property.file: |-
  11. property.1=value-1
  12. property.2=value-2
  13. property.3=value-3
  14. binaryData:
  15. bar: L3Jvb3QvMTAw (2)
1Contains the configuration data.
2Points to a file that contains non-UTF8 data, for example, a binary Java keystore file. Enter the file data in Base 64.

You can use the binaryData field when you create a config map from a binary file, such as an image.

Configuration data can be consumed in pods in a variety of ways. A config map can be used to:

  • Populate environment variable values in containers

  • Set command-line arguments in a container

  • Populate configuration files in a volume

Users and system components can store configuration data in a config map.

A config map is similar to a secret, but designed to more conveniently support working with strings that do not contain sensitive information.

Config map restrictions

A config map must be created before its contents can be consumed in pods.

Controllers can be written to tolerate missing configuration data. Consult individual components configured by using config maps on a case-by-case basis.

ConfigMap objects reside in a project.

They can only be referenced by pods in the same project.

The Kubelet only supports the use of a config map for pods it gets from the API server.

This includes any pods created by using the CLI, or indirectly from a replication controller. It does not include pods created by using the OKD node’s --manifest-url flag, its --config flag, or its REST API because these are not common ways to create pods.

Creating a config map in the OKD web console

You can create a config map in the OKD web console.

Procedure

  • To create a config map as a cluster administrator:

    1. In the Administrator perspective, select WorkloadsConfig Maps.

    2. At the top right side of the page, select Create Config Map.

    3. Enter the contents of your config map.

    4. Select Create.

  • To create a config map as a developer:

    1. In the Developer perspective, select Config Maps.

    2. At the top right side of the page, select Create Config Map.

    3. Enter the contents of your config map.

    4. Select Create.

Creating a config map by using the CLI

You can use the following command to create a config map from directories, specific files, or literal values.

Procedure

  • Create a config map:

    1. $ oc create configmap <configmap_name> [options]

Creating a config map from a directory

You can create a config map from a directory. This method allows you to use multiple files within a directory to create a config map.

Procedure

The following example procedure outlines how to create a config map from a directory.

  1. Start with a directory with some files that already contain the data with which you want to populate a config map:

    1. $ ls example-files

    Example output

    1. game.properties
    2. ui.properties
    1. $ cat example-files/game.properties

    Example output

    1. enemies=aliens
    2. lives=3
    3. enemies.cheat=true
    4. enemies.cheat.level=noGoodRotten
    5. secret.code.passphrase=UUDDLRLRBABAS
    6. secret.code.allowed=true
    7. secret.code.lives=30
    1. $ cat example-files/ui.properties

    Example output

    1. color.good=purple
    2. color.bad=yellow
    3. allow.textmode=true
    4. how.nice.to.look=fairlyNice
  2. Create a config map holding the content of each file in this directory by entering the following command:

    1. $ oc create configmap game-config \
    2. --from-file=example-files/

    When the --from-file option points to a directory, each file directly in that directory is used to populate a key in the config map, where the name of the key is the file name, and the value of the key is the content of the file.

    For example, the previous command creates the following config map:

    1. $ oc describe configmaps game-config

    Example output

    1. Name: game-config
    2. Namespace: default
    3. Labels: <none>
    4. Annotations: <none>
    5. Data
    6. game.properties: 158 bytes
    7. ui.properties: 83 bytes

    You can see that the two keys in the map are created from the file names in the directory specified in the command. Because the content of those keys might be large, the output of oc describe only shows the names of the keys and their sizes.

  3. Enter the oc get command for the object with the -o option to see the values of the keys:

    1. $ oc get configmaps game-config -o yaml

    Example output

    1. apiVersion: v1
    2. data:
    3. game.properties: |-
    4. enemies=aliens
    5. lives=3
    6. enemies.cheat=true
    7. enemies.cheat.level=noGoodRotten
    8. secret.code.passphrase=UUDDLRLRBABAS
    9. secret.code.allowed=true
    10. secret.code.lives=30
    11. ui.properties: |
    12. color.good=purple
    13. color.bad=yellow
    14. allow.textmode=true
    15. how.nice.to.look=fairlyNice
    16. kind: ConfigMap
    17. metadata:
    18. creationTimestamp: 2016-02-18T18:34:05Z
    19. name: game-config
    20. namespace: default
    21. resourceVersion: "407"
    22. selflink: /api/v1/namespaces/default/configmaps/game-config
    23. uid: 30944725-d66e-11e5-8cd0-68f728db1985

Creating a config map from a file

You can create a config map from a file.

Procedure

The following example procedure outlines how to create a config map from a file.

If you create a config map from a file, you can include files containing non-UTF8 data that are placed in this field without corrupting the non-UTF8 data. OKD detects binary files and transparently encodes the file as MIME. On the server, the MIME payload is decoded and stored without corrupting the data.

You can pass the --from-file option multiple times to the CLI. The following example yields equivalent results to the creating from directories example.

  1. Create a config map by specifying a specific file:

    1. $ oc create configmap game-config-2 \
    2. --from-file=example-files/game.properties \
    3. --from-file=example-files/ui.properties
  2. Verify the results:

    1. $ oc get configmaps game-config-2 -o yaml

    Example output

    1. apiVersion: v1
    2. data:
    3. game.properties: |-
    4. enemies=aliens
    5. lives=3
    6. enemies.cheat=true
    7. enemies.cheat.level=noGoodRotten
    8. secret.code.passphrase=UUDDLRLRBABAS
    9. secret.code.allowed=true
    10. secret.code.lives=30
    11. ui.properties: |
    12. color.good=purple
    13. color.bad=yellow
    14. allow.textmode=true
    15. how.nice.to.look=fairlyNice
    16. kind: ConfigMap
    17. metadata:
    18. creationTimestamp: 2016-02-18T18:52:05Z
    19. name: game-config-2
    20. namespace: default
    21. resourceVersion: "516"
    22. selflink: /api/v1/namespaces/default/configmaps/game-config-2
    23. uid: b4952dc3-d670-11e5-8cd0-68f728db1985

You can specify the key to set in a config map for content imported from a file. This can be set by passing a key=value expression to the --from-file option. For example:

  1. Create a config map by specifying a key-value pair:

    1. $ oc create configmap game-config-3 \
    2. --from-file=game-special-key=example-files/game.properties
  2. Verify the results:

    1. $ oc get configmaps game-config-3 -o yaml

    Example output

    1. apiVersion: v1
    2. data:
    3. game-special-key: |- (1)
    4. enemies=aliens
    5. lives=3
    6. enemies.cheat=true
    7. enemies.cheat.level=noGoodRotten
    8. secret.code.passphrase=UUDDLRLRBABAS
    9. secret.code.allowed=true
    10. secret.code.lives=30
    11. kind: ConfigMap
    12. metadata:
    13. creationTimestamp: 2016-02-18T18:54:22Z
    14. name: game-config-3
    15. namespace: default
    16. resourceVersion: "530"
    17. selflink: /api/v1/namespaces/default/configmaps/game-config-3
    18. uid: 05f8da22-d671-11e5-8cd0-68f728db1985
    1This is the key that you set in the preceding step.

Creating a config map from literal values

You can supply literal values for a config map.

Procedure

The --from-literal option takes a key=value syntax that allows literal values to be supplied directly on the command line.

  1. Create a config map by specifying a literal value:

    1. $ oc create configmap special-config \
    2. --from-literal=special.how=very \
    3. --from-literal=special.type=charm
  2. Verify the results:

    1. $ oc get configmaps special-config -o yaml

    Example output

    1. apiVersion: v1
    2. data:
    3. special.how: very
    4. special.type: charm
    5. kind: ConfigMap
    6. metadata:
    7. creationTimestamp: 2016-02-18T19:14:38Z
    8. name: special-config
    9. namespace: default
    10. resourceVersion: "651"
    11. selflink: /api/v1/namespaces/default/configmaps/special-config
    12. uid: dadce046-d673-11e5-8cd0-68f728db1985

Use cases: Consuming config maps in pods

The following sections describe some uses cases when consuming ConfigMap objects in pods.

Populating environment variables in containers by using config maps

Config maps can be used to populate individual environment variables in containers or to populate environment variables in containers from all keys that form valid environment variable names.

As an example, consider the following config map:

ConfigMap with two environment variables

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: special-config (1)
  5. namespace: default (2)
  6. data:
  7. special.how: very (3)
  8. special.type: charm (3)
1Name of the config map.
2The project in which the config map resides. Config maps can only be referenced by pods in the same project.
3Environment variables to inject.

ConfigMap with one environment variable

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: env-config (1)
  5. namespace: default
  6. data:
  7. log_level: INFO (2)
1Name of the config map.
2Environment variable to inject.

Procedure

  • You can consume the keys of this ConfigMap in a pod using configMapKeyRef sections.

    Sample Pod specification configured to inject specific environment variables

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: dapi-test-pod
    5. spec:
    6. containers:
    7. - name: test-container
    8. image: gcr.io/google_containers/busybox
    9. command: [ "/bin/sh", "-c", "env" ]
    10. env: (1)
    11. - name: SPECIAL_LEVEL_KEY (2)
    12. valueFrom:
    13. configMapKeyRef:
    14. name: special-config (3)
    15. key: special.how (4)
    16. - name: SPECIAL_TYPE_KEY
    17. valueFrom:
    18. configMapKeyRef:
    19. name: special-config (3)
    20. key: special.type (4)
    21. optional: true (5)
    22. envFrom: (6)
    23. - configMapRef:
    24. name: env-config (7)
    25. restartPolicy: Never
    1Stanza to pull the specified environment variables from a ConfigMap.
    2Name of a pod environment variable that you are injecting a key’s value into.
    3Name of the ConfigMap to pull specific environment variables from.
    4Environment variable to pull from the ConfigMap.
    5Makes the environment variable optional. As optional, the pod will be started even if the specified ConfigMap and keys do not exist.
    6Stanza to pull all environment variables from a ConfigMap.
    7Name of the ConfigMap to pull all environment variables from.

    When this pod is run, the pod logs will include the following output:

    1. SPECIAL_LEVEL_KEY=very
    2. log_level=INFO

SPECIAL_TYPE_KEY=charm is not listed in the example output because optional: true is set.

Setting command-line arguments for container commands with config maps

A config map can also be used to set the value of the commands or arguments in a container. This is accomplished by using the Kubernetes substitution syntax $(VAR_NAME). Consider the following config map:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: special-config
  5. namespace: default
  6. data:
  7. special.how: very
  8. special.type: charm

Procedure

  • To inject values into a command in a container, you must consume the keys you want to use as environment variables, as in the consuming ConfigMaps in environment variables use case. Then you can refer to them in a container’s command using the $(VAR_NAME) syntax.

    Sample Pod specification configured to inject specific environment variables

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: dapi-test-pod
    5. spec:
    6. containers:
    7. - name: test-container
    8. image: gcr.io/google_containers/busybox
    9. command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] (1)
    10. env:
    11. - name: SPECIAL_LEVEL_KEY
    12. valueFrom:
    13. configMapKeyRef:
    14. name: special-config
    15. key: special.how
    16. - name: SPECIAL_TYPE_KEY
    17. valueFrom:
    18. configMapKeyRef:
    19. name: special-config
    20. key: special.type
    21. restartPolicy: Never
    1Inject the values into a command in a container using the keys you want to use as environment variables.

    When this Pod is run, the output from the echo command run in the test-container container is as follows:

    1. very charm

Injecting content into a volume by using config maps

You can inject content into a volume by using config maps.

Example ConfigMap custom resource (CR)

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: special-config
  5. namespace: default
  6. data:
  7. special.how: very
  8. special.type: charm

Procedure

You have a couple different options for injecting content into a volume by using config maps.

  • The most basic way to inject content into a volume by using a config map is to populate the volume with files where the key is the file name and the content of the file is the value of the key:

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: dapi-test-pod
    5. spec:
    6. containers:
    7. - name: test-container
    8. image: gcr.io/google_containers/busybox
    9. command: [ "/bin/sh", "cat", "/etc/config/special.how" ]
    10. volumeMounts:
    11. - name: config-volume
    12. mountPath: /etc/config
    13. volumes:
    14. - name: config-volume
    15. configMap:
    16. name: special-config (1)
    17. restartPolicy: Never
    1File containing key.

    When this pod is run, the output of the cat command will be:

    1. very
  • You can also control the paths within the volume where config map keys are projected:

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: dapi-test-pod
    5. spec:
    6. containers:
    7. - name: test-container
    8. image: gcr.io/google_containers/busybox
    9. command: [ "/bin/sh", "cat", "/etc/config/path/to/special-key" ]
    10. volumeMounts:
    11. - name: config-volume
    12. mountPath: /etc/config
    13. volumes:
    14. - name: config-volume
    15. configMap:
    16. name: special-config
    17. items:
    18. - key: special.how
    19. path: path/to/special-key (1)
    20. restartPolicy: Never
    1Path to config map key.

    When this pod is run, the output of the cat command will be:

    1. very