ConfigMaps and Secrets

Learn how to manage configuration data and sensitive information in Kubernetes using ConfigMaps and Secrets. Keep your applications configurable and secure.

Table of Contents

1. Introduction

Applications often need configuration data and sensitive information:

  • Configuration: Environment-specific settings, feature flags, endpoints
  • Sensitive Data: Passwords, API keys, certificates, tokens

Kubernetes provides two objects for this:

  • ConfigMaps: Store non-sensitive configuration data
  • Secrets: Store sensitive information

Both can be mounted as volumes or exposed as environment variables in Pods.

2. ConfigMaps

A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or configuration files in a volume.

2.1 Use Cases

  • Application configuration files
  • Environment variables
  • Command-line arguments
  • Configuration data in volumes

2.2 Important Notes

  • ConfigMaps are NOT encrypted - don't store secrets
  • ConfigMaps are namespace-scoped
  • ConfigMaps can be updated without recreating Pods
  • Data size limit: 1MB per ConfigMap

3. Creating ConfigMaps

There are several ways to create ConfigMaps:

3.1 From Literal Values

kubectl create configmap app-config \
  --from-literal=key1=value1 \
  --from-literal=key2=value2 \
  --from-literal=database_url=postgresql://localhost:5432/mydb

3.2 From Files

# From a single file
kubectl create configmap app-config --from-file=config.properties

# From multiple files
kubectl create configmap app-config \
  --from-file=config.properties \
  --from-file=app.yaml

# From a directory
kubectl create configmap app-config --from-file=./config/

3.3 From YAML Definition

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: default
data:
  # Simple key-value
  database_url: "postgresql://localhost:5432/mydb"
  log_level: "info"
  
  # Multi-line value
  app.properties: |
    server.port=8080
    server.host=0.0.0.0
    app.name=myapp
    app.version=1.0.0
kubectl apply -f configmap.yaml

3.4 Viewing ConfigMaps

# List ConfigMaps
kubectl get configmaps

# Describe ConfigMap
kubectl describe configmap app-config

# View ConfigMap data
kubectl get configmap app-config -o yaml

4. Using ConfigMaps

ConfigMaps can be used in Pods in three ways:

4.1 As Environment Variables

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    env:
    - name: DATABASE_URL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: database_url
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: log_level

4.2 All Keys as Environment Variables

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    envFrom:
    - configMapRef:
        name: app-config

4.3 As Volume Mounts

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  - name: config-volume
    configMap:
      name: app-config

This mounts all ConfigMap keys as files in /etc/config. Each key becomes a filename.

4.4 Specific Keys as Files

volumes:
- name: config-volume
  configMap:
    name: app-config
    items:
    - key: app.properties
      path: application.properties

4.5 In Deployments

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:1.0
        envFrom:
        - configMapRef:
            name: app-config

5. Secrets

A Secret is an object that contains a small amount of sensitive data such as passwords, tokens, or keys. Kubernetes stores Secrets in base64 encoding (not encryption).

5.1 Use Cases

  • Database passwords
  • API keys and tokens
  • TLS certificates
  • Docker registry credentials
  • SSH keys

5.2 Important Notes

  • Secrets are base64 encoded, NOT encrypted
  • Anyone with API access can read Secrets
  • Use RBAC to restrict Secret access
  • Consider external secret management (Vault, AWS Secrets Manager)
  • Secrets are namespace-scoped
  • Data size limit: 1MB per Secret

5.3 Secret Types

  • Opaque: User-defined data (default)
  • kubernetes.io/dockerconfigjson: Docker registry credentials
  • kubernetes.io/tls: TLS certificate and key
  • kubernetes.io/service-account-token: Service account token

6. Creating Secrets

6.1 From Literal Values

kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=secretpassword123

6.2 From Files

# Create secret from file
echo -n 'secretpassword123' > password.txt
kubectl create secret generic db-secret --from-file=password.txt

# Create TLS secret
kubectl create secret tls tls-secret \
  --cert=tls.crt \
  --key=tls.key

6.3 From YAML Definition

Values must be base64 encoded:

# Encode values
echo -n 'admin' | base64
echo -n 'secretpassword123' | base64
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=  # base64 encoded 'admin'
  password: c2VjcmV0cGFzc3dvcmQxMjM=  # base64 encoded 'secretpassword123'

6.4 Docker Registry Secret

kubectl create secret docker-registry regcred \
  --docker-server=docker.io \
  --docker-username=myuser \
  --docker-password=mypassword \
  --docker-email=myuser@example.com

6.5 Viewing Secrets

# List secrets (values are hidden)
kubectl get secrets

# Describe secret
kubectl describe secret db-secret

# View secret data (base64 encoded)
kubectl get secret db-secret -o yaml

# Decode secret value
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d

7. Using Secrets

Secrets can be used similarly to ConfigMaps:

7.1 As Environment Variables

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password

7.2 All Keys as Environment Variables

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    envFrom:
    - secretRef:
        name: db-secret

7.3 As Volume Mounts

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: db-secret

7.4 TLS Secret in Pod

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: tls-volume
      mountPath: /etc/tls
  volumes:
  - name: tls-volume
    secret:
      secretName: tls-secret

7.5 Image Pull Secrets

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  imagePullSecrets:
  - name: regcred
  containers:
  - name: app
    image: private-registry.io/myapp:1.0

8. Best Practices

8.1 Use ConfigMaps for Non-Sensitive Data

Never store passwords, keys, or tokens in ConfigMaps. Use Secrets instead.

8.2 Enable Encryption at Rest

Configure encryption at rest for etcd to encrypt Secrets stored in the cluster.

8.3 Use RBAC

Restrict access to Secrets using Role-Based Access Control. Only grant access to users and service accounts that need it.

8.4 Consider External Secret Management

For production, consider using external secret management systems like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault.

8.5 Rotate Secrets Regularly

Implement a secret rotation strategy. Update Secrets and restart Pods to pick up new values.

8.6 Use Immutable ConfigMaps/Secrets

For better performance and security, mark ConfigMaps and Secrets as immutable:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
immutable: true
data:
  key: value

8.7 Don't Commit Secrets to Git

Never commit Secrets or base64-encoded values to version control. Use CI/CD pipelines to inject secrets at deployment time.

Summary: ConfigMaps store non-sensitive configuration data, while Secrets store sensitive information. Both can be used as environment variables or volume mounts. Remember that Secrets are base64 encoded, not encrypted, so use RBAC and consider external secret management for production.

Post a Comment

0 Comments