Mastering ConfigMaps and Secrets in Kubernetes

Dhwarika JhaDhwarika Jha
6 min read

What is ConfigMaps?

  • According to kubernetes.io, a ConfigMap is an API object used to store non-confidential data in key-value pairs.

  • ConfigMaps are used to store configuration data that can be consumed by pods or other Kubernetes resources.

  • ConfigMaps are typically used to store non-sensitive configuration data such as environment variables, command-line arguments, or configuration files. This data can be accessed by pods as environment variables or mounted as files.

  • A ConfigMap is not designed to hold large chunks of data. The data stored in a ConfigMap cannot exceed 1 MiB.

  • There are four different ways that you can use a ConfigMap to configure a container inside a Pod:

    1. Inside a container command and args

    2. Environment variables for a container

    3. Add a file in read-only volume, for the application to read

    4. Write code to run inside the Pod that uses the Kubernetes API to read a ConfigMap

What is Secrets?

  • According to kubernetes.io, a Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key.

  • Secrets are used to store sensitive information such as passwords, API keys, and TLS certificates. Secrets provide a secure way to store and manage this confidential data within a cluster. They are similar to ConfigMaps but are specifically designed to handle sensitive information.

  • There are three main ways for a Pod to use a Secret:

    1. As files in a volume mounted on one or more of its containers.

    2. As container environment variable.

    3. By the kubelet when pulling images for the Pod.

Difference between ConfigMaps and Secrets in Kubernetes.

Criteria

ConfigMaps

Secrets

Purpose

Store non-sensitive configuration data.

Store sensitive information.

Data Types

Text files, key-value pairs, or environment variables. ConfigMaps store data as plain text

Text files, key-value pairs, or environment variables. Secrets can store data as base64-encoded or opaque.

Data Visibility

Data is visible in plain text to anyone with access.

Data is encrypted and stored securely.

Use Cases

Configuration files, environment variables, and command-line options.

Passwords, API keys, TLS certificates, secrets.

Security

No encryption or protection of data.

Data is encrypted and stored securely.

Accessing Data

Accessed as environment variables or mounted as files.

Accessed as environment variables or mounted as files.

Update Dynamics

Changes require pod restarts to take effect.

Changes are dynamically updated without pod restarts.

Namespaces

ConfigMaps can be shared across namespaces.

Secrets are limited to a single namespace.

Kubernetes Objects

ConfigMaps are represented as ConfigMap objects.

Secrets are represented as Secret objects.

Creation

Data is provided directly in the YAML file or from files.

Data is provided directly in the YAML file or from files.

Access Control

ConfigMaps have no built-in access control mechanisms.

Secrets can be granted specific access controls.

Use in Pods

ConfigMaps can be used in any pod.

Secrets are primarily used by pods for sensitive data.

Volume Mounts

ConfigMaps can be mounted as volumes in pods.

Secrets can also be mounted as volumes in pods.

Data Size

ConfigMaps can store larger amounts of data.

Secrets have size limitations based on the backend storage.

Backup and Restore

ConfigMaps are easily backed up and restored.

Secrets require additional security measures for backup and restoration.

Data Modification

ConfigMap data can be modified without restarting pods.

Secrets require pod restarts for data modification.

Let's start with the tasks now to learn and master ConfigMaps and Secrets.

Tasks 1

Create a ConfigMap for your Deployment.

  • Let's create a mysql-config.yml file.

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: todo-app
        labels:
          app: todo-app
        namespace: todo-app
      data:
        MYSQL_DB: "database_todo"
    
  • This YAML file creates a ConfigMap object that stores a single configuration setting, MYSQL_DBwith the value "database_todo". This ConfigMap can be used by a pod in the deploy1 namespace to access this configuration setting as an environment variable or a file in a mounted volume.

  • Now apply the configmap.yml file to your deployment.

      kubectl apply -f configmap.yml
      kubectl get configmap -n <namespace> #To verify the ConfigMap creation
    

  • The ConfigMap is created successfully.

Task 2

Create a Secret for your Deployment

Before creating Secrets, let us encrypt the username and password.

  • For example, I have taken password= test@123

  • In your terminal, using base64 you can encode and decode:

  •   echo -n 'test@123' | base64
    

  • You can verify the encrypted characters by using the following:

      echo dGVzdEAxMjM= | base64 --decode
    

  • What is base64?

    Base64 is a binary-to-text encoding scheme that represents binary data in sequences of 24 bits that can be represented by four 6-bit Base64 digits.

    It is always better to not use hardcoded values for data like usernames and passwords.

    I am going to use these encoded characters in the mysql-secret.yml file that I am going to create now.

    COPY

      apiVersion: v1
      kind: Secret
      metadata:   
        name: my-secret
        namespace: todo-app
      type: Opaque
      data:
        password: dGVzdEAxMjM=
    
  • This YAML file creates a Secret object that stores a single piece of sensitive data, passwordwith the value admin@123. This Secret can be used by a pod in the deploy1 namespace to access this sensitive data as an environment variable or a file in a mounted volume. The value is encoded in base64 format to protect it from being exposed accidentally or stored in a terminal log.

  • What's the type: Opaque mentioned here in the above code block?

    In Kubernetes, type: Opaque is the default type for a Secret object.

    It means that the contents of the Secret are unstructured and can contain arbitrary key-value pairs.

    Opaque Secrets are used to store arbitrary user-defined data, such as passwords, OAuth tokens, and ssh keys.

    Other types of Secrets include Service account token secrets (store a token that references a service account.), Docker registry secrets (store credentials for accessing a Docker registry), and TLS secrets (store TLS certificates and keys).

  • Let's apply the secret to deployment.

      kubectl apply -f mysql-secret.yaml -n <namespace>
    
  • We can verify the creation of secrets using:

      kubectl get secrets -n <namespace>
    

  • Update the sqldeployment.yml with the secrets and config map.

       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: mysql-configuration
         labels:
           app: mysql
         namespace: todo-app 
       spec:
         replicas: 2
         selector:
           matchLabels:
             app: mysql
         template:
           metadata:
             labels:
               app: mysql
           spec:
             containers:
             - name: mysql-container
               image: mysql:8
               ports:
               - containerPort: 3306
               env:
               - name: MYSQL_ROOT_PASSWORD
                 valueFrom:
                   secretKeyRef:
                     name: my-secret
                     key: password
               - name: MYSQL_DATABASE
                 valueFrom:
                   configMapKeyRef:
                     name: my-configmap
                     key: MYSQL_DB
    
  • Let's apply this to the cluster.

      kubectl apply -f sqldeployment.yaml
    
  • Let's verify if the pods are running.

      kubectl get pods -n <namespace>
    

    pods are created.

  • we need to use the MySQL service. For that, we will have to expose the k8s cluster to a port. I will create a sqlservice.yaml for that.

       apiVersion: v1
       kind: Service
       metadata:
         name: mysql-service-configuration
         namespace: todo-app
       spec:
         ports:
         - name: mysql
           port: 3306
         clusterIP: None
         selector:
           app: mysql
    
  • And apply to the cluster.

      kubectl apply -f sqlservice.yaml
    
  • Get inside the worker node and install the MYSQL client.

      sudo apt install mysql-client-core-8.0
    
  • Now on the controller, connect to any node:

      kubectl exec -it mysql-configuration-858b8c57ff-g87gz /bin/sh -n todo-app
    
  • Connect using the username and password you gave in the secret.yml file.

       mysql -u root -p${MYSQL_ROOT_PASSWORD}
    
  • Now we are in the MYSQL console. We can see the databases in the container using show databases;

#Day35 #90daysofdevops

Thankyou.....

0
Subscribe to my newsletter

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

Written by

Dhwarika Jha
Dhwarika Jha