<commit_before>:icons:
:linkcss:
:imagesdir: ../images

= Kubernetes ConfigMap and Secrets
:toc:

Kubernetes has resource types that allows to decouple application code from configuration. It makes the applications to be more portable. This chapter will cover how ConfigMap and Secrets can be used to do that.

. ConfigMap is just a set of key-value pairs. It allow you to decouple configuration artifacts from image content.
. Secrets allows separating sensitive information such as credentials and keys from an application.

ConfigMap is similar to Secrets, but provides a means of working with strings that don’t contain sensitive information.

This section will explain how to use ConfigMap and Secrets.

== Pre-requisites

A 3 master nodes and 5 worker nodes cluster as explained at link:../cluster-install#multi-master-multi-node-multi-az-gossip-based-cluster[] is used for this chapter.

All configuration files for this chapter are in the `config-secrets` directory.

== ConfigMap

This section will explain:

. Pass configuration information to a Pod
. Define environment variables in a Pod using ConfigMap

=== Create a ConfigMap object

Create a ConfigMap:

    $ kubectl apply -f ./templates/redis-configmap.yaml
    configmap "redis-config" created

`redis-configmap.yaml` is a standard resource configuration file. It defines the configuration information as:

    data:
      redis-config: |
        maxmemory=2mb
        maxmemory-policy=allkeys-lru

The configuration data is stored in the main key `data`. `redis-config` is an attribute inside this key where the configuration information for the Redis pod is defined as key-value pairs.

Get the list of ConfigMaps:

    $ kubectl get configmap
    NAME           DATA      AGE
    redis-config   1         14s

Get more details about the created ConfigMap:

```
$ kubectl get configmap/redis-config -o yaml
apiVersion: v1
items:
- apiVersion: v1
  data:
    redis-config: |
      maxmemory 2mb
      maxmemory-policy allkeys-lru
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-22T18:38:27Z
    labels:
      k8s-app: redis
    name: redis-config
    namespace: default
    resourceVersion: "302238"
    selfLink: /api/v1/namespaces/default/configmaps/redis-config
    uid: 316309d0-b758-11e7-8c3f-06329c8974cc
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""
```

The configuration information is shown as key/value pairs in the `data` key.

==== Alternative ways to create ConfigMap

We created a ConfigMap using a resource configuration file. Other ways to create ConfigMap are listed below:

NOTE: These ConfigMaps are using the exact same name as the one previously created. If you like to try the commands, then you either need to give a different name to the ConfigMap or delete the previously created ConfigMap using the command `kubectl delete -f ./templates/redis-configmap.yaml`.

. `kubectl create configmap --from-literal=<key>:<value>`. Multiple `--from-literal=<key>:<value>` options can be used to define different key/value pairs. For example:

  $ kubectl create configmap redis-config --from-literal=maxmemory=2mb --from-literal=maxmemory-policy=allkeys-lru
  configmap "redis-config" created
+
More details about the ConfigMap can be obtained as:
+
  $ kubectl get configmap/redis-config -o yaml
  apiVersion: v1
  data:
    maxmemory: 2mb
    maxmemory-policy: allkeys-lru
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-22T15:29:31Z
    name: redis-config
    namespace: default
    resourceVersion: "287452"
    selfLink: /api/v1/namespaces/default/configmaps/redis-config
    uid: cccf20b7-b73d-11e7-8c3f-06329c8974cc
+
. `kubectl create configmap redis-config --from-file=<properties file>` where `<properties file>` is a property file with key/value pairs. For example, `templates/redis-config` looks like:
+
  maxmemory 2mb
  maxmemory-policy allkeys-lru
+
And now the ConfigMap can be created as:
+
  $ kubectl create configmap redis-config --from-file=templates/redis-config
  configmap "redis-config" created
