Managing Configuration and Secrets in Kubernetes
Modern applications require dynamic configuration management and secure handling of sensitive data. Kubernetes offers ConfigMaps and Secrets to handle these requirements efficiently, allowing you to decouple configuration from application code and manage sensitive information securely.
Introduction
In the traditional monolithic application days, environment variables and configurations were bundled up with the application and deployed as one large object. However, in the cloud-native application model it's important to decouple these for many reasons:
- Environment Flexibility: Decoupling allows the same application to run across different environments (development, staging, production) without code changes. Environment-specific configurations can be applied externally, improving the portability of the application.
- Scalability and Dynamic Management: When configuration is externalized, it's easier to scale applications horizontally since the configuration can be managed and applied independently. This allows for dynamic reconfiguration in response to changes in load or other factors without redeploying or restarting containers.
- Security and Sensitive Data Handling: Keeping sensitive configuration data, such as secrets and credentials, separate from the application codebase helps maintain security. It ensures that sensitive data is not exposed within the code and can be securely managed using secrets management tools.
- Continuous Deployment and Rollbacks: Decoupling facilitates continuous deployment practices by allowing configurations to be updated independently of the application. This separation also simplifies rollback procedures in case a configuration change needs to be reverted without affecting the application version that's running.
- Maintainability and Clarity: Keeping configuration separate from application code helps maintain a clean codebase and makes it clearer for developers to understand the application logic. It avoids cluttering the application with environment-specific conditionals and settings, making the code easier to maintain and evolve.
Understanding ConfigMaps
What are ConfigMaps?
ConfigMaps store non-sensitive configuration data as key-value pairs. They are first-class objects in the Kubernetes API, making them stable and widely supported.
Use Cases for ConfigMaps
ConfigMaps are used to store:
- Environment variables
- Configuration files (e.g., web server configs)
- Hostnames
- Service ports
- Account names
Avoid storing sensitive data in ConfigMaps; use Secrets for that purpose.
Creating ConfigMaps
ConfigMaps can be created imperatively or declaratively.
Imperative Creation
Create a ConfigMap with literal values:
Create a ConfigMap from a file:
Declarative Creation
Define a ConfigMap in a YAML file (configmap.yaml
):
Apply the YAML file:
Using ConfigMaps
Inject ConfigMap data into Pods using environment variables, command arguments, or volumes.
As Environment Variables
Define environment variables in the Pod specification:
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app-container
image: myapp:latest
env:
- name: ENV
valueFrom:
configMapKeyRef:
name: app-config
key: env
- name: DEBUG
valueFrom:
configMapKeyRef:
name: app-config
key: debug
As Volumes
Mount the ConfigMap as a volume:
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
volumes:
- name: config-volume
configMap:
name: app-config
containers:
- name: app-container
image: myapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
Kubernetes-Native Applications
Kubernetes-native applications can access ConfigMap data directly via the API server, simplifying configuration management and reducing dependencies on environment variables or volumes.
Understanding Secrets
What are Secrets?
Secrets store sensitive data such as passwords, tokens, and certificates. They are similar to ConfigMaps but are designed to handle sensitive information securely.
Are Kubernetes Secrets Secure?
By default, Kubernetes Secrets are not encrypted in the cluster store or in transit. They are base64-encoded, which is not secure. To enhance security, use additional tools like HashiCorp Vault for better encryption.
Creating Secrets
Secrets can also be created imperatively or declaratively.
Imperative Creation
Create a Secret with literal values:
$ kubectl create secret generic db-credentials --from-literal=username=dbuser --from-literal=password=securepass
Declarative Creation
Define a Secret in a YAML file (secret.yaml
):
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: ZGJ1c2Vy
password: c2VjdXJlcGFzcw==
Apply the YAML file:
Using Secrets
Inject Secret data into Pods using environment variables, command arguments, or volumes.
As Volumes
Mount the Secret as a volume:
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: db-credentials
containers:
- name: app-container
image: myapp:latest
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
Hands-On Examples
Example ConfigMap
Create a ConfigMap with configuration data:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-config
data:
APP_ENV: "production"
APP_DEBUG: "false"
Deploy and inspect the ConfigMap:
Example Secret
Create a Secret with sensitive data:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: ZGJ1c2Vy
password: c2VjdXJlcGFzcw==
Deploy and inspect the Secret:
Summary
ConfigMaps and Secrets are essential tools in Kubernetes for managing application configuration and sensitive data. By decoupling configuration from application code and handling sensitive information securely, you can create more flexible, maintainable, and secure applications.