Modul 8 — Orchestrace: Kubernetes
37. ConfigMaps, Secrets a správa konfigurace
Jak oddělit konfiguraci a citlivé údaje od image aplikace pomocí ConfigMap a Secret objektů.
Úvod a kontext
Image aplikace by měl zůstat stejný napříč prostředími (vývoj, staging,
produkce) — mění se jen konfigurace: adresa databáze, přístupové
údaje, feature flagy. Natvrdo zapsat tyto hodnoty do image by znamenalo
sestavovat samostatný image pro každé prostředí, což popírá smysl
kontejnerizace. Kubernetes pro oddělení konfigurace od image nabízí dva
objekty: ConfigMap pro necitlivá data a Secret pro citlivé
údaje.
Teorie
ConfigMap
ConfigMap uchovává nešifrovaná konfigurační data jako
klíč-hodnota páry — proměnné prostředí, konfigurační soubory, řádky
příkazů.
# z literálů
kubectl create configmap app-config \
--from-literal=LOG_LEVEL=info \
--from-literal=FEATURE_X=enabled
# ze souboru
kubectl create configmap nginx-config --from-file=nginx.conf
Nebo deklarativně:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: info
FEATURE_X: "enabled"
Použití v Podu — jako proměnné prostředí, nebo jako připojený soubor:
spec:
containers:
- name: app
image: mycompany/app:1.4.0
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d
volumes:
- name: nginx-conf
configMap:
name: nginx-config
Secret
Secret má stejné API jako ConfigMap, ale je určen pro citlivá
data — hesla, API klíče, TLS certifikáty. Hodnoty jsou uloženy jako
base64, což není šifrování, jen kódování — kdokoliv se
čtecím přístupem k objektu Secret v clusteru si hodnotu snadno dekóduje
(base64 -d). Skutečná ochrana Secretů stojí na:
- RBAC (řízení přístupu) — omezit, kdo smí Secrety číst,
- šifrování dat v etcd v klidu (encryption at rest, nastavení
clusteru), - v produkci často na napojení na externí správce tajemství (Vault a
podobné nástroje — tomu se podrobně věnuje samostatná lekce v modulu
o bezpečnosti).
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password='S3cretHeslo!'
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4= # base64("admin")
password: UzNjcmV0SGVzbG8h # base64("S3cretHeslo!")
Použití v Podu je analogické ConfigMap:
spec:
containers:
- name: app
image: mycompany/app:1.4.0
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
ConfigMap a Secret jako proměnné vs. jako soubory
Obě varianty lze mountnout buď jako proměnné prostředí (jednoduché,
ale změna vyžaduje restart Podu, aby se projevila), nebo jako soubory
do volume (Kubernetes umí aktualizovat obsah mountnutého souboru za
běhu bez restartu Podu, byť aplikace musí sama detekovat změnu
souboru, aby ji zohlednila).
Klíčový princip: image se nemění, konfigurace ano
Stejný image mycompany/app:1.4.0 tak lze nasadit do vývojového,
staging i produkčního namespace jen s odlišnými ConfigMap/Secret
objekty — to je přesně princip 12factor
metodiky "konfigurace v prostředí, ne v kódu", který jsme si popsali
dříve u Dockeru a Kubernetes ho plně podporuje.
Praktický příklad
Nasazení jedné aplikace do dvou různých ConfigMap podle prostředí, se
stejným Deploymentem:
# staging
kubectl create configmap app-config --from-literal=API_URL=https://staging.api.firma.cz -n staging
# produkce
kubectl create configmap app-config --from-literal=API_URL=https://api.firma.cz -n production
# stejný Deployment manifest (jen jiný namespace) v obou prostředích
kubectl apply -f deployment.yaml -n staging
kubectl apply -f deployment.yaml -n production
Aplikace uvnitř Podu čte proměnnou API_URL z prostředí a chová se
podle toho, aniž by se cokoliv měnilo na obsahu image.
Shrnutí
ConfigMap a Secret oddělují konfiguraci od image aplikace — ConfigMap
pro necitlivá data, Secret pro citlivá (byť jen base64 kódovaná, ne
šifrovaná — skutečnou ochranu zajišťuje RBAC a šifrování v etcd, případně
externí secrets manager). Obojí lze do Podu předat jako proměnné
prostředí nebo jako mountnuté soubory. Díky tomu stačí jeden image na
všechna prostředí, liší se jen přiložená konfigurace.
Kontrolní otázky
- Proč base64 kódování v Secret objektu samo o sobě neposkytuje
bezpečnost a co ji skutečně zajišťuje? - Jaký je rozdíl mezi předáním konfigurace jako proměnné prostředí a
jako mountnutého souboru z hlediska aktualizace za běhu? - Proč je žádoucí, aby se stejný Docker image používal ve všech
prostředích a lišila se jen konfigurace? - Mini cvičení: vytvořte Secret
api-keys jedním klíčemtoken,
připojte ho do Podu jako proměnnou prostředíAPI_TOKENa uvnitř
Podu příkazemkubectl exec ... -- env | grep API_TOKENověřte, že
je hodnota dostupná v čitelné (dekódované) podobě.
Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.