Hogyan menedzseljünk titkokat és konfigurációkat a Kubernetes segítségével

Üdvözöljük a felhőalapú alkalmazásfejlesztés világában! A Kubernetes forradalmasította az alkalmazások telepítését, skálázását és menedzselését, de a konténerizált környezetben való munka számos új kihívást is hozott magával. Ezek közül az egyik legkritikusabb a biztonságos titokkezelés és a konfigurációk hatékony menedzselése. Ebben a cikkben egy átfogó útmutatót nyújtunk arról, hogyan kezelhetjük ezeket a létfontosságú elemeket a Kubernetes ökoszisztémában, a natív megoldásoktól a fejlett, külső eszközökig, miközben folyamatosan a biztonságra és a hatékonyságra törekszünk.

Miért kritikus a titkok és konfigurációk kezelése Kubernetesben?

Képzeljük el, hogy egy alkalmazásfejlesztő csapat tagjaként dolgozunk. Az alkalmazásunknak szüksége van adatbázis-hitelesítő adatokra, API kulcsokra külső szolgáltatásokhoz, vagy éppen különböző környezeti változókra a fejlesztési, teszt és éles környezetben. Ezeknek az információknak a helytelen kezelése komoly biztonsági réseket és működési problémákat eredményezhet:

  • Biztonsági kockázatok: Ha a jelszavakat, API kulcsokat, tanúsítványokat közvetlenül a kódban (hardkódolva) vagy verziókövető rendszerekben (mint a Git) tároljuk, az hatalmas kockázatot jelent. Egy esetleges adatszivárgás beláthatatlan következményekkel járhat.
  • Működési megbízhatóság: A környezetfüggő konfigurációk (pl. adatbázis URL-ek, logolási szintek) rossz kezelése miatt az alkalmazás hibásan működhet, vagy akár összeomolhat különböző környezetekben.
  • Fejlesztői élmény és hatékonyság: A manuális konfigurációkezelés lassú, hibalehetőségeket rejt és frusztráló. Az automatizált és egységes kezelés javítja a fejlesztők életét és a CI/CD folyamatokat.
  • Skálázhatóság és automatizálás: A Kubernetes egyik fő előnye a skálázhatóság. A titkok és konfigurációk centralizált és automatizált kezelése elengedhetetlen a dinamikusan változó infrastruktúrákban.
  • Compliance és auditálhatóság: Számos iparágban és szabályozási környezetben szigorú előírások vonatkoznak az érzékeny adatok kezelésére. A megfelelő eszközökkel nyomon követhető, hogy ki, mikor és milyen titkokhoz fért hozzá.

A Kubernetes natív megoldásai: ConfigMap és Secret

A Kubernetes két beépített erőforrást kínál a konfigurációk és titkok kezelésére: a ConfigMap-et és a Secret-et. Fontos megérteni a különbségeket és a korlátokat, hogy megfelelően tudjuk őket használni.

ConfigMap: A konfigurációk tárolásának alapja

A ConfigMap objektumok célja a nem érzékeny konfigurációs adatok kulcs-érték párok vagy konfigurációs fájlok formájában történő tárolása. Ezek az adatok ezután környezeti változóként, parancssori argumentumként, vagy fájlként csatolhatók a Pod-okhoz.

Mire használjuk a ConfigMap-et?

  • Környezeti változók: Az alkalmazások gyakran használnak környezeti változókat a konfiguráláshoz (pl. DATABASE_HOST, LOG_LEVEL).
  • Parancssori argumentumok: Néhány alkalmazás parancssori argumentumokat vár, amelyek szintén származhatnak ConfigMap-ből.
  • Konfigurációs fájlok: Például egy Nginx konfigurációs fájl, egy Spring Boot application.properties vagy egy Logback konfiguráció, amelyeket fájlként csatolunk a konténerbe.

Példa ConfigMap használatára:

