Explaining ConfigMaps and Secrets

Objectives

After completing this lesson, you will be able to:
  • Explain how to store Configs and Secrets decoupled from your application
  • Configure your application to use ConfigMaps and Secrets
  • Identify differences between mounting and injecting ConfigMaps and Secrets

Usage Scenario for ConfigMaps and Secrets

Assuming that you have already deployed applications, you may consider securing them. Some of them need configuration with sensitive data like passwords or API keys. So, how to store this data securely and inject it into your application?

Why Use ConfigMaps and Secrets?

Applications typically need some configuration. Especially when it comes to distributed applications, each application likely needs to access a database, a message queue, or an SMTP service to send emails. In addition, applications often need to be configured with sensitive data like passwords or API keys.

These backing services should be treated as attached resources. There should be no hard-coded configuration in the application. Instead, the application should be configured to use the attached resources. This allows for easy change of the backing services without the need to change the application. Typically, the application is configured via environment variables, which are simple key-value pairs that are passed to the application at startup. So by continuing the example above, the application should be configured with environment variables storing the database connection string, SMTP server address and credentials, and so on. The same also applies to sensitive data like passwords or API keys.

When deploying workloads to Kubernetes, you can define environment variables directly in the deployment manifest. However, this is not a good practice since these manifests are often stored in version control systems like Git. This means that the sensitive data is stored in plain text in the version control system. This is not a good practice since the data is not encrypted and can be read by anyone with access to the version control system.

What are ConfigMaps and Secrets in Kubernetes?

Kubernetes has two native resources to store configuration data decoupled from the application: ConfigMaps and Secrets.

ConfigMaps should be used for non-sensitive data. Secrets should be used for sensitive data like passwords or API keys. Please note that there is also a restriction on the size of the data stored in ConfigMaps and Secretes. ConfigMaps and Secrets can both store up to 1 MB of data. Everything that exceeds this limit should be mounted into the application as storage.

Using ConfigMaps

A ConfigMap can be created as follows:

YAML
123456789101112131415161718
apiVersion: v1 kind: ConfigMap metadata: name: my-config data: my-key: "my-value" my-other-key: "my-other-value" # You can also use file-like key-value pairs my-file-like-key: | # This "file" contains a bash script /bin/bash echo "Hello World" my-other-file-like-key: | # This "file" contains a JSON object { "key": "value" }

So, as you can see, ConfigMaps are a simple but powerful way to store configuration data. But how do you use them in your application?

You can assign a ConfigMap to a container in a Deployment manifest as follows:

YAML
1234567891011121314151617181920212223242526
apiVersion: apps/v1 kind: Deployment metadata: name: hello-kyma-config spec: replicas: 1 selector: matchLabels: app: hello-kyma-config template: metadata: labels: app: hello-kyma-config spec: containers: - name: my-container image: my-image envFrom: # 1. Use all keys as environment variables - configMapRef: name: my-config env: # 2. Use only specific keys as environment variables - name: MY_KEY valueFrom: configMapKeyRef: name: my-config key: my-key

There are far more ways to use ConfigMaps in your application. Please refer to the official documentation for more information.

Using Secrets

A Secret can be created as follows:

YAML
12345678
apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque # default type data: username: "YWRtaW4=" # This is the base64 encoded string "admin" password: "dG9wc2VjcmV0" # This is the base64 encoded string "topsecret"

The above listed manifest creates a Secret with two keys: username and password. Kubernetes also comes with different Secret types that can be used to store different types of sensitive data. For example, you can use the kubernetes.io/dockerconfigjson type to store a Docker config file. This is useful if you want to pull images from a private Docker registry.

Using Secrets in your application is very similar to using ConfigMaps. You can assign a Secret to a container in a Deployment manifest as follows:

YAML
12345678910111213141516171819202122232425
apiVersion: apps/v1 kind: Deployment metadata: name: hello-kyma-secret spec: selector: matchLabels: app: hello-kyma-secret template: metadata: labels: app: hello-kyma-secret spec: containers: - name: my-container image: ghcr.io/sap-samples/kyma-runtime-learning-journey/hello-kyma:1.0.0 envFrom: # 1. Use all keys as environment variables - secretRef: name: my-secret env: # 2. Use only specific keys as environment variables - name: PASSWORD valueFrom: secretKeyRef: name: my-secret key: password

Difference Between Mounting and Injecting ConfigMaps and Secrets

ConfigMaps and Secrets in Kubernetes allow you to inject configuration data into Pods at runtime. There are two ways to do this: mounting and injecting.

Mounting involves creating a volume in the Pod and adding the ConfigMap or Secret as a volume to that Pod. This allows you to access the data in the ConfigMap or Secret as files in the volume.

For example, if you have a ConfigMap named "my-config" with a key "config.txt", you can mount it in your Pod like this:

YAML
1234567891011121314
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container volumeMounts: - name: my-config-volume mountPath: /etc/config volumes: - name: my-config-volume configMap: name: my-config

You can then access the data in config.txt as a file at /etc/config/config.txt in your container.

Injecting, on the other hand, involves injecting the data directly into the Pod as environment variables or command-line arguments.

For example, if you have a Secret named my-secret with a key password.txt you can inject it into your Pod like this:

YAML
12345678910111213
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container env: - name: MY_PASSWORD valueFrom: secretKeyRef: name: my-secret key: password.txt

You can then access the value of password.txt as the environment variable MY_PASSWORD in your container.

In general, mounting is useful when you need to access the data as files in your container while injecting is useful when you need to pass the data to your application as environment variables or command-line arguments.

ConfigMaps and Secrets in the Kyma dashboard

In the Kyma dashboard, you can create, view, edit ,and delete ConfigMaps and Secrets. You can also use the dashboard to create a new deployment and assign a ConfigMap or Secret to it.

For both ConfigMaps and Secrets, you can see an overview of all existing resources for the current namespace by clicking on the corresponding menu item in the left navigation.

ConfigMaps Overview

After clicking on a ConfigMap or Secret, you can see the details of the resource. You can also edit the resource by clicking on the "Edit" button in the top right corner.

ConfigMap Details

For secrets by default, the values are base64 encoded. You can click on the "Decode" button to decode the values to plain text.

Secret Details

Summary

This lesson explained the concept of ConfigMaps and Secrets. You have learned when and how to use them and how you can create and manage them in the Kyma dashboard.

Further Reading

Log in to track your progress & complete quizzes