|
|
Kubernetes ConfigMaps and Secrets
Author: Venkata Sudhakar
In Kubernetes, hardcoding configuration values (database URLs, API keys, feature flags) directly into container images is an anti-pattern because it ties the image to a specific environment and forces a new image build for every configuration change. Kubernetes provides two dedicated objects for externalising configuration: ConfigMaps for non-sensitive configuration data and Secrets for sensitive data such as passwords, API keys, and TLS certificates. A ConfigMap stores key-value pairs of plain text configuration. A Secret stores key-value pairs of base64-encoded data and is handled more securely by Kubernetes - it can be encrypted at rest in etcd, is not logged in kubelet logs, and can be mounted read-only from memory (tmpfs) rather than disk. However, Secrets are only as secure as the RBAC policies controlling who can read them. For production workloads, Secrets are typically integrated with external secret managers like AWS Secrets Manager, HashiCorp Vault, or GCP Secret Manager via the External Secrets Operator. The below example shows how to create a ConfigMap and a Secret and then inject them into a Spring Boot Pod as both environment variables and mounted files.
Create the ConfigMap and Secret in the cluster,
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
configmap/app-config created
secret/app-secrets created
# Verify
kubectl get configmaps -n production
kubectl get secrets -n production
NAME DATA AGE
app-config 4 5s
NAME TYPE DATA AGE
app-secrets Opaque 4 3s
The below example shows how to reference the ConfigMap and Secret in a Deployment - injecting values both as environment variables and as a mounted configuration file.
It gives the following output inside the running Pod,
# Check injected env vars inside the Pod
kubectl exec -it myapp-7d9f-abc -n production -- env | grep -E "LOG|DB"
LOG_LEVEL=INFO
DB_URL=jdbc:mysql://prod-db:3306/appdb
DB_USERNAME=produser
DB_PASSWORD=S3cur3P@ssw0rd!
# Check mounted config file
kubectl exec -it myapp-7d9f-abc -n production -- cat /app/config/application.properties
server.port=8080
management.endpoints.web.exposure.include=health,info,metrics
spring.application.name=myapp
Update ConfigMap without redeploying: When you update a ConfigMap that is mounted as a volume file, Kubernetes automatically propagates the change to all Pods within about 1 minute - no redeployment needed. However, environment variables injected from a ConfigMap are only refreshed when the Pod restarts. For applications that need live configuration reloading, the file mount approach combined with Spring Cloud Config or Spring Boot Actuator refresh endpoint is the recommended pattern.
|
|