Létrehozhatunk egy ConfigMap-et kubectl paranccsal vagy YAML fájlból:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_host: "mydb-service"
  log_level: "INFO"
  # Vagy akár teljes fájl tartalma
  config.json: |
    {
      "featureFlags": {
        "newFeature": true
      }
    }

Majd ezt felhasználhatjuk egy Pod-ban környezeti változóként vagy fájlként:

apiVersion: v1
kind: Pod
metadata:
  name: my-app-pod
spec:
  containers:
  - name: my-app
    image: my-app:1.0
    env:
    - name: DATABASE_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: database_host
    envFrom: # Az összes kulcsot környezeti változóként adjuk át
    - configMapRef:
        name: app-config
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config # Fájlként csatolja a config.json-t ide
  volumes:
  - name: config-volume
    configMap:
      name: app-config

Korlátok:

A ConfigMap-ek mérete korlátozott (általában 1 MB), és nem alkalmasak érzékeny adatok tárolására.

Secret: Az érzékeny adatok tárolója

A Secret objektumok célja az érzékeny adatok, mint például jelszavak, OAuth tokenek, SSH kulcsok vagy TLS tanúsítványok tárolása. Fontos azonban megérteni egy alapvető tényt:

FONTOS: A Kubernetes Secret-ek csak Base64 kódolást használnak, NEM titkosítást!

Ez azt jelenti, hogy ha valaki hozzáfér a Kubernetes API-hoz vagy az etcd adatbázishoz, könnyedén dekódolhatja a Secret tartalmát. Ezért a Kubernetes natív Secret-je önmagában nem nyújt végpontok közötti titkosítást, és további biztonsági intézkedésekre van szükség.

Mire használjuk a Secret-et?

  • Adatbázis jelszavak: Az alkalmazásnak szüksége van a adatbázishoz való csatlakozáshoz.
  • API kulcsok: Külső szolgáltatásokhoz (pl. felhőszolgáltatók, fizetési átjárók).
  • TLS tanúsítványok: Webes forgalom titkosításához.
  • Image Pull Secrets: Privát konténer regisztrációs adatbázisokból való image letöltéséhez.

Példa Secret használatára:

Hasonlóan a ConfigMap-hez, Secret-et is létrehozhatunk kubectl paranccsal vagy YAML fájlból. A kulcs-érték párokat Base64 kódoltan kell megadni:

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque # Vagy kubernetes.io/tls, kubernetes.io/dockerconfigjson stb.
data:
  username: dXNlcg== # "user" base64 kódolva
  password: cGFzcw== # "pass" base64 kódolva

Felhasználás Pod-ban, hasonlóan a ConfigMap-hez:

apiVersion: v1
kind: Pod
metadata:
  name: my-app-db-pod
spec:
  containers:
  - name: my-app
    image: my-app:1.0
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: username
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: db-credentials

Korlátok és biztonsági szempontok:

  • Nincs end-to-end titkosítás: Ahogy már említettük, a Secret-ek alapértelmezetten nem titkosítottak, csak kódoltak.
  • Láthatóság: Bárki, aki kubectl get secret parancsot futtathat a megfelelő jogosultságokkal, hozzáférhet a titkok kódolt formájához.
  • Git-ben tárolás veszélye: Soha ne commit-oljunk natív Kubernetes Secret YAML fájlokat Git-be titkosítatlanul!

Haladó titokkezelési stratégiák Kubernetesben

Mivel a natív Kubernetes Secret csak base64 kódolja az adatokat, és nem nyújt valódi titkosítást vagy központi menedzsmentet, a valódi titkosításhoz, a központi titokkezeléshez és a GitOps alapú munkafolyamatokhoz gyakran külső megoldásokra van szükség.

1. Titkosítás kliens oldalon: Sealed Secrets

A Sealed Secrets a Bitnami egy nyílt forráskódú projektje, amely lehetővé teszi, hogy titkosított Kubernetes Secret-eket tároljunk Git repozitóriumban is. Ez a megközelítés különösen jól illeszkedik a GitOps munkafolyamatokhoz.

