0%
Managing Secrets and Configurations in Kubernetes

Managing Secrets and Configurations in Kubernetes

Learn how to manage secrets and configurations in Kubernetes effectively to secure your applications and simplify their deployment.

I

InSkillCoach

· min

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.

InSkillCoach

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+
791
157

Comments

Comments are powered by GitHub Discussions

Sign in with GitHub to join the discussion

Link copied!