Kubernetes Series - Part 5: Configuration and Secrets
/ 3 min read
Series Navigation
- Part 1: Core Fundamentals
- Part 2: Workload Management
- Part 3: Networking Essentials
- Part 4: Storage and Persistence
- Part 5: Configuration and Secrets (Current)
- Part 6: Security and Access Control
- Part 7: Observability
- Part 8: Advanced Patterns
- Part 9: Production Best Practices
Introduction
After managing dozens of applications across multiple environments, I’ve learned that proper configuration management is crucial for maintaining reliable and secure Kubernetes deployments. In this article, I’ll share practical insights from real-world experience managing configurations and secrets.
ConfigMaps
Here’s how we structure our ConfigMaps for different environments:
apiVersion: v1kind: ConfigMapmetadata: name: app-config labels: app: myapp env: productiondata: app.properties: | log.level=INFO cache.ttl=3600 api.timeout=30 metrics.enabled=true nginx.conf: | server { listen 80; location /health { return 200 'healthy\n'; } location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }ConfigMap Best Practices
-
Organization
- Use meaningful names
- Group related configurations
- Version your configs
metadata:name: app-config-v2labels:version: "2.0" -
Environment Management
- Separate configs by environment
- Use kustomize for variations
- Document all options
Secrets Management
Our approach to managing secrets securely:
apiVersion: v1kind: Secretmetadata: name: app-secrets annotations: vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/role: "myapp"type: OpaquestringData: api-key: ${VAULT_API_KEY} db-password: ${VAULT_DB_PASSWORD}External Secrets Integration
We use External Secrets Operator for AWS Secrets Manager:
apiVersion: external-secrets.io/v1beta1kind: ExternalSecretmetadata: name: app-external-secretsspec: refreshInterval: 1h secretStoreRef: name: aws-secrets kind: SecretStore target: name: app-secrets data: - secretKey: api-key remoteRef: key: myapp/production/api-key - secretKey: db-password remoteRef: key: myapp/production/db-passwordSecret Management Tips
-
Security Practices
- Never commit secrets to git
- Rotate secrets regularly
- Use external secret managers
- Implement least privilege access
-
Secret Rotation
- Automate rotation where possible
- Plan for zero-downtime updates
- Monitor secret usage
Environment Variables
How we handle environment variables in deployments:
apiVersion: apps/v1kind: Deploymentmetadata: name: myappspec: template: spec: containers: - name: myapp env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: DB_HOST valueFrom: configMapKeyRef: name: app-config key: database.host - name: API_KEY valueFrom: secretKeyRef: name: app-secrets key: api-key envFrom: - configMapRef: name: app-config - secretRef: name: app-secretsEnvironment Variable Best Practices
-
Organization
- Group related variables
- Use clear naming conventions
- Document each variable’s purpose
-
Security
- Avoid sensitive data in env vars
- Use secrets for credentials
- Implement proper RBAC
Configuration Updates
How we handle configuration updates:
apiVersion: apps/v1kind: Deploymentmetadata: name: myappspec: template: metadata: annotations: checksum/config: ${CONFIG_CHECKSUM} spec: containers: - name: myapp volumeMounts: - name: config mountPath: /app/config readOnly: true volumes: - name: config configMap: name: app-configUpdate Strategies
-
Rolling Updates
- Use checksums to trigger updates
- Implement proper health checks
- Monitor update progress
-
Zero-downtime Updates
- Use readiness probes
- Implement graceful shutdown
- Monitor application health
Real-world Example
Complete example of a production application with configs and secrets:
---apiVersion: v1kind: ConfigMapmetadata: name: app-configdata: application.yaml: | server: port: 8080 logging: level: INFO cache: enabled: true ttl: 3600---apiVersion: external-secrets.io/v1beta1kind: ExternalSecretmetadata: name: app-secretsspec: refreshInterval: 1h secretStoreRef: name: aws-secrets kind: SecretStore target: name: app-secrets data: - secretKey: db-password remoteRef: key: myapp/production/db-password---apiVersion: apps/v1kind: Deploymentmetadata: name: myappspec: template: metadata: annotations: checksum/config: ${CONFIG_CHECKSUM} spec: containers: - name: myapp image: myapp:1.0.0 volumeMounts: - name: config mountPath: /app/config readOnly: true env: - name: SPRING_CONFIG_LOCATION value: /app/config/application.yaml - name: DB_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: db-password volumes: - name: config configMap: name: app-configCommon Issues and Solutions
From my experience, here are frequent problems and solutions:
-
Configuration Drift
- Use GitOps practices
- Implement configuration validation
- Regular audits
-
Secret Management
- Implement proper rotation
- Monitor secret access
- Regular security audits
-
Update Problems
- Test updates thoroughly
- Implement rollback procedures
- Monitor application health
Production Checklist
✅ Configuration Management
- Version control for configs
- Environment separation
- Documentation
- Validation procedures
✅ Secret Management
- External secrets manager
- Rotation policy
- Access controls
- Audit logging
✅ Security
- RBAC configuration
- Network policies
- Encryption
- Security scanning
✅ Monitoring
- Configuration changes
- Secret access
- Error tracking
- Health metrics
Conclusion
Proper configuration and secrets management is fundamental to running reliable and secure Kubernetes applications. Key takeaways from my experience:
- Use external secret managers
- Implement proper versioning
- Automate where possible
- Monitor and audit regularly
- Plan for updates and rollbacks
In the next part, we’ll explore security and access control in Kubernetes, where I’ll share practical tips for securing your cluster and applications.