Hogyan működik a Sealed Secrets?

A Sealed Secrets egy Controller-t telepít a Kubernetes klaszterbe. Ez a Controller generál egy nyilvános/privát kulcspárt. A felhasználó a nyilvános kulccsal titkosítja a natív Kubernetes Secret-jét egy kubeseal CLI eszközzel. Az eredmény egy SealedSecret erőforrás, amely elkötelezhető a Git-be. Amikor a SealedSecret-et alkalmazzuk a klaszteren, a Controller a privát kulcsával feloldja (de-seal-eli) és létrehozza a natív Kubernetes Secret-et.

Előnyök:

  • GitOps kompatibilitás: Lehetővé teszi a titkok Git-ben való biztonságos tárolását titkosítva.
  • Egyszerűség: Viszonylag könnyen beállítható és használható kisebb és közepes klaszterekhez.
  • Nincs külső függőség: Nem igényel külső titokkezelő rendszert, ami leegyszerűsíti az infrastruktúrát.

Hátrányok:

  • Kulcskezelés: A privát kulcsot biztonságosan kell tárolni. Ha elveszik, nem tudjuk de-seal-elni a titkokat.
  • Nincs központi felügyelet: Nem nyújt központi titokkezelő szolgáltatást, auditálást vagy dinamikus titkokat.

2. Külső titokkezelő rendszerek integrálása

Ez a megközelítés a legbiztonságosabb és legrugalmasabb, mivel a titkokat a Kubernetesen kívül, dedikált, biztonságos rendszerekben tároljuk. A Kubernetes alkalmazások ezután valamilyen módon lekérdezik ezeket a titkokat a futás során.

HashiCorp Vault

A HashiCorp Vault egy ipari szabványnak számító, nyílt forráskódú titokkezelő rendszer, amely képes dinamikus titkokat generálni, tanúsítványokat kezelni, titkokat rotálni és átfogó auditálhatóságot biztosítani.

Integráció Kubernetes-szel:
  • Vault Agent Injector: Ez egy Kubernetes Mutating Admission Webhook, amely automatikusan injektál egy Vault Agent sidecar konténert a Pod-okba. A sidecar felelős a titkok lekérdezéséért a Vault-ból és azok fájlrendszerbe történő mount-olásáért.
  • Kubernetes Auth Method: A Vault képes hitelesíteni Kubernetes Service Account tokenekkel, így a Pod-ok megbízhatóan azonosíthatják magukat a Vault felé anélkül, hogy további titkokra lenne szükségük a hitelesítéshez.
Előnyök:
  • Centralizált titokkezelés: Egyetlen helyen kezelhetők az összes titok, nem csak a Kuberneteshez kapcsolódók.
  • Dinamikus titkok: A Vault képes időleges, egyszer használatos titkokat generálni (pl. adatbázis jelszavak, AWS IAM kulcsok), amelyek automatikusan lejárnak és visszavonódnak.
  • Széleskörű integráció: Támogatja számos felhőszolgáltatót és adatbázist.
  • Auditálás: Részletes naplózás minden titokhozzáférésről.
  • Titok rotáció: Automatikusan rotálhatja a titkokat.
Hátrányok:
  • Komplexitás: Beállítása és fenntartása összetettebb, mint a natív Secret vagy Sealed Secrets.
  • Infrastruktúra overhead: Külön infrastruktúrát igényel a Vault futtatásához és magas rendelkezésre állásának biztosításához.

Felhő szolgáltatók titokkezelői

A nagy felhőszolgáltatók is kínálnak saját, menedzselt titokkezelő szolgáltatásokat, amelyek szorosan integrálódnak az adott felhő platformmal:

  • AWS Secrets Manager / AWS Parameter Store (SSM)
  • Azure Key Vault
  • Google Secret Manager

