A modern, felhőalapú alkalmazások fejlesztésében és üzemeltetésében a Kubernetes vált de facto szabvánnyá a konténerizált munkafolyamatok orchestrálására. Egyik alapvető erőssége abban rejlik, hogy képes kezelni a konténerek efemer, azaz rövid élettartamú és állapotmentes jellegét. Ez a tulajdonság azonban komoly kihívásokat vet fel az adattárolás terén, hiszen a legtöbb valós alkalmazásnak szüksége van valamilyen formában perzisztens, azaz tartós adatra. Itt lépnek színre a Kubernetes kötetek (Volumes), amelyek kulcsfontosságú szerepet játszanak a podokon belüli adattárolás és adatmegosztás biztosításában.
A Kubernetes kontextusában a kötet egy olyan absztrakció, amely lehetővé teszi a konténerek számára, hogy hozzáférjenek egy adott tárolóhelyhez, amelynek élettartama független a konténer élettartamától. Más szóval, míg egy konténer újraindulhat, összeomolhat vagy törlődhet, a hozzá csatolt kötet adatai megmaradhatnak, vagy éppen megoszthatók más konténerekkel ugyanazon a podon belül.
A konténerizáció kihívásai és az adattárolás alapvető problémája
A konténerek, mint például a Docker konténerek, alapvetően efemer, azaz ideiglenes környezetek. Minden konténer a saját izolált fájlrendszerével indul el, amely a konténer image-éből épül fel. Amikor egy konténer leáll vagy törlődik, minden változás, amelyet a fájlrendszerében eszközöltek, elveszik. Ez a tervezési elv kiválóan alkalmas állapotmentes (stateless) alkalmazások futtatására, amelyek nem tárolnak adatokat helyben, vagy az adatokat külső adatbázisokba, üzenetsorokba írják.
Azonban a valóságban a legtöbb alkalmazásnak szüksége van valamilyen formában állapotra. Gondoljunk csak adatbázisokra, fájlszerverekre, tartalomkezelő rendszerekre vagy bármely olyan alkalmazásra, amely felhasználói adatokat, konfigurációt vagy logokat generál. Ha ezeket az alkalmazásokat konténerizáljuk anélkül, hogy perzisztens tárolást biztosítanánk, az adatvesztés elkerülhetetlen lenne a konténer újraindulásakor vagy áthelyezésekor.
A másik fontos szempont az adatok megosztásának igénye. Egy podon belül gyakran fut több konténer is, amelyeknek ugyanazokhoz az adatokhoz kell hozzáférniük. Például egy webes alkalmazás konténerének és egy loggyűjtő segédkonténernek ugyanazt a log fájlt kell elérnie. A konténerek alapértelmezett izolációja miatt ez nem lehetséges külső mechanizmus nélkül.
A Kubernetes kötetek pontosan ezekre a problémákra kínálnak megoldást. Lehetővé teszik az adatok fennmaradását a konténer élettartamán túl, és biztosítják az adatok megosztását a podon belüli konténerek között. Egy kötet lényegében egy könyvtár, amely elérhető a pod összes konténere számára, és amelynek tartalmát a konténerek újraindítása vagy leállítása sem befolyásolja feltétlenül.
A Pod élettartama és a kötetek kapcsolata
A Kubernetes legkisebb üzembe helyezhető egysége a Pod. Egy pod egy vagy több konténert tartalmaz, amelyek közös hálózati névteret, IP-címet és tároló erőforrásokat osztanak meg. Amikor egy pod létrejön, a Kubernetes kiosztja számára a szükséges erőforrásokat, és elindítja a benne definiált konténereket. Amikor egy pod leáll (például a benne futó alkalmazás hibája, a node leállása vagy a felhasználói törlés miatt), a podhoz tartozó összes konténer is leáll, és az ezekben a konténerekben végrehajtott, nem perzisztens változások elvesznek.
Itt jön a kötetek kritikus szerepe: egy Kubernetes kötet élettartama szigorúan a pod élettartamához kötődik, de hosszabb, mint az egyes konténerek élettartama a podon belül. Ez azt jelenti, hogy ha egy konténer a podon belül összeomlik és újraindul, a kötet tartalma érintetlen marad, és az újraindult konténer továbbra is hozzáférhet az adatokhoz. Amikor azonban a pod teljesen megszűnik (törlésre kerül), a hozzá tartozó kötetek is megszűnhetnek, vagy leválaszthatók, a kötet típusától függően. A perzisztens kötetek (Persistent Volumes) esetében az adatok a pod törlése után is megmaradnak, mivel azok élettartama független a podétól, és a mögöttes tárolóinfrastruktúrához kötődik.
Ez a megkülönböztetés alapvető a Kubernetes adattárolási modelljének megértéséhez. A kötetek nem csupán egy könyvtárat jelentenek, hanem egy mechanizmust, amely elválasztja az adatok élettartamát az alkalmazás konténerének élettartamától, ezzel biztosítva az adatok tartósságát és elérhetőségét, még dinamikus és efemer környezetben is.
A Kubernetes kötetek alapvető célja az, hogy megoldást nyújtsanak a konténerizált alkalmazások efemer jellegéből adódó adattárolási kihívásokra, biztosítva az adatok perzisztenciáját a konténer újraindulásai között, valamint lehetővé téve az adatok megosztását a podon belüli konténerek között, miközben az adatok élettartama szorosan a podhoz, vagy perzisztens kötetek esetén a mögöttes tárolóinfrastruktúrához kötődik.
A Kubernetes kötetek típusai: Részletes áttekintés
A Kubernetes számos különböző kötet típust támogat, amelyek mindegyike más-más célt szolgál, és eltérő tulajdonságokkal rendelkezik az élettartam, a teljesítmény és a mögöttes tároló technológia szempontjából. A megfelelő kötet típus kiválasztása kritikus az alkalmazás igényeinek kielégítéséhez.
1. emptyDir
Az emptyDir
a legegyszerűbb kötet típus. Amint a neve is sugallja, ez egy kezdetben üres könyvtár, amelyet a pod létrehozásakor hoz létre a Kubernetes. Ez a könyvtár a pod élettartamáig létezik. Amikor a pod megszűnik, az emptyDir
kötet tartalma véglegesen törlődik.
- Célja és használati esetei:
- Ideiglenes tárolás: Kiválóan alkalmas ideiglenes adatok, például cache-ek, scratch fájlok vagy futásidejű állapotok tárolására, amelyekre nincs szükség a pod újraindulása után.
- Adatmegosztás a podon belül: Mivel az
emptyDir
kötetet a pod összes konténere elérheti és megoszthatja, ideális a konténerek közötti adatcserére (pl. egy konténer generálja az adatot, egy másik feldolgozza). - Checkpointing: Bizonyos alkalmazások ideiglenesen menthetik az állapotukat egy
emptyDir
kötetbe, mielőtt áthelyezik azt egy perzisztens tárolóba.
- Élettartama: Szigorúan a pod élettartamához kötődik. Ha a pod leáll vagy törlődik, az
emptyDir
tartalma is elveszik. Ha egy konténer összeomlik és újraindul a podon belül, azemptyDir
tartalma megmarad. - Tárolási hely: Alapértelmezés szerint a node bármely elérhető tárolóján (általában a node gyökér fájlrendszerén) jön létre. Opcionálisan beállítható, hogy memóriában (RAM) tárolódjon (
emptyDir: { medium: Memory }
), ami rendkívül gyors, de korlátozott méretű és szintén efemer.
Példa konfiguráció:
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-temp-data
spec:
containers:
- name: app-container
image: nginx
volumeMounts:
- name: temp-storage
mountPath: /app/data
- name: sidecar-container
image: busybox
command: ["sh", "-c", "echo 'Hello from sidecar' > /shared/file.txt && sleep 3600"]
volumeMounts:
- name: temp-storage
mountPath: /shared
volumes:
- name: temp-storage
emptyDir: {}
Ez a példa létrehoz egy emptyDir
kötetet temp-storage
néven, amelyet mindkét konténer csatlakoztat a saját útvonalán. A sidecar-container
ír egy fájlt a megosztott könyvtárba, amelyet az app-container
is olvashatna.
2. hostPath
A hostPath
kötet egy fájlt vagy könyvtárat csatlakoztat a node fájlrendszeréből a podba. Ez azt jelenti, hogy a pod konténerei közvetlenül hozzáférhetnek a node fizikai tárolóján lévő adatokhoz.
- Célja és használati esetei:
- Rendszereszközök elérése: Használható a node operációs rendszerének bizonyos fájljaihoz vagy könyvtáraihoz való hozzáféréshez (pl.
/var/log
a logok gyűjtéséhez,/dev
eszközök eléréséhez). - Speciális esetek: Ritkán használják alkalmazásadatokhoz a hordozhatóság hiánya miatt, de bizonyos infrastruktúra-specifikus feladatokhoz (pl. monitoring ügynökök, hálózati pluginok) hasznos lehet.
- Rendszereszközök elérése: Használható a node operációs rendszerének bizonyos fájljaihoz vagy könyvtáraihoz való hozzáféréshez (pl.
- Biztonsági megfontolások: A
hostPath
kötetek használata általában nem javasolt alkalmazásokhoz a következő okok miatt:- Hordozhatóság hiánya: Az alkalmazás szorosan a node fájlrendszeréhez kötődik, ami megnehezíti a podok más node-okra történő ütemezését vagy a cluster áthelyezését.
- Biztonsági kockázat: A pod teljes hozzáférést kap a node fájlrendszerének egy részéhez, ami biztonsági rést jelenthet, ha a pod kompromittálódik. Egy rosszindulatú konténer hozzáférhet vagy módosíthatja a node kritikus fájljait.
- Adatvesztés kockázata: Ha a node meghibásodik, vagy törlésre kerül, a
hostPath
-on tárolt adatok is elvesznek.
Példa konfiguráció:
apiVersion: v1
kind: Pod
metadata:
name: log-collector
spec:
containers:
- name: collector
image: busybox
command: ["tail", "-f", "/var/log/node-logs/messages"]
volumeMounts:
- name: node-logs
mountPath: /var/log/node-logs
readOnly: true
volumes:
- name: node-logs
hostPath:
path: /var/log
type: DirectoryOrCreate
Ez a példa csatlakoztatja a node /var/log
könyvtárát a pod /var/log/node-logs
útvonalára. Fontos megjegyezni, hogy a type
mezővel megadható a hostPath viselkedése (pl. DirectoryOrCreate
, File
, Socket
stb.).
3. NFS (Network File System)
Az NFS kötetek lehetővé teszik egy meglévő hálózati fájlrendszer (NFS share) csatlakoztatását a podhoz. Az NFS egy elosztott fájlrendszer protokoll, amely lehetővé teszi, hogy egy kliens hozzáférjen a távoli szerveren lévő fájlokhoz, mintha azok helyben lennének.
- Célja és előnyei:
- Megosztott hozzáférés több pod között: Az NFS köteteket több pod is csatlakoztathatja egyszerre, akár különböző node-okon is, ami ideálissá teszi megosztott adatok (pl. weboldal tartalmak, felhasználói feltöltések) tárolására.
- Perzisztencia: Az adatok az NFS szerveren tárolódnak, így függetlenek a podok és a Kubernetes node-ok élettartamától. Ha egy pod leáll, az adatok megmaradnak.
- Egyszerűség: Ha már rendelkezésre áll egy NFS szerver, viszonylag egyszerűen integrálható a Kubernetesbe.
- Hátrányok:
- Központi hibapont: Az NFS szerver meghibásodása az összes hozzá csatolt pod számára elérhetetlenné teszi az adatokat.
- Teljesítmény: A hálózati késleltetés és az NFS szerver teljesítménye befolyásolhatja az alkalmazás sebességét.
- Adminisztráció: Egy külön NFS szerver üzemeltetése és karbantartása szükséges.
- Biztonság: Az NFS alapértelmezett beállításai nem mindig a legbiztonságosabbak, további konfigurációra lehet szükség.
Példa konfiguráció:
apiVersion: v1
kind: Pod
metadata:
name: my-web-app
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- name: nfs-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-storage
nfs:
server: 192.168.1.100 # Az NFS szerver IP címe
path: "/exports/webdata" # Az NFS exportált könyvtára
readOnly: false
Ez a pod az 192.168.1.100
IP-címen található NFS szerver /exports/webdata
könyvtárát csatlakoztatja az Nginx konténer HTML fájljainak tárolására.
4. Perzisztens kötetek (Persistent Volume – PV) és Perzisztens kötet igények (Persistent Volume Claim – PVC)
A PV és PVC a Kubernetes perzisztens tárolási modelljének sarokkövei. Céljuk, hogy absztrakciós réteget biztosítsanak a mögöttes tároló infrastruktúra (például AWS EBS, Google Persistent Disk, Azure Disk, NFS, iSCSI stb.) felett. Ezáltal az alkalmazásfejlesztőknek nem kell ismerniük a tárolórendszer részleteit, és a cluster adminisztrátorok rugalmasan kezelhetik a tárolóerőforrásokat.
Persistent Volume (PV)
A PersistentVolume
(PV) egy cluster-szintű erőforrás, amely egy adott tároló egységet reprezentál a clusterben. Ezt a tárolót a cluster adminisztrátora biztosítja (statikus provisionálás), vagy dinamikusan hozza létre egy tároló szolgáltató (dinamikus provisionálás).
- Definíciója: Egy PV leírja a tároló kapacitását (méret, hozzáférési módok, tároló típus), és a mögöttes tároló részleteit (pl. egy AWS EBS kötet ID-ja, egy NFS szerver címe).
- Élettartama: A PV élettartama teljesen független a podoktól és a node-októl. Ez azt jelenti, hogy ha egy pod törlődik, vagy egy node meghibásodik, a PV és a rajta tárolt adatok érintetlenek maradnak.
- Hozzáférési módok (Access Modes): Meghatározzák, hogy egy kötet hogyan csatolható fel a node-okra:
ReadWriteOnce
(RWO): A kötetet egyszerre csak egy node csatlakoztathatja olvasási/írási módban. Ez a leggyakoribb mód.ReadOnlyMany
(ROX): A kötetet több node is csatlakoztathatja olvasási módban.ReadWriteMany
(RWX): A kötetet több node is csatlakoztathatja olvasási/írási módban. Ezt általában hálózati fájlrendszerek (pl. NFS) támogatják.ReadWriteOncePod
(RWOP): Kubernetes 1.22+ verziótól. A kötetet egyszerre csak egy pod csatlakoztathatja olvasási/írási módban. Ez a mód biztosítja a legszigorúbb korlátozást a pod szintjén, függetlenül a node-tól.
- Reclaim Policy (Visszaállítási házirend): Meghatározza, mi történjen a mögöttes tárolóval, amikor a PV-t használó PVC törlődik:
Retain
: Az adatok megmaradnak a tárolón, a PV állapotba kerül, és manuális beavatkozásra van szükség a törléshez.Delete
: A PV és a mögöttes tároló is törlődik. Ez a dinamikusan létrehozott PV-k alapértelmezett viselkedése.Recycle
(deprecated): Tartalmazta az adatok törlését a köteten, majd újra felhasználhatóvá tételét. Helyette a dinamikus provisionálás és aDelete
policy javasolt.
Példa PV konfiguráció:
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
nfs:
path: /exports/data
server: 192.168.1.200
Ez egy NFS alapú PV-t definiál 10 GB kapacitással, ReadWriteOnce hozzáférési móddal és Retain reclaim policy-vel.
Persistent Volume Claim (PVC)
A PersistentVolumeClaim
(PVC) egy felhasználói (vagy alkalmazás) igény a tárolóerőforrásra. A PVC egy névtér-szintű erőforrás, amelyet az alkalmazásfejlesztők hoznak létre, hogy tárolót igényeljenek a PV-k absztrakciós rétegén keresztül.
- Célja: A PVC lehetővé teszi, hogy az alkalmazásfejlesztők tárolóerőforrásokat igényeljenek anélkül, hogy ismerniük kellene a mögöttes tároló infrastruktúra részleteit. Egyszerűen megadják a szükséges méretet, hozzáférési módot és opcionálisan a kívánt tárolóosztályt.
- Kötés (Binding): Amikor egy PVC létrejön, a Kubernetes megpróbálja megkeresni a clusterben egy megfelelő, szabad PV-t, amely kielégíti a PVC igényeit (méret, hozzáférési módok, StorageClass). Ha talál ilyet, összekapcsolja (bindeli) a PV-t a PVC-vel. Ezt követően a PV már nem érhető el más PVC-k számára.
Példa PVC konfiguráció:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
Ez egy PVC-t definiál, amely 5 GB tárhelyet igényel ReadWriteOnce módban, a „standard” StorageClass-ból.
StorageClass
A StorageClass
egy cluster-szintű erőforrás, amely egy „osztályt” vagy „profilt” definiál a tárolóerőforrásokhoz. Lehetővé teszi a dinamikus provisionálást, ami azt jelenti, hogy a Kubernetes automatikusan létrehozza a mögöttes tárolót (pl. egy új AWS EBS kötetet) a felhőszolgáltatónál, amikor egy PVC igényli azt.
- Célja: A StorageClassok lehetővé teszik a tárolóerőforrások finomhangolását (pl. teljesítmény szint, replikáció, biztonsági mentési politika) és az automatikus provisionálást.
- Dinamikus provisionálás: Ez az előny a legfontosabb. Ahelyett, hogy a cluster adminisztrátornak manuálisan kellene létrehoznia a PV-ket, a StorageClass definiálja, hogyan hozza létre a tárolórendszer a PV-t, amikor egy PVC igényli azt.
- Provisioner: Minden StorageClass egy
provisioner
-t használ, amely egy adott tárolórendszerhez (pl.kubernetes.io/aws-ebs
,kubernetes.io/gce-pd
,csi.hetzner.cloud
) tartozó illesztőprogram.
Példa StorageClass konfiguráció:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-disks
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
fstype: ext4
reclaimPolicy: Delete
volumeBindingMode: Immediate
Ez a StorageClass dinamikusan hoz létre Google Cloud Platform (GCP) SSD típusú perzisztens lemezeket, amelyek ext4 fájlrendszerrel vannak formázva. Amikor egy PVC ezt a StorageClass-t igényli, a GCP-n létrejön egy új SSD lemez.
PV, PVC és Pod összekapcsolása
A podok a PVC-ken keresztül hivatkoznak a tárolóra. A pod definíciójában a volumes
szekcióban hivatkozunk a PVC nevére, majd a konténer volumeMounts
szekciójában csatlakoztatjuk a kívánt útvonalra.
Példa Pod konfiguráció PVC-vel:
apiVersion: v1
kind: Pod
metadata:
name: my-database-pod
spec:
containers:
- name: database
image: postgres
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: db-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: db-storage
persistentVolumeClaim:
claimName: my-pvc # A korábban definiált PVC neve
Ez a pod a my-pvc
nevű PVC-t használja, amely egy PV-hez van bindelve, amely pedig a mögöttes tárolóinfrastruktúrához. Az adatbázis adatai a /var/lib/postgresql/data
útvonalon tárolódnak, és perzisztensek maradnak a pod újraindítása vagy törlése esetén is (amennyiben a PV reclaim policy-je megfelelő).
A PV/PVC modell előnyei:
- Absztrakció: Elválasztja a tároló infrastruktúra részleteit az alkalmazásoktól.
- Dinamikus provisionálás: Automatikusan biztosítja a tárolóerőforrásokat igény szerint.
- Hordozhatóság: Az alkalmazások könnyebben áttelepíthetők különböző Kubernetes clusterek vagy felhőszolgáltatók között.
- Rugalmasság: A cluster adminisztrátorok rugalmasan kezelhetik a tárolóerőforrásokat.
5. ConfigMap és Secret
Bár nem hagyományos értelemben vett adattárolási megoldások, a ConfigMap
és a Secret
is használhatók kötetként a podokon belül, hogy konfigurációs adatokat vagy érzékeny információkat tegyenek elérhetővé a konténerek számára fájlként.
ConfigMap
A ConfigMap
kulcs-érték párokat tárol, amelyeket nem érzékeny konfigurációs adatokhoz használnak. Ezek az adatok beilleszthetők a konténerek környezeti változóiként, parancssori argumentumaiként, vagy fájlként csatolhatók egy kötetbe.
- Célja: Alkalmazáskonfigurációk, nem érzékeny API kulcsok, környezeti változók tárolása.
- Kötetként való használat: Amikor egy
ConfigMap
-et kötetként csatolunk, aConfigMap
minden kulcs-érték párja egy külön fájlként jelenik meg a megadott csatolási útvonalon, a kulcs nevével azonos fájlnévvel.
Példa ConfigMap kötetként:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
database_url: "jdbc:postgresql://db:5432/mydb"
log_level: "INFO"
---
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: my-app
image: my-custom-app
volumeMounts:
- name: config-volume
mountPath: /etc/app-config
volumes:
- name: config-volume
configMap:
name: my-config
Ebben a példában a /etc/app-config/database_url
és a /etc/app-config/log_level
fájlok jönnek létre a konténerben, amelyek tartalmazzák a ConfigMap
-ben definiált értékeket.
Secret
A Secret
hasonló a ConfigMap
-hez, de érzékeny adatok, például jelszavak, API kulcsok, OAuth tokenek vagy SSH kulcsok tárolására szolgál. A Secret adatokat base64 kódolással tárolja, de ez nem titkosítás! A Secret adatok titkosítva tárolódnak a Kubernetes API szerver adatbázisában (etcd), ha a titkosítás engedélyezve van.
- Célja: Érzékeny adatok biztonságos kezelése és eljuttatása a podokhoz.
- Kötetként való használat: A
Secret
is kötetként csatolható, hasonlóan aConfigMap
-hez. Minden kulcs egy fájlként jelenik meg a csatolási útvonalon. A fájlok tartalmát a Kubernetes dekódolja, így a konténer olvasható formában fér hozzájuk.
Példa Secret kötetként:
apiVersion: v1
kind: Secret
metadata:
name: my-db-credentials
type: Opaque
data:
username: dXNlcg== # "user" base64 kódolva
password: cGFzcw== # "pass" base64 kódolva
---
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: db-client
image: mysql-client
volumeMounts:
- name: credentials-volume
mountPath: /etc/db-credentials
readOnly: true
volumes:
- name: credentials-volume
secret:
secretName: my-db-credentials
Ebben a példában a /etc/db-credentials/username
és a /etc/db-credentials/password
fájlok jönnek létre a konténerben, amelyek tartalmazzák a dekódolt felhasználónevet és jelszót.
6. Projected Volumes
A Projected
kötetek lehetővé teszik több kötetforrás (ConfigMap
, Secret
, downwardAPI
, serviceAccountToken
) tartalmának egyetlen könyvtárba történő „vetítését”. Ez hasznos, ha több konfigurációs vagy biztonsági forrásból származó adatot kell egyetlen, egységes fájlrendszerstruktúrában elérhetővé tenni.
- Célja: Egységes hozzáférés biztosítása különböző forrásokból származó adatokhoz.
- Források:
ConfigMap
: Konfigurációs adatok.Secret
: Érzékeny adatok.downwardAPI
: Pod metadata (pl. pod neve, namespace, IP cím) fájlokként.serviceAccountToken
: A podhoz tartozó Service Account token, amely a Kubernetes API-hoz való hitelesítésre szolgál.
Példa Projected Volume konfiguráció:
apiVersion: v1
kind: Pod
metadata:
name: projected-volume-pod
spec:
containers:
- name: my-app
image: my-custom-app
volumeMounts:
- name: all-in-one-config
mountPath: /etc/projected-config
readOnly: true
volumes:
- name: all-in-one-config
projected:
sources:
- configMap:
name: my-config
items:
- key: log_level
path: app_log_level
- secret:
name: my-db-credentials
items:
- key: username
path: db_username
- downwardAPI:
items:
- path: pod_name
fieldRef:
fieldPath: metadata.name
- path: pod_namespace
fieldRef:
fieldPath: metadata.namespace
Ez a példa létrehoz egy /etc/projected-config
könyvtárat a konténerben, amely tartalmazza az app_log_level
, db_username
, pod_name
és pod_namespace
fájlokat, amelyek különböző forrásokból származó adatokat tartalmaznak.
7. CSI (Container Storage Interface)
A Container Storage Interface (CSI) egy szabványos interfész, amely lehetővé teszi a Kubernetes számára, hogy külső tárolórendszerekkel kommunikáljon és azokból dinamikusan provisionáljon köteteket. A CSI a Kubernetes 1.9-es verziójával jelent meg, és mára a preferált módszer a külső tárolók integrálására.
- Miért jött létre? Korábban minden tároló illesztőprogram be volt építve a Kubernetes magjába. Ez azt jelentette, hogy egy új tárolórendszer támogatásához frissíteni kellett a Kubernetes-t, és a tárolófejlesztőknek szorosan együtt kellett működniük a Kubernetes fejlesztőkkel. A CSI egy független, vendor-agnosztikus szabványt biztosít, amely lehetővé teszi a tárolófejlesztők számára, hogy saját CSI illesztőprogramokat (CSI drivers) fejlesszenek és telepítsenek a Kubernetes clusterbe, anélkül, hogy a Kubernetes magját módosítani kellene.
- Működési elv: A CSI driverek egy sor API-t implementálnak, amelyek lehetővé teszik a Kubernetes számára, hogy tároló műveleteket (pl. kötet létrehozása, törlése, csatlakoztatása, leválasztása, pillanatfelvétel készítése) végezzen a mögöttes tárolórendszeren.
- Előnyök:
- Bővíthetőség: Könnyen hozzáadhatók új tárolórendszerek támogatásai.
- Függetlenség: A tárolófejlesztők függetlenül fejleszthetnek és adhatnak ki illesztőprogramokat.
- Funkcionalitás: Támogatja az összetettebb tárolófunkciókat, mint például a kötetek pillanatfelvételei, klónozása és átméretezése.
- Stabilitás: Kevesebb kód a Kubernetes magjában, ami növeli a stabilitást.
- Használata: A CSI köteteket StorageClass-on keresztül használják, amely a CSI driver nevét adja meg provisionerként.
A legtöbb felhőszolgáltató (AWS, GCP, Azure) és on-premise tároló szolgáltató (Ceph, NetApp, Portworx, Pure Storage stb.) rendelkezik CSI driverrel, amely lehetővé teszi a PV/PVC modell zökkenőmentes használatát a saját tároló termékeikkel.
8. Egyéb kötet típusok (rövid említés)
A Kubernetes számos egyéb, specifikusabb kötet típust is támogat, bár némelyikük elavult vagy ritkábban használt:
- gitRepo (deprecated): Lehetővé tette egy Git repository klónozását egy kötetbe a pod indításakor. A Kubernetes 1.20-tól elavult. Helyette egy init konténer használata javasolt, amely klónozza a repót egy
emptyDir
kötetbe. - subPath: Nem önálló kötet típus, hanem egy opció a
volumeMounts
-ban. Lehetővé teszi, hogy egy kötetnek csak egy alkönyvtárát csatlakoztassuk a konténerbe. Ez hasznos lehet, ha egyetlen PV-ről több konténernek kell hozzáférnie különböző alkönyvtárakhoz. - Ephemeral Volumes (CSI Ephemeral, Generic Ephemeral Volumes): Ezek a kötetek dinamikusan jönnek létre és törlődnek a pod élettartamával együtt, de a mögöttes tárolórendszert a CSI driver kezeli. Hasznosak lehetnek rövid élettartamú, nagy teljesítményű ideiglenes tároláshoz, például scratch space-hez vagy cache-ekhez, ahol az
emptyDir
nem elegendő. - Specifikus felhőalapú kötetek: Pl.
awsElasticBlockStore
,gcePersistentDisk
,azureDisk
,azureFile
. Ezek a felhőszolgáltatók saját tároló megoldásai, amelyek közvetlenül integrálhatók PV-k nélkül is (bár a PV/PVC modell használata javasolt). - Hálózati tárolók: Pl.
glusterfs
,cephfs
,iscsi
,fibreChannel
. Ezek is hálózati tárolórendszerek, amelyek közvetlenül csatolhatók. Ma már sok esetben CSI drivereken keresztül érhetők el.
Kötetek csatlakoztatása (mounting) és használata a Pod-ban
Miután egy kötetet definiáltunk a pod specifikációjában a volumes
szekcióban, azt csatlakoztatni kell a podon belüli konténerekhez. Ez a volumeMounts
szekcióban történik a konténer definíciójában.
name
: A csatlakoztatni kívánt kötet neve, amelynek meg kell egyeznie avolumes
szekcióban definiált névvel.mountPath
: Az útvonal a konténer fájlrendszerén belül, ahová a kötetet csatlakoztatni kell. Ez az útvonal lesz a kötet gyökere a konténer számára.readOnly
(opcionális): Hatrue
-ra van állítva, a kötet csak olvasható módban lesz csatlakoztatva a konténer számára. Ez növeli a biztonságot és megakadályozza a véletlen adatmódosítást.subPath
(opcionális): Lehetővé teszi egy kötetnek csak egy alkönyvtárának csatlakoztatását a konténerbe. Ez különösen hasznos, ha egyetlen kötetet több célra használnak, vagy ha egy ConfigMap/Secret-ből csak bizonyos fájlokat szeretnénk csatolni.
Példa több konténer és subPath használatára:
apiVersion: v1
kind: Pod
metadata:
name: multi-container-volume
spec:
volumes:
- name: shared-data
emptyDir: {}
- name: config-data
configMap:
name: my-multi-config
containers:
- name: writer-container
image: busybox
command: ["sh", "-c", "echo 'Data from writer' > /data/shared_file.txt && sleep 3600"]
volumeMounts:
- name: shared-data
mountPath: /data
- name: config-data
mountPath: /app/config/general # Csatolja az egész ConfigMap-et
- name: reader-container
image: busybox
command: ["sh", "-c", "cat /data/shared_file.txt && cat /app/config/specific_setting && sleep 3600"]
volumeMounts:
- name: shared-data
mountPath: /data
- name: config-data
mountPath: /app/config/specific_setting # Csatolja a ConfigMap egy konkrét fájlját
subPath: specific_setting
Ez a példa bemutatja, hogyan oszthat meg egy emptyDir
kötetet két konténer, és hogyan csatolható egy ConfigMap
részlegesen (subPath
használatával) az egyik konténerbe.
Adatkezelési stratégiák Kubernetesben
A Kubernetes kötetek ismerete alapvető fontosságú a hatékony adatkezelési stratégiák kidolgozásához a konténerizált környezetben.
Állapotfüggetlen (Stateless) és Állapotfüggő (Stateful) alkalmazások
- Állapotfüggetlen: Az alkalmazás nem tárol semmilyen adatot helyben, minden szükséges információt külső forrásokból (pl. adatbázisok, üzenetsorok, külső API-k) szerez be. Ezek a podok könnyen skálázhatók és önjavítók, mivel bármelyik példány lecserélhető anélkül, hogy adatvesztés történne. Az
emptyDir
kötetek használhatók ideiglenes, nem kritikus adatokhoz. - Állapotfüggő: Az alkalmazásnak szüksége van perzisztens tárolásra az adataihoz (pl. adatbázisok, fájlszerverek). Ezekhez az alkalmazásokhoz elengedhetetlenek a Persistent Volume-ok és Persistent Volume Claim-ek. A Kubernetes biztosít egy speciális vezérlőt is az állapotfüggő alkalmazásokhoz, a StatefulSet-et, amely garantálja a podok stabil hálózati identitását és a perzisztens tárolóhoz való kötést, még pod újraindulás vagy áthelyezés esetén is.
Adatbázisok futtatása Kubernetesen
Adatbázisok futtatása Kubernetesen egyre gyakoribb, de gondos tervezést igényel. Kulcsfontosságú a perzisztens tárolás (PV/PVC) biztosítása a tényleges adatfájlok számára. Emellett figyelembe kell venni a magas rendelkezésre állást, a biztonsági mentést és visszaállítást, valamint a teljesítményt. A StatefulSet vezérlő segít az adatbázis klaszterek üzemeltetésében a stabil identitás és a kötetek garantált hozzárendelése révén.
Loggyűjtés és Monitoring
A konténerizált alkalmazások logjainak gyűjtése és elemzése létfontosságú az üzemeltetéshez. A logok alapértelmezés szerint a konténer stdout/stderr kimenetére kerülnek, amelyeket a konténer futtatókörnyezet (pl. containerd) gyűjt össze. Ezeket a logokat általában egy külső log aggregációs rendszerbe (pl. Elasticsearch, Splunk, Loki) továbbítják. Bizonyos esetekben, ha az alkalmazás fájlba írja a logokat, egy emptyDir
kötet vagy egy perzisztens kötet használható ideiglenes tárolásra, mielőtt egy sidecar konténer továbbítja azokat. A hostPath
kötetek használhatók a node-szintű logok (pl. Kubelet logok) gyűjtésére.
Biztonsági mentés és visszaállítás
A perzisztens adatokról rendszeres biztonsági mentést kell készíteni. A Kubernetes ökoszisztémában számos eszköz létezik erre, mint például a Velero, amely a Kubernetes API-t és a CSI pillanatfelvétel funkcióit használja a kötetekről és cluster állapotról történő biztonsági mentéshez, majd visszaállításhoz. Fontos megérteni, hogy a PV/PVC csak a tárolóerőforrást kezeli, a biztonsági mentésért és a visszaállításért az alkalmazásnak vagy egy külső eszköznek kell gondoskodnia.
Adatmigráció
Az adatok migrálása Kubernetes clusterek között vagy a tárolórendszerek cseréje során összetett feladat lehet. A CSI-alapú kötetek és a CSI pillanatfelvételek/klónok jelentősen leegyszerűsítik ezt a folyamatot, lehetővé téve a kötetek gyors másolását vagy áthelyezését. A megfelelő reclaim policy (pl. Retain
) beállítása kulcsfontosságú, hogy az adatok ne vesszenek el a PV/PVC törlésekor.
Biztonsági megfontolások és legjobb gyakorlatok
A Kubernetes kötetek konfigurálása során a biztonság mindig prioritás kell, hogy legyen. Hibás beállítások komoly sérülékenységeket okozhatnak.
hostPath
kockázatai: Ahogy korábban említettük, ahostPath
kötetek használata biztonsági kockázatot jelent, mivel hozzáférést biztosítanak a node fájlrendszeréhez. Kerülje a használatát, hacsak nem feltétlenül szükséges, és akkor is csak olvasási módban (readOnly: true
) és a legszűkebb hozzáférési jogokkal.Secret
kezelés:- Titkosítás: Győződjön meg róla, hogy az etcd (a Kubernetes adatbázisa) titkosítva tárolja a Secreteket. Ez alapértelmezés szerint nem mindig van bekapcsolva.
- Hozzáférés-vezérlés (RBAC): Korlátozza a Secret-ekhez való hozzáférést Role-Based Access Control (RBAC) segítségével. Csak azoknak a felhasználóknak és Service Account-oknak legyen engedélye a Secret-ek olvasására, akiknek feltétlenül szükségük van rá.
- Külső Secret menedzserek: Fontolja meg külső Secret menedzserek (pl. HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) integrálását, amelyek további biztonsági rétegeket (pl. központi kezelés, auditálás, rotáció) biztosítanak.
- Hozzáférés-vezérlés (RBAC) a PVC-khez: Bár a PVC-k nem tartalmaznak érzékeny adatokat, az RBAC használatával korlátozható, hogy mely felhasználók vagy Service Account-ok hozhatnak létre, módosíthatnak vagy törölhetnek PVC-ket.
- Fájlrendszer jogosultságok: A csatlakoztatott kötetek fájlrendszer jogosultságainak helyes beállítása (UID, GID) kritikus. A
securityContext
a pod vagy konténer szintjén lehetővé teszi a felhasználói és csoportazonosítók beállítását, amelyekkel a konténer folyamatai futnak, így kontrollálva a fájlrendszer hozzáférést. - Kvóták és erőforrás-korlátok: A
ResourceQuota
használatával korlátozhatók a névtérben létrehozható PV-k és PVC-k száma és mérete, megelőzve a tárolóerőforrások túlzott felhasználását.
Teljesítmény és skálázhatóság
A Kubernetes kötetek teljesítménye és skálázhatósága szorosan összefügg a mögöttes tárolórendszerrel és a hálózati infrastruktúrával. A konténerizáció előnyei csak akkor érvényesülnek igazán, ha az adatelérés nem válik szűk keresztmetszetté.
- A tároló típusának hatása a teljesítményre:
- SSD vs. HDD: Az SSD alapú tárolók (pl. felhőalapú SSD-k, NVMe) sokkal jobb I/O teljesítményt nyújtanak, mint a hagyományos HDD-k. Állapotfüggő alkalmazások, különösen adatbázisok esetében az SSD használata szinte elengedhetetlen.
- Hálózati tárolók (NFS, CephFS) vs. Blokk tárolók (EBS, GCE PD): A hálózati fájlrendszerek (NFS) megoszthatók több pod között, de a hálózati késleltetés és az NFS szerver teljesítménye korlátozó tényező lehet. A blokk tárolók (Persistent Disk, Elastic Block Store) általában jobb I/O teljesítményt nyújtanak, de jellemzően csak egyetlen node-hoz csatolhatók ReadWriteOnce módban.
- Lokalitás: Ha lehetséges, válasszon olyan tároló megoldást, amely közel van a Kubernetes node-okhoz, vagy azonos adatközpontban/zónában található, hogy minimalizálja a hálózati késleltetést.
- I/O műveletek optimalizálása:
- Fájlrendszer optimalizálás: A fájlrendszer típusának (pl. ext4, XFS) és opcióinak helyes beállítása javíthatja a teljesítményt.
- Alkalmazás szintű optimalizálás: Az alkalmazásnak hatékonyan kell kezelnie az I/O-t (pl. aszinkron I/O, adatbázis indexek, cache-elés).
- Monitoring: Figyelje az I/O metrikákat (IOPS, átviteli sebesség, késleltetés) a tárolórendszeren és a podokon belül, hogy azonosítsa a szűk keresztmetszeteket.
- Skálázhatósági szempontok:
- Tároló cluster: Nagyobb, elosztott alkalmazásokhoz skálázható tároló clusterek (pl. Ceph, Portworx) használata javasolt, amelyek képesek kezelni a növekvő adatmennyiséget és I/O terhelést.
- Dinamikus provisionálás: A StorageClass és a dinamikus provisionálás kulcsfontosságú a skálázhatóság szempontjából, mivel automatikusan képesek új tárolóerőforrásokat biztosítani igény szerint.
- Kötet átméretezés: Modern Kubernetes verziók és CSI driverek támogatják a kötetek online átméretezését, ami lehetővé teszi a tárolókapacitás növelését az alkalmazás leállítása nélkül.
Hibaelhárítás és gyakori problémák
A Kubernetes kötetekkel kapcsolatos problémák gyakoriak lehetnek, különösen a komplexebb tároló beállítások esetén. Íme néhány gyakori probléma és hibaelhárítási tipp:
Pending
állapotú PVC-k:- Ok: A PVC nem tudott PV-hez kötődni.
- Lehetséges okok:
- Nincs megfelelő, szabad PV a clusterben, amely kielégítené a PVC igényeit (méret, hozzáférési módok, StorageClass).
- A StorageClass hibásan van konfigurálva, vagy a mögöttes provisioner nem működik.
- A tárolórendszerben nincs elegendő kapacitás.
- Hibaelhárítás:
- Ellenőrizze a PVC eseményeit:
kubectl describe pvc <pvc-name>
. - Ellenőrizze a StorageClass-t:
kubectl describe sc <storageclass-name>
. - Ellenőrizze a PV-ket:
kubectl get pv
, keressen olyan PV-ket, amelyekAvailable
állapotban vannak, és megfelelnek a PVC igényeinek. - Ha dinamikus provisionálás van használatban, ellenőrizze a CSI driver logjait.
- Ellenőrizze a PVC eseményeit:
CrashLoopBackOff
a nem elérhető kötetek miatt:- Ok: A konténer nem tudja csatlakoztatni a kötetet, vagy nem tud hozzáférni a csatlakoztatott adatokhoz, és ezért összeomlik.
- Lehetséges okok:
- A PVC nem kötődött PV-hez.
- A mögöttes tárolórendszer nem elérhető vagy hibás.
- Fájlrendszer jogosultsági problémák a köteten.
- Hálózati problémák (NFS esetén).
- Helytelen
mountPath
vagysubPath
a konténer definíciójában.
- Hibaelhárítás:
- Ellenőrizze a pod eseményeit:
kubectl describe pod <pod-name>
. - Ellenőrizze a konténer logjait:
kubectl logs <pod-name> -c <container-name>
. - SSH-zzon be a node-ra (ha lehetséges), és ellenőrizze, hogy a kötet csatlakoztatva van-e a node szintjén (
df -h
,mount
) és a jogosultságok helyesek-e. - Ellenőrizze a hálózati kapcsolatot az NFS szerverhez.
- Ellenőrizze a pod eseményeit:
- Engedélyezési problémák:
- Ok: A konténerben futó alkalmazásnak nincs megfelelő jogosultsága a kötetre való íráshoz vagy olvasáshoz.
- Lehetséges okok:
- A fájlrendszer jogosultságai (permissions) nem megfelelőek a csatlakoztatott köteten.
- A konténer egy másik felhasználóval/csoporttal fut, mint amilyen jogosultsággal a könyvtár rendelkezik.
- Hibaelhárítás:
- Használja a
securityContext
-et a pod vagy konténer definíciójában arunAsUser
ésfsGroup
beállításához, hogy a konténer a megfelelő felhasználóként fusson, és a kötet fájlrendszer jogosultságai automatikusan beállítódjanak. - Manuálisan ellenőrizze és állítsa be a jogosultságokat a mögöttes tárolón, ha szükséges.
- Használja a
- Tárolóhely betelése:
- Ok: A PV-hez tartozó mögöttes tároló megtelt.
- Hibaelhárítás:
- Növelje a PV kapacitását, ha a mögöttes tárolórendszer és a CSI driver támogatja az online átméretezést. Ehhez módosítani kell a PVC-t, ami elindítja a PV átméretezését.
- Törölje a felesleges adatokat a köteten.
- Hozzon létre egy nagyobb PV-t és PVC-t, majd migrálja az adatokat.