Introduction to Kubernetes ConfigMaps and Secrets
You've probably deployed a containerized application to Kubernetes and immediately hit a wall: how do you manage configuration values without hardcoding them into your Docker images? How do you handle sensitive data like API keys and database passwords securely? If you're struggling with environment variables scattered across multiple files or secrets committed to version control, you're not alone. This is where Kubernetes ConfigMaps and Secrets come in.
In this guide, you'll learn how to separate configuration from container images, manage non-sensitive configuration with ConfigMaps, and handle sensitive data securely with Secrets. You'll see practical examples of how to use these resources in real deployments, understand the key differences between them, and learn best practices that will keep your applications maintainable and secure.
What Are ConfigMaps and Secrets?
Think of ConfigMaps as a key-value store for non-sensitive configuration data. They allow you to externalize configuration from your container images, making your deployments more flexible and easier to manage. When you need to change a setting—like a database URL, feature flags, or application thresholds—you can update the ConfigMap without rebuilding your image.
Secrets are similar to ConfigMaps but designed specifically for sensitive data. They store passwords, OAuth tokens, SSH keys, and other credentials that shouldn't be exposed in plain text. Kubernetes encrypts Secrets at rest and provides additional security controls to prevent accidental exposure.
ConfigMaps: Managing Non-Sensitive Configuration
Basic ConfigMap Structure
A ConfigMap is a Kubernetes resource that stores non-confidential data in key-value pairs. Here's a simple example:
This ConfigMap defines three configuration values that your application can read at runtime. The data section contains the actual key-value pairs, while metadata.name gives the ConfigMap a unique identifier.
Mounting ConfigMaps as Files
The most common way to use ConfigMaps is to mount them as files in your container's filesystem. This approach works well for applications that read configuration from files rather than environment variables.
In this example, the ConfigMap app-config is mounted to /etc/config inside the container. Each key-value pair becomes a separate file, so database-url becomes /etc/config/database-url containing the database connection string.
Using ConfigMaps as Environment Variables
Many applications prefer to read configuration from environment variables. Kubernetes makes this easy with the envFrom field:
This mounts all keys from app-config as environment variables in the container. The database-url key becomes the DATABASE_URL environment variable (Kubernetes automatically converts keys to uppercase and replaces dots with underscores).
ConfigMap with Multiple Data Sources
You can define ConfigMaps using different data sources:
The from-file key demonstrates how you can include multi-line configuration directly in the ConfigMap definition.
Secrets: Handling Sensitive Data Securely
Basic Secret Structure
Secrets work similarly to ConfigMaps but are designed for sensitive data. Here's an example:
Notice that the values are base64-encoded. This is intentional—Secrets are stored as base64-encoded strings in etcd, not in plain text. However, base64 encoding is not encryption; it's just a way to represent binary data as text.
Creating Secrets from Strings
You can create Secrets directly from strings without manual base64 encoding:
The stringData field is decoded to base64 when the Secret is created, making it much easier to work with.
Mounting Secrets as Files
Like ConfigMaps, Secrets can be mounted as files:
The Secret is mounted to /etc/secrets inside the container, with each key becoming a file. The file contents are decoded from base64, so your application receives the actual sensitive data.
Using Secrets as Environment Variables
Secrets can also be used as environment variables:
This approach gives you fine-grained control over which secrets are exposed as environment variables.
Key Differences Between ConfigMaps and Secrets
| Feature | ConfigMap | Secret |
|---|---|---|
| Purpose | Non-sensitive configuration | Sensitive data |
| Storage | Base64 encoded | Base64 encoded |
| Encryption | No | Yes (at rest) |
| Access control | RBAC applies | RBAC applies |
| Mount as files | Yes | Yes |
| Use as env vars | Yes | Yes |
| Image pull secrets | No | Yes |
The most important distinction is security. Secrets are encrypted at rest in etcd and have additional access controls. ConfigMaps are not encrypted and should never contain sensitive data.
Practical Example: Deploying an Application with Configuration
Let's walk through a complete example of deploying an application with both ConfigMaps and Secrets.
Application Requirements
Your application needs:
- A database connection string (sensitive)
- Feature flags (non-sensitive)
- Log level configuration (non-sensitive)
Deployment Manifest
This deployment uses ConfigMaps for feature flags and log levels, and Secrets for database credentials. The application can read configuration from both mounted files and environment variables.
Best Practices
ConfigMap Best Practices
- Keep ConfigMaps immutable when possible: Immutable ConfigMaps are more efficient and prevent accidental changes.
-
Use ConfigMaps for configuration, not code: ConfigMaps are for runtime configuration, not application code.
-
Avoid large ConfigMaps: Mounting large ConfigMaps can impact pod startup time.
Secret Best Practices
-
Never commit Secrets to version control: Always create Secrets through Kubernetes or use external secret management systems.
-
Use external secret management: For production environments, consider tools like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault.
-
Rotate secrets regularly: Implement a rotation strategy for sensitive credentials.
-
Apply RBAC controls: Restrict access to Secrets using Kubernetes Role-Based Access Control.
-
Use specific secret types: Kubernetes supports predefined secret types like
kubernetes.io/dockerconfigjsonfor image pull secrets.
Common Pitfalls
Pitfall 1: Hardcoding Secrets in Images
Never bake secrets into your Docker images. If an image is compromised, all secrets are exposed.
Pitfall 2: Using Secrets in ConfigMaps
ConfigMaps are not encrypted and should never contain sensitive data. Use Secrets for credentials and tokens.
Pitfall 3: Forgetting to Restart Pods
When you update a ConfigMap or Secret, pods don't automatically pick up the changes. You must restart them for the changes to take effect.
Pitfall 4: Exposing Secrets in Logs
Be careful not to log secrets in application logs. Kubernetes automatically masks secrets in pod events, but your application code must not print them.
Conclusion
ConfigMaps and Secrets are essential tools for managing configuration and sensitive data in Kubernetes applications. ConfigMaps provide a flexible way to externalize non-sensitive configuration, while Secrets offer secure storage for sensitive information. By following best practices and understanding the key differences between these resources, you can build more maintainable and secure deployments.
The next step is to explore how Kubernetes handles configuration updates and how to implement rolling updates when configuration changes. Platforms like ServerlessBase can automate much of this configuration management, handling ConfigMaps and Secrets securely and efficiently for your deployments.
Practical Next Steps
- Create a ConfigMap for your application's non-sensitive configuration
- Create a Secret for any sensitive data like database credentials
- Update your deployment to use both resources
- Test configuration changes by updating the ConfigMap and restarting pods
- Implement secret rotation for production environments