+
More details about the ConfigMap can be obtained as:
+
  $ kubectl get configmap/redis-config -o yaml
  apiVersion: v1
  data:
    redis-config: |
      maxmemory=2mb
      maxmemory-policy=allkeys-lru
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-22T15:56:08Z
    name: redis-config
    namespace: default
    resourceVersion: "289533"
    selfLink: /api/v1/namespaces/default/configmaps/redis-config
    uid: 84901162-b741-11e7-8c3f-06329c8974cc
+
The filename becomes a key stored in the data section of the ConfigMap. The file contents become the key’s value.

At the end of this section, you'll have created a ConfigMap `redis-config`.

=== Consume in a pod volume

A ConfigMap must be created before referencing it in a Pod specification (unless you mark the ConfigMap as "`optional`"). If you reference a ConfigMap that doesn’t exist would , the Pod won’t start.

Let's use `redis-config` ConfigMap to create our `redis.conf` configuration file in the pod `redis-pod`. It maps the ConfigMap to the volume where the configuration resides:

    $ kubectl apply -f ./templates/redis-pod.yaml
    pod "redis-pod" created

Wait for the pod to run:

    $ kubectl get pods
    NAME        READY     STATUS    RESTARTS   AGE
    redis-pod   1/1       Running   0          12m

Check logs from the pod to verify that Redis has started:

  $ kubectl logs redis-pod
                  _._                                                  
             _.-``__ ''-._                                             
        _.-``    `.  `_.  ''-._           Redis 2.8.19 (00000000/0) 64 bit
    .-`` .-```.  ```\/    _.,_ ''-._                                   
   (    '      ,       .-`  | `,    )     Running in stand alone mode
   |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
   |    `-._   `._    /     _.-'    |     PID: 6
    `-._    `-._  `-./  _.-'    _.-'                                   
   |`-._`-._    `-.__.-'    _.-'_.-'|                                  
   |    `-._`-._        _.-'_.-'    |           http://redis.io        
    `-._    `-._`-.__.-'_.-'    _.-'                                   
   |`-._`-._    `-.__.-'    _.-'_.-'|                                  
   |    `-._`-._        _.-'_.-'    |                                  
    `-._    `-._`-.__.-'_.-'    _.-'                                   
        `-._    `-.__.-'    _.-'                                       
            `-._        _.-'                                           
                `-.__.-'                                               

  [6] 22 Oct 18:39:45.386 # Server started, Redis version 2.8.19
  [6] 22 Oct 18:39:45.386 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
  [6] 22 Oct 18:39:45.386 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
  [6] 22 Oct 18:39:45.386 * The server is now ready to accept connections on port 6379

Validate that your redis cluster picked up the appropriate configuration:

    $ kubectl exec redis-pod -it 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"
    127.0.0.1:6379> quit

You should see the same values that were specified in `./templates/redis-configmap.yaml` outputted in the above commands.

Now, changing the pod configuration would involve the following steps:

. Edit `redis-configmap.yaml`
. Update the ConfigMap using the command: `kubectl apply -f templates/redis-config.yaml`
. Wrap the pod in a Deployment
. Terminate the pod, Deployment will restart the pod and pick up new configuration

=== Consume as pod environment variables

The data from ConfigMap can be used to initialize environment variables in a pod. We'll use `arungupta/print-hello` image to print "`Hello World`" on the console. The number of times this message is printed is defined by an environment variable `COUNT`. This value of this variable is defined in the ConfigMap.

==== Create a pod and use ConfigMap

. Create a ConfigMap:

  $ kubectl create configmap hello-config --from-literal=COUNT=2
  configmap "hello-config" created

. Get more details about this ConfigMap:

  $ kubectl get configmap/hello-config -o yaml
  apiVersion: v1
  data:
    COUNT: "2"
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-26T21:40:10Z
    name: hello-config<commit_msg>Fixed the name of the apply command<commit_after>:icons:
:linkcss:
:imagesdir: ../images

= Kubernetes ConfigMap and Secrets
:toc:

Kubernetes has resource types that allows to decouple application code from configuration. It makes the applications to be more portable. This chapter will cover how ConfigMap and Secrets can be used to do that.

. ConfigMap is just a set of key-value pairs. It allow you to decouple configuration artifacts from image content.
. Secrets allows separating sensitive information such as credentials and keys from an application.

ConfigMap is similar to Secrets, but provides a means of working with strings that don’t contain sensitive information.

This section will explain how to use ConfigMap and Secrets.

== Pre-requisites

A 3 master nodes and 5 worker nodes cluster as explained at link:../cluster-install#multi-master-multi-node-multi-az-gossip-based-cluster[] is used for this chapter.

All configuration files for this chapter are in the `config-secrets` directory.

== ConfigMap

This section will explain:

. Pass configuration information to a Pod
. Define environment variables in a Pod using ConfigMap

=== Create a ConfigMap object

Create a ConfigMap:

    $ kubectl apply -f ./templates/redis-configmap.yaml
    configmap "redis-config" created

`redis-configmap.yaml` is a standard resource configuration file. It defines the configuration information as:

    data:
      redis-config: |
        maxmemory=2mb
        maxmemory-policy=allkeys-lru

The configuration data is stored in the main key `data`. `redis-config` is an attribute inside this key where the configuration information for the Redis pod is defined as key-value pairs.

Get the list of ConfigMaps:

    $ kubectl get configmap
    NAME           DATA      AGE
    redis-config   1         14s

Get more details about the created ConfigMap:

```
$ kubectl get configmap/redis-config -o yaml
apiVersion: v1
items:
- apiVersion: v1
  data:
    redis-config: |
      maxmemory 2mb
      maxmemory-policy allkeys-lru
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-22T18:38:27Z
    labels:
      k8s-app: redis
    name: redis-config
    namespace: default
    resourceVersion: "302238"
    selfLink: /api/v1/namespaces/default/configmaps/redis-config
    uid: 316309d0-b758-11e7-8c3f-06329c8974cc
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""
```

The configuration information is shown as key/value pairs in the `data` key.

==== Alternative ways to create ConfigMap

We created a ConfigMap using a resource configuration file. Other ways to create ConfigMap are listed below:

NOTE: These ConfigMaps are using the exact same name as the one previously created. If you like to try the commands, then you either need to give a different name to the ConfigMap or delete the previously created ConfigMap using the command `kubectl delete -f ./templates/redis-configmap.yaml`.

. `kubectl create configmap --from-literal=<key>:<value>`. Multiple `--from-literal=<key>:<value>` options can be used to define different key/value pairs. For example:

  $ kubectl create configmap redis-config --from-literal=maxmemory=2mb --from-literal=maxmemory-policy=allkeys-lru
  configmap "redis-config" created
+
More details about the ConfigMap can be obtained as:
+
  $ kubectl get configmap/redis-config -o yaml
  apiVersion: v1
  data:
    maxmemory: 2mb
    maxmemory-policy: allkeys-lru
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-22T15:29:31Z
    name: redis-config
    namespace: default
    resourceVersion: "287452"
    selfLink: /api/v1/namespaces/default/configmaps/redis-config
    uid: cccf20b7-b73d-11e7-8c3f-06329c8974cc
+
. `kubectl create configmap redis-config --from-file=<properties file>` where `<properties file>` is a property file with key/value pairs. For example, `templates/redis-config` looks like:
+
  maxmemory 2mb
  maxmemory-policy allkeys-lru
+
And now the ConfigMap can be created as:
+
  $ kubectl create configmap redis-config --from-file=templates/redis-config
  configmap "redis-config" created
+
More details about the ConfigMap can be obtained as:
+
  $ kubectl get configmap/redis-config -o yaml
  apiVersion: v1
  data:
    redis-config: |
      maxmemory=2mb
      maxmemory-policy=allkeys-lru
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-22T15:56:08Z
    name: redis-config
    namespace: default
    resourceVersion: "289533"
    selfLink: /api/v1/namespaces/default/configmaps/redis-config
    uid: 84901162-b741-11e7-8c3f-06329c8974cc
+
The filename becomes a key stored in the data section of the ConfigMap. The file contents become the key’s value.

At the end of this section, you'll have created a ConfigMap `redis-config`.

=== Consume in a pod volume

A ConfigMap must be created before referencing it in a Pod specification (unless you mark the ConfigMap as "`optional`"). If you reference a ConfigMap that doesn’t exist would , the Pod won’t start.

Let's use `redis-config` ConfigMap to create our `redis.conf` configuration file in the pod `redis-pod`. It maps the ConfigMap to the volume where the configuration resides:

    $ kubectl apply -f ./templates/redis-pod.yaml
    pod "redis-pod" created

Wait for the pod to run:

    $ kubectl get pods
    NAME        READY     STATUS    RESTARTS   AGE
    redis-pod   1/1       Running   0          12m

Check logs from the pod to verify that Redis has started:

  $ kubectl logs redis-pod
                  _._                                                  
             _.-``__ ''-._                                             
        _.-``    `.  `_.  ''-._           Redis 2.8.19 (00000000/0) 64 bit
    .-`` .-```.  ```\/    _.,_ ''-._                                   
   (    '      ,       .-`  | `,    )     Running in stand alone mode
   |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
   |    `-._   `._    /     _.-'    |     PID: 6
    `-._    `-._  `-./  _.-'    _.-'                                   
   |`-._`-._    `-.__.-'    _.-'_.-'|                                  
   |    `-._`-._        _.-'_.-'    |           http://redis.io        
    `-._    `-._`-.__.-'_.-'    _.-'                                   
   |`-._`-._    `-.__.-'    _.-'_.-'|                                  
   |    `-._`-._        _.-'_.-'    |                                  
    `-._    `-._`-.__.-'_.-'    _.-'                                   
        `-._    `-.__.-'    _.-'                                       
            `-._        _.-'                                           
                `-.__.-'                                               

  [6] 22 Oct 18:39:45.386 # Server started, Redis version 2.8.19
  [6] 22 Oct 18:39:45.386 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
  [6] 22 Oct 18:39:45.386 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
  [6] 22 Oct 18:39:45.386 * The server is now ready to accept connections on port 6379

Validate that your redis cluster picked up the appropriate configuration:

    $ kubectl exec redis-pod -it 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"
    127.0.0.1:6379> quit

You should see the same values that were specified in `./templates/redis-configmap.yaml` outputted in the above commands.

Now, changing the pod configuration would involve the following steps:

. Edit `redis-configmap.yaml`
. Update the ConfigMap using the command: `kubectl apply -f templates/redis-configmap.yaml`
. Wrap the pod in a Deployment
. Terminate the pod, Deployment will restart the pod and pick up new configuration

=== Consume as pod environment variables

The data from ConfigMap can be used to initialize environment variables in a pod. We'll use `arungupta/print-hello` image to print "`Hello World`" on the console. The number of times this message is printed is defined by an environment variable `COUNT`. This value of this variable is defined in the ConfigMap.

==== Create a pod and use ConfigMap

. Create a ConfigMap:

  $ kubectl create configmap hello-config --from-literal=COUNT=2
  configmap "hello-config" created

. Get more details about this ConfigMap:

  $ kubectl get configmap/hello-config -o yaml
  apiVersion: v1
  data:
    COUNT: "2"
  kind: ConfigMap
  metadata:
    creationTimestamp: 2017-10-26T21:40:10Z
    name: hello-config
{'fraction_non_alphanumeric': 0.09134697115657052, 'fraction_numerical': 0.03309344364481215, 'mean_word_length': 2.4142000386922033, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4409073', 'n_tokens_mistral': 5660, 'n_tokens_neox': 5163, 'n_words': 1873}