Spring Boot Configuration Management with Kubernetes ConfigMaps and Secrets
Managing application configurations is a critical part of deploying and maintaining software in a Kubernetes (K8s) environment. Kubernetes provides powerful tools like ConfigMaps and Secrets to externalize application settings and sensitive data, enabling better portability, scalability, and security. This guide explores the fundamentals of configuration management with Spring Boot in Kubernetes, including practical steps, best practices, and answers to frequently asked questions (FAQs).
Why Externalize Configurations in Kubernetes?
Externalizing configurations separates application code from its operational settings. This abstraction provides several benefits:
- Environment Flexibility: Deploy the same application image across different environments (e.g., development, staging, production) with environment-specific configurations.
- Scalability: Centralize configuration management, making it easier to update and roll out changes across distributed deployments.
- Security: Keep sensitive data, like passwords and tokens, outside the application image.
- Maintenance and Debugging: Dynamically update configurations without rebuilding and redeploying the application.
By combining Kubernetes ConfigMaps and Secrets with Spring Boot’s property injection capabilities, you can create robust configuration management for microservices.
Creating a ConfigMap and Mounting It as Environment Variables
Kubernetes ConfigMaps allow you to store non-sensitive configuration data, such as application properties or connection strings. These can be injected into a Spring Boot application as environment variables.
Step 1. Create a ConfigMap
You can create a ConfigMap using the Kubernetes CLI or a YAML manifest.
Using kubectl
:
kubectl create configmap app-config --from-literal=APP_ENV=production --from-literal=APP_NAME=SpringBootApp
Using YAML:
apiVersion: v1 kind: ConfigMap metadata: name: app-config data: APP_ENV: production APP_NAME: SpringBootApp
Apply the YAML configuration:
kubectl apply -f configmap.yaml
Step 2. Mount ConfigMap as Environment Variables
Update your deployment configuration to mount ConfigMap data into your Pods:
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-deployment spec: replicas: 1 template: spec: containers: - name: springboot-container image: springboot-app-image envFrom: - configMapRef: name: app-config
The application can now access these variables like so:
@Value("${APP_ENV}") private String appEnvironment;
Step 3. Verify Injection
Run the following command to check injected values:
kubectl exec <pod-name> -- printenv | grep APP_
YAML vs. ENV File Format
Kubernetes supports multiple formats for injecting configurations. Configurations in ConfigMaps can appear as key-value pairs in YAML or ENV format. Choosing between them depends on your organizational preference, but YAML provides better readability and structure for complex configurations.
Example Key-Value ENV Pair (ConfigMap):
data: APP_NAME: "SpringBootApp" APP_VERSION: "1.0.0"
Example Key-Value ENV Parsed File (Env File):
APP_NAME=SpringBootApp APP_VERSION=1.0.0
While both formats achieve the same goal, YAML aligns with Kubernetes declarative file management standards.
Using @Value
and @ConfigurationProperties
to Read Configurations
Spring Boot simplifies configuration injection with the @Value
and @ConfigurationProperties
annotations:
@Value
– Injects individual properties:
@Value("${APP_NAME}") private String appName;
@ConfigurationProperties
– Binds multiple properties to a POJO class:
@ConfigurationProperties(prefix = "app") public class AppConfig { private String name; private String version; // Getters and setters }
Annotate the POJO with @Component
and enable the feature:
@EnableConfigurationProperties(AppConfig.class)
Using Kubernetes Secrets for Passwords or Tokens
Sensitive data should never be stored in plain text. Kubernetes Secrets provide a secure way to manage and inject credentials.
Step 1. Create a Secret
Using kubectl
:
kubectl create secret generic db-credentials --from-literal=DB_USERNAME=admin --from-literal=DB_PASSWORD=secret123
Using YAML:
apiVersion: v1 kind: Secret metadata: name: db-credentials type: Opaque data: DB_USERNAME: YWRtaW4= # Base64 encoded 'admin' DB_PASSWORD: c2VjcmV0MTIz # Base64 encoded 'secret123'
Step 2. Mount a Secret as Environment Variables
envFrom: - secretRef: name: db-credentials
Or, mount the secret as a volume:
volumeMounts: - name: secret-volume mountPath: /etc/secrets volumes: - name: secret-volume secret: secretName: db-credentials
Ensure sensitive files are referenced securely:
cat /etc/secrets/DB_USERNAME
Encrypting Secrets Using Sealed Secrets
Sealed Secrets encrypt Kubernetes Secrets, making them safer for version control.
Encrypt the Secret
Generate a sealed version of your secret:
kubectl create secret generic db-credentials --from-literal=DB_PASSWORD=supersecret --dry-run=client -o yaml | kubeseal > sealedsecret.yaml
The transformed sealedsecret.yaml
can now be safely committed to version control.
Auto-Reloading Configurations with Spring Cloud Kubernetes
For dynamic Kubernetes deployments, you can enable auto-reloading of configurations with Spring Cloud Kubernetes:
- Add the dependency:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-config</artifactId> </dependency>
- Combine it with Spring’s
@RefreshScope
to refresh beans:
@RestController @RefreshScope public class TestController { /*...*/ }
Common Mistakes in Kubernetes Config Injection
- Injecting large ConfigMaps: Avoid committing excess data into ConfigMaps as it can overwhelm the API server.
- Exposing Secrets accidentally: Ensure Secrets are not logged.
- Not validating mounted files: Applications can fail if paths are incorrect.
Testing Configuration Propagation
Use the following steps to verify configuration accuracy:
- Validate ConfigMaps:
kubectl get configmap app-config -o yaml
- Inspect injected environment variables:
kubectl exec <pod-name> -- env | grep APP_
- Test auto-reloading by modifying ConfigMaps.
FAQ
What are ConfigMaps and Secrets used for?
- ConfigMaps store non-sensitive configurations, while Secrets manage sensitive data like passwords and API keys.
How does encryption work with Sealed Secrets?
Sealed Secrets encrypt data at rest. Only the Kubernetes cluster holding the decryption key can decrypt the data.
How can I test if my Secret was injected correctly?
Check mounted secrets with:
cat /etc/secrets/<key-name>
Can I create a Secret without base64 encoding?
Yes, Kubernetes CLI automatically encodes literals provided using kubectl create secret
.
What happens if a ConfigMap or Secret is missing?
Pods referencing missing ConfigMaps or Secrets will not start unless you set optional=true
for those references.
By following these steps and best practices, you can confidently manage configurations in your Spring Boot applications deployed on Kubernetes.