Mastering ConfigMaps and Secrets in Kubernetes
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:
Inside a container command and args
Environment variables for a container
Add a file in read-only volume, for the application to read
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:
As files in a volume mounted on one or more of its containers.
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_DB
with the value"database_todo"
. This ConfigMap can be used by a pod in thedeploy1
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,
password
with the valueadmin@123
. This Secret can be used by a pod in thedeploy1
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.....
Subscribe to my newsletter
Read articles from Dhwarika Jha directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by