Ezek az eszközök hasonló funkciókat kínálnak, mint a Vault, de az adott felhő ökoszisztémájába integrálva. A Kubernetes-szel való integrációjuk gyakran operátorok (pl. External Secrets Operator) vagy CSI illesztők (Container Storage Interface Secret Store Driver) segítségével történik.

External Secrets Operator (ESO)

Az External Secrets Operator (ESO) egy Kubernetes operátor, amely lehetővé teszi, hogy a külső titokkezelő rendszerekben tárolt titkokat natív Kubernetes Secret objektumokként tegyük elérhetővé a klaszterben. Ez hibrid megközelítés: a titkokat továbbra is külsőleg tároljuk és kezeljük, de az alkalmazások számára natív Kubernetes Secret-ként jelennek meg.

Hogyan működik az ESO?

Az ESO a ExternalSecret nevű Custom Resource Definition (CRD) objektumokat figyeli. Ezek a CRD-k definiálják, hogy melyik külső titkot melyik külső titokkezelő rendszerből (pl. AWS Secrets Manager, Azure Key Vault, HashiCorp Vault) kell lekérdezni, és milyen néven kell Kubernetes Secret-ként létrehozni a klaszterben. Az operátor rendszeresen szinkronizálja ezeket a titkokat, biztosítva, hogy a Kubernetes Secret mindig naprakész legyen.

Előnyök:
  • Egyszerű alkalmazás oldali integráció: Az alkalmazások a megszokott módon, natív Kubernetes Secret-ekből olvashatják a titkokat.
  • Külső rendszerek előnyeinek kihasználása: Profitálhatunk a külső titokkezelők biztonsági, auditálási és rotálási funkcióiból.
  • Flexibilitás: Támogatja a legtöbb népszerű külső titokkezelő rendszert.
Hátrányok:
  • Titkok megjelenése: Bár csak ideiglenesen és az operátor által felügyelten, a titkok egy időre Plain-text (Base64 kódolt) formában megjelennek natív Kubernetes Secret-ekben a klaszterben. Ez egy „bizalmi határ” kérdése – ha a klaszter maga nem biztonságos, ez is kockázatot jelent.
  • Mégis szükség van külső rendszerre: Az ESO csak egy „híd”, nem egy titokkezelő rendszer önmagában.

Best Practices a titkok és konfigurációk kezeléséhez

