Mastering ConfigMaps and Secrets in Kubernetes

Ajay GiteAjay Gite
7 min read

Table of contents

ConfigMaps

A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or configuration files in a volume.

A ConfigMap allows you to decouple environment-specific configuration from your container images so that your applications are easily portable.

To create a ConfigMap from a literal value, use the following command:

kubectl create configmap configmap-1 --from-literal=name=first-configmap\
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-1
spec:
  containers:
  - name: demo-container
    image: nginx
    envFrom:
    - configMapRef:
       name: configmap-1
  • apiVersion: Specifies the Kubernetes API version being used, which is v1 in this case, representing the core API version for Kubernetes objects.

  • kind: Indicates the type of Kubernetes object being created. In this configuration, it's a Pod, indicating the creation of a Pod resource.

  • metadata: Contains metadata about the Pod, including its name.

  • spec: Defines the specification for the Pod, including its containers and other settings.

  • containers: Specifies an array of containers running within the Pod. In this case, there's one container named demo-container that uses the NGINX image.

  • envFrom: Specifies an array of environment variable sources for the container.

  • configMapRef: Specifies that the environment variable values should be sourced from a ConfigMap.

  • name: Specifies the name of the ConfigMap from which the environment variables will be sourced, and in this case, it's configmap-1.

To create a ConfigMap from multiple literal values, use the following command:

kubectl create configmap configmap-2 --from-literal=name=second-configmap --from-literal=color=blue
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-2
spec:
  containers:
  - name: demo-container
    image: nginx
    env:
    - name: COLOR
      valueFrom:   
        configMapKeyRef:   
          name: configmap-2
          key: color
  • apiVersion: Specifies the Kubernetes API version being used. In this case, it's v1, which is the core API version for Kubernetes objects.

  • kind: Specifies the type of Kubernetes object being created. In this configuration, it's a Pod, indicating the creation of a Pod resource.

  • metadata: Contains metadata about the Pod, such as its name.

  • spec: Defines the specification for the Pod, including its containers and other settings.

  • containers: Specifies an array of containers running within the Pod. In this case, there is one container named demo-container that uses the NGINX image.

  • env: Specifies an array of environment variables for the container.

  • name: Sets the name of the environment variable, which is COLOR in this case.

  • valueFrom: Indicates that the value of this environment variable will come from a source other than a static value.

  • configMapKeyRef: Specifies that the value of the environment variable should be sourced from a ConfigMap.

  • name: Specifies the name of the ConfigMap, which is configmap-2.

  • key: Identifies the key within the ConfigMap from which the value should be extracted, and in this case, it's color

To create a ConfigMap from a file, use the following command:

kubectl create configmap configmap-3 --from-file=data-file
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-3
spec:
  containers:
  - name: demo-container
    image: nginx
    volumeMounts:
      - name: config
        mountPath: /etc/config
  volumes:
  - name: config
    configMap:
      name: configmap-3
  • apiVersion: Specifies the Kubernetes API version being used, which is v1 in this case, represents the core API version for Kubernetes objects.

  • kind: Indicates the type of Kubernetes object being created. In this configuration, it's a Pod, indicating the creation of a Pod resource.

  • metadata: Contains metadata about the Pod, including its name.

  • spec: Defines the specification for the Pod, including its containers and volumes.

  • containers: Specifies an array of containers running within the Pod. There's one container named demo-container that uses the NGINX image.

  • volumeMounts: Specifies an array of volume mounts for the container. In this case, it defines a volume named config and mounts it at the path /etc/config within the container.

  • volumes: Specifies an array of volumes that can be mounted into the container. It defines a volume named config and configures it to use data from a ConfigMap named configmap-3.

  • configMap: Specifies that the volume named config should be populated with data from the ConfigMap named configmap-3.

🔹Secrets

In Kubernetes, a secret is an object that contains sensitive information, such as passwords, API keys, or certificates. Secrets are stored in the Kubernetes API server and are used to pass sensitive information to a container running in a pod.

Secrets can be created and managed using the kubectl command-line tool or through manifest files.

Let's explore three types of secrets along with examples:

Generic Secrets:

  • Generic secrets are the most basic type in Kubernetes, allowing you to store key-value pairs.

  • Example: Let's say you have an application that requires a database password. You can create a generic secret named db-secret with the password as the value:

kubectl create secret generic mysecret --from-literal=username=Gopa123 --from-literal=password=MySecurePassword123
kubectl get secrets

Once the secret is created, you can use it in a pod by referencing it in the pod's manifest file. For example, here's a pod manifest file that uses the my-secret secret:

# if we want to access specific variable from secret then we can use.
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo-1
spec:
  containers:
  - name: demo-container
    image: nginx
    env:
    - name: Username
      valueFrom:   
        secretKeyRef:   
          name: db-secret
          key: username

or
# if we want to access all variable from the secret then we can use.
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo-1
spec:
  containers:
  - name: demo-container
    image: nginx
    envFrom:
    - secretRef:
       name: docker-secret
kubectl apply -f my-secret-pod.yml
kubectl exec secret-demo-1 -it -- printenv

Docker-Registry Secrets:

  • Docker-registry secrets are used when pulling images from private Docker registries that require authentication.

  • Example: If your application uses a private Docker registry, you can create a Docker-registry secret named docker-secret with the registry credentials:

kubectl create secret docker-registry docker-secret --docker-email=example@gmail.com --docker-username=dev --docker-password=pass1234 --docker-server=my-registry.example:5000
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo-2
spec:
  containers:
  - name: demo-container
    image: nginx
    envFrom:
    - secretRef:
       name: docker-secret
kubectl apply -f <file-name.yaml>
kubectl exec secret-demo-2 -it -- printenv

TLS Secrets:

  • TLS secrets are used to secure communication over HTTPS or other TLS-enabled protocols.

  • Example: Suppose you want to secure communication for your application with an SSL/TLS certificate. You can create a TLS secret named tls-secret by providing the certificate and key files:

kubectl create secret tls my-tls-secret --cert=/root/data/serverca.crt --key=/root/data/servercakey.pem
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo-3
spec:
  containers:
  - name: demo-container
    image: nginx
    volumeMounts:
      - name: data
        mountPath: /etc/cert-data
  volumes:
  - name: data
    secret:
      secretName: my-tls-secret
kubectl apply -f <file-name.yaml>
kubectl exec -it <pod-name> -- bash
cd /etc/cert-data
ls

Secrets and ConfigMaps in Kubernetes serve different purposes and are used based on the sensitivity of the data being stored and the security requirements of your application. Here's an explanation of when and why you might use Secrets over ConfigMaps and the drawbacks of using ConfigMaps for sensitive data:

When to Use Secrets Instead of ConfigMaps:

  1. Sensitive Data: Secrets are designed to store sensitive information, such as passwords, API tokens, or SSL certificates. These pieces of data should not be exposed in plain text.

  2. Base64 Encoding: Secrets can store binary data, while ConfigMaps are intended for plain text data. Secrets can encode binary data (e.g., SSL certificates) using Base64 encoding, preserving the data's integrity.

  3. Encryption: Kubernetes encrypts Secret data at rest, adding an extra layer of security for sensitive information.

  4. Authentication and Authorization: Kubernetes provides more fine-grained control over access to Secrets, allowing you to define who can read and write Secret data, enhancing security.

Drawbacks of Using ConfigMaps for Sensitive Data:

  1. Lack of Encryption: ConfigMaps do not provide encryption for data at rest. Sensitive information stored in ConfigMaps is vulnerable if an attacker gains access to the cluster's underlying storage.

  2. Limited Access Control: ConfigMaps have less granular access control compared to Secrets. Anyone with access to the namespace can read the data stored in a ConfigMap.

  3. Base64 Encoding Issues: While you can store binary data in ConfigMaps using Base64 encoding, it can lead to increased complexity, potential errors, and difficulties in managing binary content.

0
Subscribe to my newsletter

Read articles from Ajay Gite directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ajay Gite
Ajay Gite