K8s: ConfigMaps & Secrets
What are ConfigMaps in K8s?
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 as 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.
Note:
ConfigMap does not provide secrecy or encryption. If the data you want to store are confidential, use a Secret rather than a ConfigMap, or use additional (third party) tools to keep your data private.
Key Features:
Decouples configuration data from the application code.
Allows sharing of configuration across multiple pods.
Can be used to inject configuration as environment variables or files inside containers.
Pods use config maps through environment variables and configMap volumes.
Why we need ConfigMap?
Applications often need configuration data that changes between environments (e.g., development, testing, production). Hardcoding these values into your application makes it less portable and harder to manage across environments.
Using ConfigMap allows you to store non-sensitive configuration data separately, making your application flexible and environment-independent.
- Example: Configuration values like API endpoints, external service URLs, application settings, etc., vary depending on the environment in which the app is deployed. These values can be dynamically provided using ConfigMaps.
Deploying the same pod manifest and different config map manifests in different environments:
What are Secrets in K8s?
A Secret in Kubernetes stores sensitive data like passwords, tokens, or keys securely, so you don't have to include them in your application's code or Pod specification. Secrets are stored in a base64-encoded format and ensure encryption when transferred or stored. This reduces the risk of exposing sensitive information during application setup or changes.
Key Features:
Secures sensitive data such as passwords, API keys, and certificates.
Can be mounted as environment variables or files in containers.
Supports encryption to prevent accidental exposure of sensitive data.
When to use Secrets?
Secrets are used to store sensitive information, such as passwords, API tokens, or SSH keys, in a secure manner. Kubernetes Secrets keep this data encrypted and ensure that only authorized applications have access to it, enhancing security.
- Example: A database password, an API key for third-party services, or TLS certificates would all be stored securely in a Kubernetes Secret.
How to Use ConfigMap and Secrets in Real-time Projects:
In Kubernetes, ConfigMaps and Secrets are stored as objects within the cluster's etcd database.
ConfigMaps store non-sensitive configuration data in plain text.
Secrets store sensitive data, such as passwords, in base64-encoded format and can be encrypted at rest using encryption at the cluster level.
You create a ConfigMap and inject its values into your application via environment variables or mounted files.
ConfigMaps and Secrets in Kubernetes can be used in several ways:
As Environment Variables: You can inject data from ConfigMaps or Secrets into Pods by referencing them as environment variables.
Mounted as Volumes: Both ConfigMaps and Secrets can be mounted as files in containers, allowing applications to read configuration or sensitive data directly from a file system.
In Command-line Arguments: ConfigMaps can also be used to pass configuration as arguments when starting a container, offering more control over dynamic setups.
Industry Preference in Real-Time:
Environment Variables are the preferred method for most cloud-native, microservice, and modern application deployments due to their simplicity and wide support in modern frameworks.
Mounted Volumes are used in cases where file-based configuration is mandatory, or when handling sensitive information that should not be exposed through environment variables.
Command-line Arguments are less common in web applications but are used for specialized workflows like scheduled jobs or processes that require argument-based customization.
Here are the example ConfigMap and Secrets YAML files along with the necessary changes to your MySQL DB Deployment and PetClinic App Deployment to reference them as environment variables.
ConfigMap (app-config.yaml)
- This ConfigMap stores non-sensitive environment variables, such as database name, JDBC URL, etc.
CopyapiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: dev
data:
MYSQL_URL: jdbc:mysql://mysql-service:3306/petclinic
MYSQL_DATABASE: petclinic
Secrets (db-secrets.yaml)
This Secret stores sensitive information like MySQL credentials.
CopyapiVersion: v1
kind: Secret
metadata:
name: db-secrets
namespace: dev
type: Opaque
data:
MYSQL_USER: cGV0Y2xpbmlj # base64 encoded value of 'petclinic'
MYSQL_PASSWORD: cGV0Y2xpbmlj # base64 encoded value of 'petclinic'
MYSQL_ROOT_PASSWORD: cm9vdA== # base64 encoded value of 'root'
To generate base64 encoded values for your secrets, you can use this command:
Copyecho -n "your-value" | base64
MySQL DB Service: mysql-service.yaml
CopyapiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: dev
spec:
type: ClusterIP
ports:
- port: 3306
targetPort: 3306
selector:
app: mysql
MySQL DB Deployment: mysql-deployment.yaml
CopyapiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-db
namespace: dev
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.4
ports:
- containerPort: 3306
env:
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_PASSWORD
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: app-config
key: MYSQL_DATABASE
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql-persistent-storage
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc
PetClinic App Service: petclinic-service.yaml
CopyapiVersion: v1
kind: Service
metadata:
name: petclinic-service
namespace: dev
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30007
selector:
app: petclinic
PetClinic App Deployment
CopyapiVersion: apps/v1
kind: Deployment
metadata:
name: petclinic-app
namespace: dev
spec:
replicas: 2
selector:
matchLabels:
app: petclinic
template:
metadata:
labels:
app: petclinic
spec:
containers:
- name: petclinic
image: subbu7677/petclinic-spring-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_URL
valueFrom:
configMapKeyRef:
name: app-config
key: MYSQL_URL
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_PASSWORD
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: app-config
key: MYSQL_DATABASE
volumeMounts:
- mountPath: /tmp/cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
Summary:
ConfigMap (app-config.yaml):
Stores non-sensitive data like
MYSQL_URL
andMYSQL_DATABASE
.These are used in the PetClinic and MySQL deployments to dynamically inject configuration.
Secrets (db-secrets.yaml):
Stores sensitive information such as the MySQL username, password, and root password.
The values are base64-encoded to ensure secure management in Kubernetes.
Deployment Updates:
MySQL Deployment:
The environment variables
MYSQL_USER
,MYSQL_PASSWORD
, andMYSQL_ROOT_PASSWORD
now refer to the Secrets.MYSQL_DATABASE
refers to the ConfigMap.
PetClinic Deployment:
The environment variables for
MYSQL_URL
,MYSQL_DATABASE
refer to the ConfigMap.The
MYSQL_USER
,MYSQL_PASSWORD
, andMYSQL_ROOT_PASSWORD
refer to the Secrets for security.
Our Project ConfigMap & Secrete Objects:
Persistent Volume and Persistent Volume Claim:
All Resources along with MySQL-DB-Deployment and Petclinic-Deployment:
We have successfully deployed our PetClinic application along with the MySQL database using ConfigMap and Secret objects, avoiding hard-coded environment variables. The application is accessible outside the cluster, allowing us to create new owners and pets, and fully explore its features.
Best Practices in Real-time Projects
Separation of Concerns: Keep configuration and sensitive information out of your container images and store them in ConfigMaps and Secrets.
Environment-specific Configurations: Use ConfigMaps and Secrets to handle environment-specific settings, allowing the same container image to run in multiple environments.
Security: Regularly rotate Secrets and ensure they are encrypted at rest and in transit. Limit access to Secrets to only those containers that require it.
Auditing: Enable audit logs to track access to Secrets.
Backup & Recovery: Ensure that both ConfigMaps and Secrets are part of your disaster recovery plan.
Best Use Cases for Kubernetes ConfigMap
Application Configuration Across Environments:
Use Case: Manage environment-specific settings like URLs, log levels, etc., that change between development, staging, and production.
Example: Storing
API_URL
orLOG_LEVEL
as environment variables.
External Services Configuration:
Use Case: Apps that connect to external services like APIs or message queues need to adjust settings across environments.
Example: Storing API or message broker URLs in a ConfigMap.
Tuning Application Settings Without Rebuilding:
Use Case: Modify settings like timeouts or cache sizes without rebuilding the app.
Example: Changing
REQUEST_TIMEOUT
orMAX_CONNECTIONS
through a ConfigMap.
Configuration Sharing Across Pods:
Use Case: Multiple instances of an app share the same configuration.
Example: Microservices using the same API keys or service discovery URLs.
Injecting Configuration Files:
Use Case: Some apps require configuration files instead of environment variables.
Example: Injecting
application.properties
orconfig.json
into pods.
Best Use Cases for Kubernetes Secrets
Database Credentials Management:
Use Case: Securely store database credentials like usernames and passwords.
Example: Inject
DB_USERNAME
andDB_PASSWORD
from Secrets.
API Keys and Tokens:
Use Case: Safely store API keys and tokens needed for third-party services.
Example: Injecting API keys for services like Stripe or PayPal.
TLS/SSL Certificates:
Use Case: Provide certificates for secure communication (HTTPS).
Example: Storing SSL certificates in a Secret and using them in web servers.
SSH Keys for Secure Access:
Use Case: Securely store SSH keys to access servers or services.
Example: Injecting SSH keys for secure connections.
Docker Registry Credentials:
Use Case: Authenticate to private Docker registries.
Example: Storing Docker credentials to pull private images.
Encrypting Sensitive Settings:
Use Case: Securely manage sensitive configuration like encryption keys.
Example: Store and access encryption keys or session tokens using Secrets.
Securing Access to Cloud Services:
Use Case: Safely store cloud service credentials.
Example: Inject AWS or GCP credentials to access cloud services.
"The capacity to learn is a gift, the ability to learn is a skill, the willingness to learn is a choice." — Brian Herbert
Thank you, Happy Learning!
Subscribe to my newsletter
Read articles from Subbu Tech Tutorials directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by