A megfelelő eszközök kiválasztása mellett elengedhetetlen a best practices betartása a titkok és konfigurációk biztonságos és hatékony kezelése érdekében:

  • Titkok soha ne kerüljenek Git-be! Ez a legfontosabb szabály. Kivéve, ha titkosítva vannak olyan megoldással, mint a Sealed Secrets. Még ekkor is a kódolt formát tároljuk, sosem a nyers titkot.
  • Használjuk a legkevesebb privilégium elvét (least privilege): Az alkalmazásokhoz csak azokhoz a titkokhoz férjenek hozzá, amelyekre feltétlenül szükségük van, és csak a szükséges jogosultságokkal. Alkalmazzunk megfelelő RBAC (Role-Based Access Control) szabályokat a Secret-ekhez való hozzáférés korlátozására.
  • Rendszeres titok rotáció: A kulcsokat és jelszavakat automatikusan vagy rendszeres időközönként cseréljük. A Vault és a felhőalapú titokkezelők automatizálják ezt a folyamatot.
  • Auditálás és naplózás: Kövessük nyomon, ki, mikor és milyen titkokhoz fér hozzá. Az audit naplók kulcsfontosságúak a biztonsági incidensek felderítésében és a compliance követelmények teljesítésében.
  • Környezetspecifikus titkok: Külön titkokat használjunk fejlesztési, teszt és éles környezethez. Soha ne használjunk éles titkokat nem-éles környezetekben.
  • GitOps megközelítés konfigurációkhoz: A nem érzékeny konfigurációk (ConfigMaps) legyenek Git-ben verziókövetve. Ez biztosítja a „single source of truth” elvét és megkönnyíti a változások nyomon követését.
  • Ne használjunk alapértelmezett Service Account-ot: Hozzunk létre specifikus Service Account-okat a Pod-ok számára, és rendeljünk hozzájuk minimális RBAC jogosultságokat. Ne adjunk feleslegesen széleskörű jogosultságokat a Service Account-oknak.
  • Hardkódolás elkerülése: Soha ne írjunk jelszavakat, API kulcsokat vagy egyéb érzékeny adatokat közvetlenül a kódban, konténer image-ekben vagy konfigurációs fájlokban.
  • KMS (Key Management System) integráció: A titkok titkosításához használt fő kulcsok kezelését bízzuk egy dedikált KMS rendszerre (pl. AWS KMS, Azure Key Vault, Google KMS), amely magas szintű biztonságot és rendelkezésre állást nyújt.
  • Immutábilis konfigurációk: Lehetőleg ne változtassuk a ConfigMap-eket és Secret-eket futás közben. Új verzió telepítésekor inkább hozzunk létre egy új ConfigMap-et vagy Secret-et a frissített adatokkal, és végezzünk rolling update-et a Deployment-en, hogy az alkalmazás a frissített verziót használja.
  • Készítsünk biztonsági mentést: A kritikus titkokról mindig legyen biztonsági másolat, ideális esetben offline és titkosított formában.
  • Titkosítás in-transit és at-rest: Gondoskodjunk róla, hogy az adatok titkosítva legyenek tároláskor (at-rest encryption) és hálózati forgalomban egyaránt (in-transit encryption, pl. TLS/SSL használatával).

Konfigurációk frissítése és újratöltése

Mi történik, ha egy ConfigMap vagy Secret tartalma megváltozik? Fontos megérteni, hogy a Kubernetes alapértelmezetten nem frissíti automatikusan a már futó Pod-okhoz mountolt fájlokat vagy a környezeti változókat. A változások érvényesítéséhez általában újra kell indítani a Pod-okat, vagy az alkalmazásnak magának kell figyelnie a változásokat.

  • Deployment újraindítása (Rolling Update): Ez a leggyakoribb megközelítés. A Deployment-en végzett változás (pl. egy annotáció frissítése, ami nem kapcsolódik a ConfigMap-hez) triggerelhet egy rolling update-et, amely során új Pod-ok indulnak el a frissített konfigurációval.
  • Figyelő konténerek: Egyes alkalmazások vagy sidecar konténerek figyelhetik a konfigurációs fájlok változásait a mountolt volume-okon, és újraindíthatják az alkalmazást, vagy újratölthetik a konfigurációt futás közben.
  • Helm Hooks: A Helm package managerrel lehetőség van „hooks” (horgok) definiálására, amelyek segíthetnek a konfigurációs frissítések koordinálásában, bár ez sem automatizálja a futó Pod-ok frissítését.

Összefoglalás

A titkok és konfigurációk menedzselése Kubernetesben egy komplex feladat, amely alapos tervezést, a megfelelő eszközök kiválasztását és a szigorú biztonsági gyakorlatok betartását igényli. A natív ConfigMap és Secret objektumok remek kiindulópontot jelentenek, de a valódi biztonsághoz, skálázhatósághoz és auditálhatósághoz elengedhetetlen a fejlett stratégiák – mint például a Sealed Secrets a GitOps-hoz, vagy a külső titokkezelő rendszerek, mint a HashiCorp Vault vagy a felhőalapú titokkezelők az External Secrets Operator segítségével – alkalmazása. A fenti best practices betartásával jelentősen növelhetjük alkalmazásaink biztonságát, megbízhatóságát és a fejlesztési folyamat hatékonyságát a Kubernetes környezetben. A kulcs a réteges védelemben, az automatizálásban és a folyamatos odafigyelésben rejlik.

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük