Day 35: 90DaysOfChallenge

Day 35: 90DaysOfChallenge

Mastering ConfigMaps and Secrets in Kubernetes🔒🔑🛡️

ConfigMap

A ConfigMap is an API object used to store non-sensitive configuration data in key-value pairs. It is used to store configuration data such as environment variables, command-line arguments, configuration files, etc., which can then be injected into pods as environment variables or mounted as files. ConfigMaps are typically used for configuration that can be openly exposed to anyone with access to the cluster.

Secrets

Secrets are similar to ConfigMaps but specifically designed to store sensitive information such as passwords, API keys, TLS certificates, etc. Unlike ConfigMaps, Secrets store their data encrypted at rest in etcd (the Kubernetes datastore). Secrets is used for sensitive information that should not be exposed in plain text within the cluster or to users who can access the cluster. Kubernetes handles the encryption and decryption of secrets automatically.

So, while both ConfigMaps and Secrets serve the purpose of providing configuration data to Kubernetes objects, Secrets are specifically designed for sensitive information and are encrypted at rest.

Prerequisite

  • Create a Deployment File for MySQL.

Before creating a ConfigMap, let's create a Deployment file for MySQL.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
  namespace: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:8
        name: mysql
        ports:
        - containerPort: 3306
          name: mysql

Let's create a namespace named mysql -

Let's apply the deployment kubectl apply -f deployment.yml -n mysql and check whether pod is created or not - kubectl get pods -n mysql

The pod is created but it ran into an CrashLoopBackOff error. CrashLoopBackOff is a common error message that occurs when a K8S container fails to start up properly for some reason, and then repeatedly crashes. Let's create a ConfigMap containing the Database name and fetch the environment variable in our deployment file.

Task 1:

  • Create a ConfigMap for your Deployment.

Let's create a ConfigMap.yml file containing the environment variables of mysql.

apiVersion: v1
kind: ConfigMap
metadata: 
  name: mysql-configmap
  namespace: mysql
  labels:
    app: mysql
data:
  MYSQL_DATABASE: "cooldb"

The environment variable is stored inside data object containing the variable name and it's value which can further be used in our deployment file.

  • Apply the configMap.yml using the command: kubectl apply -f <configMap-file> -n <namespace>

    Apply the configMap using kubectl apply -f configMap.yml -n mysql. It creates a configMap.

  • Update the deployment.yml file to include the ConfigMap.

    As we have added the database name in ConfigMap, let's fetch the variable in our deployment file as below -

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
  namespace: mysql

spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:8
        name: mysql
        ports:
        - containerPort: 3306
          name: mysql
        env:
          - name: MYSQL_DATABASE
            valueFrom:
              configMapKeyRef:
                name: mysql-configmap
                key: MYSQL_DATABASE

Inside the env(environement variable), valueFrom object is used where we can mention the different types of file which we want to use in our container. Over here, we need to fetch values from ConfigMap, hence, we we use configMapKeyRef and define the name and the key same as the one mentioned in configMap.

  • Apply the updated deployment using the command: kubectl apply -f <deployment-file> -n <namespace-name>

After updating the deployment file, apply it again to update the configuration using kubectl apply -f deployment.yml -n mysql

  • Verify that the ConfigMap has been created by checking the status of the ConfigMaps in your Namespace.

    Check whether ConfigMap is created inside the specified namespace or not by using - kubectl get cm -n mysql Here, cm is the short form for ConfigMap.

    Let's see after applying the configMap and deployment file, pods are running or not using kubectl get pods -n mysql -o wide. The pod is still showing crashLoopBackOff error -

    Let's provide the root password of mysql in secret file.

Task 2:

  • Create a Secret for your Deployment.

apiVersion: v1
kind: Secret
metadata:
   name: mysql-secret
   namespace: mysql
   labels:
       app: mysql
type: Opaque
data:
  MYSQL_PASSWORD: dGVzdEAcMjM=

In the same way as ConfigMap the environment variable is stored inside data object containing the variable name and it's value which can further be used in our deployment file. When creating a Secret, we can also specify its type using the type field of the Secret resource, or certain equivalent kubectl command line flags (if available). The Secret type is used to facilitate programmatic handling of the Secret data. Here, the type used is Opaque.

  • Apply the secret.yml using the command: kubectl apply -f <secret-file> -n <namespace>

Apply the secret file using kubectl apply -f secret.yml -n mysql

  • Update the deployment.yml file to include the Secret.

    As we have created the secret file, let's attach the data variables from secret file to deployment file.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
  namespace: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:8
        name: mysql
        ports:
        - containerPort: 3306
          name: mysql
        env:
          - name: MYSQL_DATABASE
            valueFrom:
              configMapKeyRef:
                name: mysql-configmap
                key: MYSQL_DATABASE

          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql-secret
                key: MYSQL_PASSWORD

Inside the env(environement variable), valueFrom object is used where we mention the different types of file which we want to use in our container. Over here, we need to fetch values from Secret, hence, we use secretMapKeyRef and define the name and the key same as the one mentioned in Secret.

  • Apply the updated deployment using the command: kubectl apply -f deployment.yml -n <namespace-name>

Update the deployment file again to apply the changes using kubectl apply -f deployment.yml -n mysql

  • Verify that the Secret has been created by checking the status of the Secrets in your Namespace.

    Check whether the secret is created or not by using kubectl get secret -n mysql

    Let's see after applying the configMap, secret and deployment file, pods are running or not. We can see the pod is running without throwing any error when we use kubectl get pods -n mysql -o wide

    Let's get inside the container and check whether we are able to see our "cooldb" database or not by using kubectl exec -it <pod-name> -n <name-space> bash Once, we enter the bash command line, give mysql -u root -p and provide the password that you have set in the Secret file to get access to the MySQL container. Use command show databases; to list all the database present in the MySQL. We can see "cooldb" database is present.

      $ kubectl exec -it <pod-name> -n <name-space> bash
      bash# mysql -u root -p
      Enter password:
      mysql> show databases;
    

    Yiipppee!!! "cooldb" database is created and visible inside the container. We have completed our Day 35 Challenge and learnt how to create ConfigMap and Secret file in Kubernetes and use them in the running pods by attaching them in Deployment File.

Thanks for reading!
Happy Learning!