Managing Secrets and Configurations in Kubernetes
Learn how to manage secrets and configurations in Kubernetes effectively to secure your applications and simplify their deployment.
InSkillCoach
Introduction
In a Kubernetes environment, managing configurations and secrets is a crucial aspect of deploying and maintaining applications. This article explores the different methods for managing these elements securely and efficiently.
ConfigMaps: Managing Configurations
ConfigMaps are Kubernetes objects that store non-confidential data as key-value pairs. They are ideal for separating application configuration from code, making it possible to change settings without rebuilding the image.
Creating a ConfigMap
Method 1: From a file
# Créer un fichier de configuration
cat > app-config.properties << EOF
APP_ENV=production
LOG_LEVEL=info
API_URL=https://api.example.com
EOF
# Créer un ConfigMap à partir du fichier
kubectl create configmap app-config --from-file=app-config.properties
Method 2: From the command line
kubectl create configmap app-config \
--from-literal=APP_ENV=production \
--from-literal=LOG_LEVEL=info \
--from-literal=API_URL=https://api.example.com
Method 3: YAML definition
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
API_URL: https://api.example.com
Using ConfigMaps
1. Environment variables
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config
2. Individual environment variables
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
3. Configuration files
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
volumeMounts:
- name: config-volume
mountPath: /app/config
volumes:
- name: config-volume
configMap:
name: app-config
Secrets: Managing Sensitive Data
Secrets are similar to ConfigMaps but are designed to store sensitive data such as passwords, API tokens, and private keys. Kubernetes stores secrets in base64, but this is not real encryption.
Creating a Secret
Method 1: From the command line
kubectl create secret generic app-secrets \
--from-literal=DB_USERNAME=admin \
--from-literal=DB_PASSWORD=secretpassword
Method 2: From a file
# Créer un fichier de secrets
cat > app-secrets.txt << EOF
DB_USERNAME=admin
DB_PASSWORD=secretpassword
EOF
# Créer un Secret à partir du fichier
kubectl create secret generic app-secrets --from-file=app-secrets.txt
Method 3: YAML definition (with base64 values)
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DB_USERNAME: YWRtaW4= # base64 of "admin"
DB_PASSWORD: c2VjcmV0cGFzc3dvcmQ= # base64 of "secretpassword"
Using Secrets
1. Environment variables
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
envFrom:
- secretRef:
name: app-secrets
2. Individual environment variables
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: app-secrets
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: DB_PASSWORD
3. Configuration files
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
volumeMounts:
- name: secret-volume
mountPath: /app/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: app-secrets
Best Practices for Managing Secrets
1. Use an External Secrets Manager
Kubernetes stores secrets in base64, which is not real encryption. For stronger security, use an external secrets manager such as:
- HashiCorp Vault: A comprehensive secrets management solution
- AWS Secrets Manager: A managed service for AWS secrets
- Azure Key Vault: Azure’s secrets management service
- Google Secret Manager: GCP’s secrets management service
Integration with Vault
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: vault-auth
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: application
serviceAccount: vault-auth
tokenReviewerJWT: ""
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultSecret
metadata:
name: app-secrets
spec:
vaultAuthRef: vault-auth
path: secret/data/application
type: Opaque
2. Use Secrets for Container Registries
To access private container registries, use secrets of type docker-registry:
kubectl create secret docker-registry regcred \
--docker-server=<your-registry-server> \
--docker-username=<your-username> \
--docker-password=<your-password> \
--docker-email=<your-email>
Then reference it in your Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
imagePullSecrets:
- name: regcred
containers:
- name: myapp
image: private-registry.example.com/myapp:1.0
3. Use Secrets for TLS Certificates
For TLS certificates, use secrets of type tls:
kubectl create secret tls tls-secret \
--cert=path/to/tls.cert \
--key=path/to/tls.key
Then use it in your Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
4. Secret Rotation
Implement a regular secret rotation strategy:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
annotations:
kubernetes.io/change-cause: "Rotation of secrets - 2024-05-10"
type: Opaque
data:
DB_PASSWORD: <new-base64-encoded-password>
Advanced Configuration Management
1. ConfigMaps for Configuration Files
For applications that require complete configuration files:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
nginx.conf: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.19
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: app-config
2. ConfigMaps for Initialization Scripts
For initialization or configuration scripts:
apiVersion: v1
kind: ConfigMap
metadata:
name: init-scripts
data:
init.sh: |
#!/bin/bash
echo "Initializing application..."
# Initialization script
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
initContainers:
- name: init
image: busybox
command: ["/scripts/init.sh"]
volumeMounts:
- name: scripts-volume
mountPath: /scripts
containers:
- name: myapp
image: myapp:1.0
volumes:
- name: scripts-volume
configMap:
name: init-scripts
defaultMode: 0755
3. Using Helm for Configuration Management
Helm is a package manager for Kubernetes that simplifies configuration management:
# values.yaml
config:
APP_ENV: production
LOG_LEVEL: info
secrets:
DB_PASSWORD: secretpassword
---
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:{{ .Values.image.tag }}
env:
- name: APP_ENV
value: {{ .Values.config.APP_ENV }}
- name: LOG_LEVEL
value: {{ .Values.config.LOG_LEVEL }}
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-secrets
key: DB_PASSWORD
Securing Secrets
1. Encryption at Rest
Enable encryption at rest for secrets in etcd:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-key>
- identity: {}
2. RBAC for Secrets
Use RBAC to restrict access to secrets:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: secret-reader-binding
subjects:
- kind: ServiceAccount
name: app-service-account
namespace: default
roleRef:
kind: Role
name: secret-reader
apiGroup: rbac.authorization.k8s.io
3. Auditing Secrets
Enable auditing to track access to secrets:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
users: ["system:serviceaccount"]
verbs: ["get", "list", "watch"]
resources:
- group: ""
resources: ["secrets"]
Complete Example: An Application with ConfigMaps and Secrets
Here is a complete example of an application that uses ConfigMaps and Secrets:
# ConfigMap for the application configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
API_URL: https://api.example.com
nginx.conf: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
---
# Secret for sensitive data
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DB_USERNAME: YWRtaW4= # base64 of "admin"
DB_PASSWORD: c2VjcmV0cGFzc3dvcmQ= # base64 of "secretpassword"
---
# Application Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
volumeMounts:
- name: config-volume
mountPath: /app/config
- name: nginx-config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: app-config
- name: nginx-config-volume
configMap:
name: app-config
---
# Service to expose the application
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
Conclusion
Managing secrets and configurations effectively is essential for deploying applications securely in Kubernetes. By using ConfigMaps for non-confidential data and Secrets for sensitive data, you can separate configuration from code and make changes without rebuilding images.
For stronger security, consider using an external secrets manager such as HashiCorp Vault, which provides real encryption and advanced secrets management features.
In the next article, we will explore monitoring and logging in Kubernetes, which are crucial for maintaining the health and performance of your applications.
About InSkillCoach
Training and technology expert
Coach specializing in advanced technologies and AI, backed by GNeurone Inc.
Certifications:
- AWS Certified Solutions Architect – Professional
- Google Cloud certifications
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Comments
Comments are powered by GitHub Discussions
Sign in with GitHub to join the discussion