Kapszulák, konténerek és indulási sorrend a Kubernetes-ben
A Kubernetes az egyik legnépszerűbb konténer-orchesztrációs megoldás, amelyet világszerte alkalmaznak modern, skálázható és megbízható rendszerek építéséhez. A Kubernetes működésének alapját a kapszula (angolul: Pod) fogalma adja. Ez a legkisebb olyan egység, amelyet a Kubernetes kezelni tud.
Habár, mielőtt a K8s világába csöppennénk először a konténerek világával szoktunk megismerkedni. Ezen belül is a Docker szokott az első lépés lenni. Ha Te ez neked is ismerős, akkor furcsa lehet, hogy ott konténereket (angolul: container) kezelünk. Itt mégis a kapszulákat említünk.
Tehát itt nem magával a konténerrel dolgozunk közvetlenül, hanem ezzel a „kapszulázott” egységgel. Ma arról szeretnék nektek írni, hogyan működnek a kapszulák, hogyan épülnek fel, hogyan indulnak el, és hogyan segítik az init konténerek és a sidecar minták a stabil működést.
Mi az a kapszula (Pod)?
A kapszula egy vagy több konténerből áll, amelyeket egy logikai egységként kezelünk. Ezek a konténerek:
- osztoznak ugyanazon IP-címen, amit a Kubernetes hozzárendelt a kapszulához,
- közös tárolókat használhatnak (pl.
emptyDir
típusú ideiglenes fájlrendszer), - együtt futnak ugyanazon a csomóponton (node-on).
A kapszula úgy képzelhető el, mint egy konténercsoport, amely egy folyamat (pl. webalkalmazás) futtatására jött létre, és amelynek egyes részei (pl. naplózó eszköz) ugyanabban a környezetben futnak.
Egy vagy több konténer egy kapszulában?
A legtöbb esetben egy kapszula = egy alkalmazáskonténer. Ez a tiszta és egyszerű megközelítés jól működik. Azonban vannak olyan helyzetek, amikor egy kapszulán belül több konténerre van szükség:
- Segédkonténer (sidecar): naplózáshoz vagy proxy-záshoz
- Adapter konténer: régi interfészek kiszolgálására
- Ambassador konténer: más szolgáltatások eléréséhez
Ezek a konténerek együttesen működnek, megosztják az erőforrásokat, és logikailag egy egységet képeznek. Fontos: nem különleges típusú konténerek ezek – a “sidecar” vagy “adapter” kifejezés csak szerepet jelöl, nem technikai különbséget. Tehát minden konténer ugyanúgy épül fel, csupán más szerepkört szánunk neki.
Indítási sorrend és problémák
A Kubernetes úgy lett tervezve, hogy a kapszulán belüli konténereket párhuzamosan indítsa el. Ez teljesen rendben van, ha az egyes konténerek nem függenek egymástól. De mi történik, ha egyik konténernek előbb készen kell állnia a másik előtt?
Példa:
- Egy adatbázist csak akkor akarunk használni, ha már elérhető és inicializálva van.
- Egy webalkalmazás csak akkor indulhat, ha a konfigurációs fájlok már betöltődtek.
Erre nyújt megoldást az init konténer.
Init konténerek: előkészítés garantált sorrenddel
Az init konténer egy olyan konténer, amely a fő alkalmazáskonténerek előtt indul el, és csak akkor indul tovább a többi konténer, ha az init konténer sikeresen befejezte a feladatát.
Tulajdonságai:
- Teljesen független a fő konténerektől
- Saját képpel és jogosultságokkal rendelkezhet
- Ha hibásan fut, a fő konténerek nem indulnak el
- Addig ismétlődik az indítás, amíg sikeresen le nem fut
Ez lehetővé teszi például, hogy:
- megvárjuk egy adatbázis elérhetőségét,
- végrehajtsunk fájlműveleteket vagy jogosultság-módosításokat, amelyekhez az alkalmazáskonténer nem fér hozzá.
Példa YAML definíció:
containers:
- name: main-app
image: databaseD
initContainers:
- name: wait-database
image: busybox
command: ['sh', '-c', 'until ls /db/dir ; do sleep 5; done;']
Ebben az esetben a fő alkalmazáskonténer csak akkor indul el, ha a /db/dir
mappa elérhető. Ugye milyen hasznos ez?
Erőforrás-korlátozás kapszulán belül
A Kubernetes lehetőséget ad arra, hogy minden konténer számára meghatározzuk, mekkora erőforrást kérhet és használhat:
resources:
limits:
cpu: "1"
memory: "4Gi"
requests:
cpu: "0.5"
memory: "500Mi"
- A requests érték az a minimális erőforrás, amit a konténer igényel.
- A limits érték az a maximum, amit a konténer fogyaszthat.
Ezeket az értékeket a kapszula leírásánál kell megadni, és a Kubernetes ennek megfelelően ütemezi be a kapszulát a fürt egyik csomópontjára.
ResourceQuota: névtér szintű korlátok
Ha azt szeretnénk, hogy a különböző felhasználók vagy csapatok ne lépjék túl az erőforráskeretüket, használhatunk ResourceQuota objektumokat:
- Korlátozható a CPU, memória, podok, szolgáltatások, tárolók száma stb.
- A
scopeSelector
mezővel például prioritás alapján is szabályozhatjuk a pod futtatását
Ez segít a fürt egészének stabil működésében, és megelőzi, hogy valaki túl sok erőforrást foglaljon le véletlenül vagy szándékosan.
Mit kezdjünk régi, monolitikus alkalmazásokkal?
Sok szervezetnél felmerül a kérdés: hogyan helyezzük át a régi (monolitikus) alkalmazásokat Kubernetes környezetbe?
Két megközelítés van:
- Konténerizálás, ahogy van – az alkalmazás teljes egészében bekerül egy kapszulába, minimális módosítással. Gyorsabb és olcsóbb megoldás, de korlátozott rugalmasságot ad.
- Újratervezés mikroszolgáltatásként – az alkalmazás komponenseit különálló kapszulákba és szolgáltatásokba bontjuk, hogy teljes mértékben kihasználjuk a Kubernetes előnyeit. Idő- és erőforrás-igényesebb, de jövőállóbb.
Egy egyszerű hasonlat:
- A monolitikus alkalmazás olyan, mint egy városi busz: mindent egyszerre visz, de nem túl rugalmas.
- A mikroszolgáltatás-alapú rendszer olyan, mint egy robogóflotta (pl.: Lime): kicsi, gyors, önállóan mozog, de jól kell koordinálni.
Összefoglalás
A Kubernetes kapszulái olyan, mint a konténerek futtatásának biztonságos és jól szabályozható “csomagolása”. Az init konténerek lehetőséget adnak a folyamatok sorrendjének kézben tartására, a sidecar konténerek pedig kiterjesztik az alkalmazás funkcionalitását. A precíz erőforráskezelés (limits, quota) elengedhetetlen a fürt stabil működéséhez.
Végezetül: ha régi alkalmazást szeretnél Kubernetes-be hozni, gondold át, mit nyersz a mikroszolgáltatás-alapú újratervezéssel, és hol elég a meglévő alkalmazás konténerizálása.
Ha elakadsz, akkor keress engem és segítek.