ConfigMaps und Secrets implementieren externe Konfigurationsverwaltung für Container-Anwendungen in OpenShift und ermöglichen strikte Trennung zwischen Anwendungscode und umgebungsspezifischen Konfigurationsdaten. Diese Abstraktionskonzepte fördern Twelve-Factor-App-Prinzipien und unterstützen portable, konfigurierbare Anwendungsdeployments.
ConfigMaps und Secrets lösen dasselbe Problem – externe Konfiguration von Anwendungen – aber für unterschiedliche Datentypen. Die Wahl zwischen beiden hängt von der Sensitivität der Daten ab.
ConfigMaps verwalten nicht-sensitive Konfigurationsdaten wie Anwendungsparameter, Feature Flags und Umgebungsvariablen in Klartext-Format. Diese Transparenz ermöglicht einfache Inspektion und Debugging von Konfigurationswerten durch Entwickler und Administratoren.
Typische ConfigMap-Inhalte: - Anwendungskonfiguration (Ports, URLs, Feature-Flags) - Logging-Konfiguration - Datenbank-Hostnamen (ohne Passwörter) - Konfigurationsdateien (nginx.conf, application.properties)
Secrets handhaben sensitive Daten wie Passwörter, API-Tokens und TLS-Zertifikate mit Base64-Kodierung und zusätzlichen Sicherheitsmaßnahmen. Diese Separation gewährleistet angemessene Zugriffskontrolle und Audit-Trails für kritische Sicherheitsinformationen.
Typische Secret-Inhalte: - Datenbank-Passwörter - API-Schlüssel und Tokens - TLS-Zertifikate und private Schlüssel - Registry-Zugangsdaten
Die konzeptionelle Trennung zwischen öffentlichen und privaten Konfigurationsdaten ermöglicht differenzierte Zugriffsrichtlinien und Governance-Strategien. Diese Klassifizierung unterstützt Compliance-Anforderungen und Least-Privilege-Prinzipien.
ConfigMaps speichern Key-Value-Paare, komplexe Konfigurationsdateien oder binäre Daten als eigenständige Cluster-Ressourcen. Diese Externalisierung ermöglicht Konfigurationsänderungen ohne Container-Neuerstellung oder Anwendungsneuplatzierung.
Über YAML-Definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
database_host: "postgres.company.com"
database_port: "5432"
log_level: "INFO"
feature_new_ui: "true"
# Komplexe Konfigurationsdatei
nginx.conf: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}Über CLI-Befehle:
# Aus Key-Value-Paaren
oc create configmap app-config \
--from-literal=database_host=postgres.company.com \
--from-literal=database_port=5432
# Aus Datei
oc create configmap nginx-config --from-file=nginx.conf
# Aus Verzeichnis (alle Dateien werden zu Keys)
oc create configmap app-configs --from-file=./configs/Umgebungsspezifische ConfigMaps ermöglichen identische Anwendungsdeployments mit verschiedenen Konfigurationen für Development, Staging und Production-Umgebungen:
# development-config
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: development
data:
database_host: "postgres-dev.internal"
log_level: "DEBUG"
replicas: "1"
---
# production-config
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config # Gleicher Name, anderer Namespace
namespace: production
data:
database_host: "postgres-prod.internal"
log_level: "WARN"
replicas: "3"OpenShift unterstützt verschiedene Secret-Typen für unterschiedliche Anwendungsfälle. Jeder Typ hat spezielle Validierungen und Verwendungsszenarien.
Generic Secrets verwalten beliebige Benutzerdaten mit Base64-Kodierung für Obfuscation und konsistente Datenhandhabung:
apiVersion: v1
kind: Secret
metadata:
name: database-credentials
type: Opaque
data:
username: YWRtaW4= # Base64 für "admin"
password: cGFzc3dvcmQ= # Base64 für "password"
stringData: # Alternative: Klartext wird automatisch kodiert
api_key: "sk-1234567890abcdef"Erstellung über CLI:
# Generic Secret erstellen
oc create secret generic database-credentials \
--from-literal=username=admin \
--from-literal=password=secretpassword
# Aus Datei erstellen
oc create secret generic app-secrets --from-file=.envTLS Secrets kapseln X.509-Zertifikate und private Schlüssel für HTTPS-Konnektivität:
apiVersion: v1
kind: Secret
metadata:
name: webapp-tls
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTi... # Base64-kodiertes Zertifikat
tls.key: LS0tLS1CRUdJTi... # Base64-kodierter privater SchlüsselCLI-Erstellung:
oc create secret tls webapp-tls \
--cert=path/to/cert.crt \
--key=path/to/private.keyDocker Registry Secrets ermöglichen Pull-Access zu privaten Container-Registries:
apiVersion: v1
kind: Secret
metadata:
name: private-registry
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS... # Base64-kodierte Docker-ConfigCLI-Erstellung:
oc create secret docker-registry private-registry \
--docker-server=registry.company.com \
--docker-username=serviceaccount \
--docker-password=token123 \
--docker-email=devops@company.comService Account Tokens werden automatisch erstellt und verwalten Pod-zu-API-Server-Authentifizierung:
# Service Account Token anzeigen
oc get secret $(oc get sa default -o jsonpath='{.secrets[0].name}') -o yamlConfigMaps und Secrets können auf verschiedene Weise in Pods konsumiert werden. Die Wahl der Methode hängt von Anwendungsanforderungen und Update-Verhalten ab.
Environment Variable-Injection überträgt ConfigMap- und Secret-Werte als Container-Umgebungsvariablen:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
template:
spec:
containers:
- name: webapp
image: nginx
env:
# Einzelne Values aus ConfigMap
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database_host
# Alle Keys aus ConfigMap
envFrom:
- configMapRef:
name: app-config
# Secret-Values
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: database-credentials
key: password
# Alle Keys aus Secret
envFrom:
- secretRef:
name: database-credentialsVorteil: Einfache Integration für Anwendungen, die Umgebungsvariablen erwarten. Nachteil: Updates erfordern Pod-Restart.
Volume Mount-Integration stellt ConfigMap- und Secret-Daten als Dateisystem-Inhalte zur Verfügung:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: webapp
volumeMounts:
- name: config-volume
mountPath: /etc/config
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: config-volume
configMap:
name: app-config
- name: secret-volume
secret:
secretName: database-credentials
defaultMode: 0400 # Restriktive DateiberechtigungenResultat im Container:
/etc/config/database_host # Inhalt: postgres.company.com
/etc/config/nginx.conf # Inhalt: Nginx-Konfiguration
/etc/secrets/username # Inhalt: admin
/etc/secrets/password # Inhalt: secretpasswordVorteil: Updates werden automatisch propagiert (nach kurzer Verzögerung). Nachteil: Anwendung muss Dateisystem-basierte Konfiguration unterstützen.
Projected Volumes ermöglichen Kombination mehrerer ConfigMaps und Secrets in einzelnen Volume-Mounts:
volumes:
- name: combined-config
projected:
sources:
- configMap:
name: app-config
- secret:
name: database-credentials
- secret:
name: api-credentials
items:
- key: api_key
path: api/key.txt # Custom-PfadEinzelne Keys als spezifische Dateien mounten:
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf # Nur diese Datei mountenConfigMap- und Secret-Updates haben unterschiedliche Auswirkungen je nach Consumption-Methode:
| Consumption-Methode | Update-Propagation | Restart-Erforderlich |
|---|---|---|
| Environment Variables | Nein | Ja (Pod-Restart) |
| Volume Mounts | Ja (nach ~1 Minute) | Nein (App-abhängig) |
| Projected Volumes | Ja (nach ~1 Minute) | Nein (App-abhängig) |
Immutable ConfigMaps und Secrets verhindern Änderungen nach Erstellung:
apiVersion: v1
kind: ConfigMap
metadata:
name: immutable-config
data:
key: value
immutable: true # Kann nicht mehr geändert werdenVorteile: - Schutz vor versehentlichen Änderungen - Performance-Verbesserung (weniger API-Watches) - Bessere Cache-Nutzung
Version-Suffixes ermöglichen Blue-Green-Deployment-Strategien:
# Alte Version
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-v1
data:
version: "1.0"
---
# Neue Version
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-v2
data:
version: "2.0"Deployment kann schrittweise auf neue Version umgestellt werden:
# Deployment Update
spec:
template:
spec:
volumes:
- name: config-volume
configMap:
name: app-config-v2 # Von v1 auf v2 umstellenSecret-Handling erfordert besondere Aufmerksamkeit für Sicherheit und Compliance.
Secret Encryption-at-Rest gewährleistet Verschlüsselung sensibler Daten im etcd-Cluster-Store:
# OpenShift-Konfiguration (Cluster-Administrator)
apiVersion: config.openshift.io/v1
kind: APIServer
metadata:
name: cluster
spec:
encryption:
type: aescbc # VerschlüsselungsalgorithmusGranulare Zugriffskontrolle auf ConfigMap- und Secret-Ressourcen:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: config-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"] # Nur Lese-Zugriff auf Secrets
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developers-config-access
subjects:
- kind: User
name: developer@company.com
roleRef:
kind: Role
name: config-readerSecret-Rotation-Strategien für regelmäßige Passwort-Updates:
# 1. Neues Secret erstellen
oc create secret generic database-credentials-new \
--from-literal=username=admin \
--from-literal=password=new-password
# 2. Deployment auf neues Secret umstellen
oc patch deployment webapp -p '{
"spec": {
"template": {
"spec": {
"volumes": [{
"name": "secret-volume",
"secret": {
"secretName": "database-credentials-new"
}
}]
}
}
}
}'
# 3. Nach erfolgreicher Rotation altes Secret löschen
oc delete secret database-credentialsBeschränkung des Secret-Zugriffs auf autorisierte Container:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: webapp
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: trueIntegration mit Enterprise Key Management Systems:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: vault-secret
spec:
refreshInterval: 5m
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: database-credentials
creationPolicy: Owner
data:
- secretKey: password
remoteRef:
key: database/prod
property: passwordConfigMaps und Secrets als Code mit Versionskontrolle:
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: app-config
files:
- config/application.properties
- config/nginx.conf
secretGenerator:
- name: app-secrets
files:
- secrets/.env
type: OpaqueConfigMaps und Secrets sind auf 1MB begrenzt. Für größere Konfigurationen:
# Aufteilen großer Konfigurationen
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-base
data:
# Grundkonfiguration
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-features
data:
# Feature-spezifische Konfiguration# ConfigMap-/Secret-Usage prüfen
oc get events --field-selector reason=FailedMount
# Kubelet-Logs für Volume-Mount-Probleme
oc adm node-logs <node-name> -u kubelet# Verfügbare ConfigMaps/Secrets prüfen
oc get configmaps,secrets
# Details anzeigen
oc describe configmap app-config
oc describe secret database-credentials
# Pod-Events prüfen
oc describe pod <pod-name># Container-Umgebungsvariablen prüfen
oc exec <pod-name> -- env | grep DATABASE
# ConfigMap-Keys validieren
oc get configmap app-config -o yaml# Mounted Volumes prüfen
oc exec <pod-name> -- ls -la /etc/config
# Mount-Details validieren
oc exec <pod-name> -- cat /proc/mounts | grep config# Secret-Inhalt dekodieren
oc get secret database-credentials -o jsonpath='{.data.password}' | base64 -dNaming Conventions:
# Umgebungsspezifische Namen
metadata:
name: webapp-config-prod
name: webapp-secrets-prod
# Oder Namespace-basierte Trennung
metadata:
name: webapp-config
namespace: productionGranularität: - Separate ConfigMaps für verschiedene Komponenten - Secrets nur für tatsächlich sensitive Daten verwenden - Immutable für kritische Konfigurationen