ConfigMaps and Secrets are fundamental Kubernetes objects that enable you to decouple configuration data from your application code, a core tenet of building cloud-native applications and the 12-factor app methodology. A ConfigMap is designed to store non-sensitive configuration data such as database hosts, API endpoints, log levels, or application-specific settings. By externalizing this data, your application images remain generic and portable, allowing you to easily reuse them across different environments (dev, staging, prod) simply by swapping out the ConfigMap. Applications running in a Pod can consume ConfigMap data in various ways: as environment variables, as files mounted into the Pod, or even as command-line arguments. This flexibility ensures your applications get the correct settings without needing to be rebuilt or redeployed.
While ConfigMaps handle general configuration, Secrets are specifically designed for sensitive information like passwords, API keys, OAuth tokens, SSH keys, or TLS certificates. The primary distinction from ConfigMaps is security: Kubernetes stores Secrets encrypted at rest (though this depends on the underlying storage and configuration) and provides tighter access controls via Role-Based Access Control (RBAC). This ensures that only authorized Pods and users can access sensitive data. Like ConfigMaps, Secrets can be mounted as environment variables or as files within a Pod, making them readily available to your application without hardcoding them directly into images or application code.
Practically, you'll often define both ConfigMaps and Secrets in your Kubernetes manifests to configure a single application. For instance, a database Pod might use a ConfigMap for its connection string's non-sensitive parts (e.g., host, port) and a Secret for the username and password. This separation not only enhances security but also simplifies configuration management, allowing you to update settings or credentials independently of your application deployment. For production-grade secret management, consider integrating Kubernetes Secrets with external solutions like HashiCorp Vault or cloud-provider KMS services for even greater security and lifecycle control.
Key Takeaways
- ConfigMaps store non-sensitive configuration, decoupling it from application code.
- Secrets store sensitive data like passwords and API keys, with enhanced security features.
- Both can be consumed by Pods as environment variables or mounted files.
- Essential for building portable, reusable, and secure cloud-native applications.
- Always prioritize security; for production, consider external secret management tools.
Code Example
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
spec:
containers:
- name: my-container
image: nginx:latest
env:
- name: APP_CONFIG_SETTING
valueFrom:
configMapKeyRef:
name: app-config-map
key: my_setting
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-map
data:
my_setting: "production_value"
---
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque # or kubernetes.io/basic-auth, etc.
data:
username: "dXNlcg==" # base64 encoded "user"
password: "cGFzc3dvcmQ=" # base64 encoded "password"How this code works
The code demonstrates how to inject configuration and sensitive credentials into a Kubernetes Pod using ConfigMap and Secret objects. Its job is to define a running application container (my-app-pod) and provide it with specific environment variables without hardcoding those values directly into the pod definition. This modular approach allows for easier updates to settings and better security for sensitive data.
The Pod requests its configuration via valueFrom in the env section. For non-sensitive settings, configMapKeyRef references the app-config-map to set APP_CONFIG_SETTING from the my_setting key. For sensitive data, secretKeyRef points to db-credentials to inject the password value into DB_PASSWORD. A subtle but crucial point for beginners is that Secret values like username and password are stored as base64 encoded strings in the YAML; Kubernetes automatically decodes them before making them available inside the container. The type: Opaque simply denotes a generic secret without Kubernetes imposing specific interpretation rules.