Kubernetes a gyakorlatban: a Deploymentek

A Kubernetes hasznos a csapatnak, hasznos a projektnek, egyszerűsíti a telepítést, a skálázhatóságot, a hibatűrést és lehetővé teszi, hogy bármely alacsony szintű infrastruktúrán ugyanazt futtassuk.

Kubernetes cikksorozatunkat Rinor Maloku (http://rinormaloku.com) “Learn Kubernetes in Under 3 Hours: A Detailed Guide to Orchestrating Containers” posztjának fordítására alapozzuk, a szerző engedélyével. Az eredeti angol nyelvű poszt itt olvasható.

A Kubernetes-be implementált “Deployment” funkció abban segít minket, hogy szembenézzünk az alkalmazásokat érintő egyetlen állandó ténnyel, azzal, hogy az alkalmazások mindig változnak. Voltaképpen azok az alkalmazások, amelyek nem változnak folyamatosan gyakorlatilag halottnak tekinthetők. Az élő alkalmazásokhoz mindig készülnek új kódok, amelyeket valaki elkészít, becosmagol és leszállít. A szállítási folyamat bármely lépésében hibázhatunk, ez egy természetes velejáró.

A Deployment-ek abban segítenek minket – a fent leírt problémát megoldva – hogy automatizálják az erőforrások egyik verzióból a másikba történő léptetését úgy, hogy egy hibás verzió esetén a visszaállás is gyorsan végrehajtható legyen.

Deployment-ek a gyakorlatban

Jelenleg két pod-unk van és egy szolgáltatásunk, amely egy load balancer segítségével elérhetővé teszi a pod-okon futó alkalmazást a felhasználók számára (Lásd a lenti ábrát). Korábban említettük, hogy a pod-ok telepítése külön-külön egyáltalán nem tökéletes, nem ideális. Hiszen külön kell kezelnünk őket minden egyes lépésben (create, update, delete, sőt a monitorozásukat is külön meg kell oldani). Gyors frissítéseket és visszaállításokat tehát nem lehet megoldani ezzel a megoldással. Ez nem elfogadható. Erre ad megoldást a Kubernetes “Deployment” funkciója.

Mielőtt továbbmennénk, álljunk meg egy pillanatra, és fejtsük ki, pontosan mik is az elvárásaink a platformmal szemben. Az elvárásaink leírása abban segít minket, hogy ez alapján elkészíthetjük a Deployment definícióját. Nézzük csak, mit is akarunk pontosan:

  1. 2 pod-ot akarunk futtatni, amelyek a rinormaloku/sentiment-analysis-frontend alkalmazást futtatják,
  2. Leállás nélküli csomag telepítést szeretnénk,
  3. A pod-okat az “app: sa-frontend” címkével szeretnénk ellátni, hogy a megfelelő szolgáltatás számára felfedezhető legyen.

A következő részben a fenti leírás alapján elkészítjük a Deployment definíciót.

A Deployment definíció

Az alábbi YAML file-lal teljes mértékben lefedjük a fenti igényeinket:

Nézzük soronként:

  1. Kind: a leírás fajtája (esetünkben Deployment)
  2. Replicas: a pod-ok darabszáma: kettővel indulunk.
  3. Type: a stratégiát határozza meg, amelyet alkalmazni szeretnénk a verzióváltás során, esetünkben ez a “RollingUpdate”, amely során nincs leállási idő.
  4. MaxUnavailable: A “RollingUpdate” során használatos érték, amely azt határozza meg, hogy a verzióváltás során hány pod-ot kapcsolhatunk le. Esetünkben két pod-dal futunk, így a váltásnál csak egyet engedhetünk lekapcsolni, hogy a maradék másik még ki tudja szolgálni a verzióváltás alatt érkező kéréseket.
  5. MaxSurge: szintén a “RollingUpdate” során használatos érték, amely azt határozza meg, hogy a verzióváltás során hány újabb pod-ot adhatunk a deployment-hez. Esetünkben a váltás során egy újabb pod-ot adunk a service-hez.
  6. Template: az új pod(ok) létrehozásához szükséges alap sablon, amelyből az új pod létrejön.
  7. app: sa-frontend: a pod template címkéje
  8. ImagePullPolicy: amikor “Always”-re van állítva, az azt jelenti, hogy minden egyes deployment-kor újra letölti a container image-eket.

Őszintén szólva, a fenti tömény szöveg engem is összezavart, inkább nézzük a továbbiakat:

Mint mindig, ellenőrizzük, hogy minden rendben fut-e:

Látható, hogy 4 futó pod-unk van, melyekből kettőt a Deployment hozott létre, a másik kettőt mi hiztuk létre korábban manuálisan. Ez utóbbiakat törölhetjük a kubectl delete pod <pod-name> paranccsal.

Feladat: töröljük ki a deployment által létrehozott pod egyikét is, és nézzük meg, mi történik.

Magyarázat: Egy pod kitörlésével a deployment érzékelte, hogy eltérés van a megkívánt és a jelenlegi állapot között, így elindított még egy pod-ot.

Vagyis a megkívánt állapot megtartása mellett milyen egyéb előnyei vannak a Deployment-eknek? Kezdjük az előnyök felsorolásával.

1-es számú előny: leállásmentes csomagkirakás

Termék manager-ünk azzal a kéréssel érkezett hozzánk, hogy az ügyfél zöld színű gombot szeretne látni a felületen. A fejlesztők elkészültek a kóddal és leszállították az egyetlen dolgot, amir szükségünk van: az új container image-et: rinormaloku/sentiment-analysis-frontend:green

Most mi következünk, a DevOps-osok, mégpedig egy leállásmentes csomagkiadást kell végrehajtanunk. Vajon a korábban kiépített infratruktúránk lehetővé teszi ezt? Nézzük!

Szerkesszük meg a deploy-frontend-pods.yaml file-t, amelyben módosítsuk a container image nevét az újra. Mentsük el a változást, majd futtassuk az alábbi parancsot:

A rollout státuszát pedig az alábbi parancs alapján ellenőrizhetjük:

A fentiek alapján a csomagkiadás megtörtént. Az egyes replikák egyenként cserélődtek le. Ez azt is jelenti, hogy az alkalmazásunk a verzióváltás során mindvégig elérhető maradt. Mielőtt tovább mennénk, ellenőrizzük, hogy a frissített alkalmazás valóban elérhető-e a nagyközönség számára.

A csomagkiadás ellenőrzése

Lássuk tehát a friss verziót a böngészőnkben is. Ehhez a már korábban kiadott minikube parancsot kell csak újra kiadnunk:

Egy böngészőablakban az alábbiakat láthatjuk:

Mi is van a “RollingUpdate” hátterében?

Miután az új deployment-et elindítottuk a Kubernetes összehasonlítja az új állapotot a régivel. Esetünkben az új állapot két pod-ot kér az új image-ekből (a zöld gombbal). Ez eltér a jelenleg futó állapottól, így a “RollingUpdate” folyamat beindul.

A “RollingUpdate” az általunk megadott keretek között fut, vagyis figyelembe veszi a “maxUnavailable: 1” és a “maxSurge: 1” értékeket. Ez azt jelenti, hogy a deployment 1 db pod-ot lőhet ki és 1db újat indíthat el. Ez a folyamat addig folytatódik, ameddig az összes pod-on le nem váltódik a verzió.

Folytassuk a második előnnyel.

Megjegyzés: a következő rész párbeszédes formában írodott.

2-es számú előny: visszaállás egy korábbi változatra

A Termékmanager beront az irodába, láthatóan krízis állapotban van:

  • Az alkalmazásban felfedeztek egy kritikus hibát, az ÉLES-en!! Azonnal álljunk vissza a korábbi verzióra! – kiáltja a manager.

Látja benned a higgadt nyugodtságot, még a szemed se rebben. A terminálodhoz fordulsz, és:

Vetsz egy rövid pillantást a korábban kiadott csomagokra. “A legutóbbi verzió hibás, de az azt megelőző még jól működött?” kérdezed a termékmanagertől.

“Igen, egyáltalán figyelsz te rám?!” – értetlenkedik.

Ügyet sem vetsz a hangvételre, hiszen tudod mit kell tenned, egyerűen kiadod, hogy:

Frissíted az oldalt a böngészőben, és íme, visszaálltunk!

A manager álla leesik.

Megmentetted a napot!

VÉGE

Nos, igen….. Elég unalmas novella volt. A Kubernetes előtt ez a jelenet sokkal jobb lett volna, még több dráma, magasabb feszültség. Régi szép idők!

A fenti részben a legtöbb parancs egyértelmű, az egyetlen rész, ami gondolkodásra és kutatása adhat okot az a “CHANGE-CAUSE” résszel kapcsolatos: az első revízióban ennek értéek <none>, míg a második reíziónál ez kubectl.exe apply –filename=sa-frontend-deployment-green.yaml –record=true”.

Ha arra tippeltél, hogy ez a korábban alkalmazott –record kapcsoló miatt van, akkor jól tippeltél!

És akkor eljött az idő, hogy a korábban megtanult elméleti részeket alapján befejezzük a teljes architektúra Kubernetesítését.

A Kubernetes és minden más a gyakorlatban

A legfontosabb erőforrásokat már megtanultuk létrehozni, azonban vannak még komponensek, amelyeket el kell készítenünk, ezeket az alábbi ábrán szürkével jelöltük.

Kezdjük alulról: az sa-logic deployment-tel.

Az sa-logic komponens kitelepítése

A terminál ablakodban navigálj a “resource-manifests” mappába és ott add ki a következő parancsot:

A fenti deployment 3 pod-ot hozott létre. (a Python alkalmazásunk fut ezekben a konténerekben). Ezeket az “app:sa-logic” címkével láttuk el. A címkék teszik lehetővé, hogy egy SA-logic Service-be tudjuk őket célzottan szervezni. Nyissuk meg az sa-logic-deployment.yaml file-t és nézzük át a tartalmát.

A koncepció ugyanaz mint korábban, éppen ezért nem is töltünk itt több időt, haladunk tovább a következő Sevice-ünkkel.

Az SA-logic szolgáltatás

Először nézzük meg, miért is van egyáltalán szükség erre a service-re. Java alkalmazásunk (amely az sa-webapp deployment pod-okon fut) függ az elemzést végrehajtó Python alkalmazástól. Most azonban – szemben azzal az állapottal, amikor mindent egy példányban lokálisan futtattunk – már nem csak egyetlen Python alkalmazásunk van, amely egy adott port-on figyel, hanem kettő, vagy akár több is lehet.

Ezért van szükségünk egy Service-re, amely egy belépési pontot ad pod-ok egy halmazához. Ez azt jelenti, hogy az sa-logic nevű service-t használhatjuk az sa-logic pod-ok eléréséhez.

Tegyünk is így:

Frissített alkalmazás állapot: 2 pod-unk van (amelyek a Python alkalmazást tartalmazzák) és van egy sa-logic service-ünk, amely belépési pontként funkcionál.

Most az sa-webapp pod-okat kell kitelepítenünk, melyet egy deployment erőforrással érünk el.

Az SA-WebApp kitelepítése

Már rutinosan kezeljük a deployment leírásokat, azonban ez az egy tartalmaz még új elemeket. Nyissuk meg az sa-web-app-deployment.yaml file-t és nézzük meg az alábbi részt:

Az első dolog, ami érdekelhet minket, az a kiemelt “env” rész. Azt értjük, hogy ez az “SA_LOGIC_API_URL” változót deklarálja a “http://sa-logic” értékkel. De miért is itt tesszük ezt meg?

Ezennel mutatkozzon be a kube-dns.

A KUBE-DNS

A Kubernetes-en belül létezik egy speciális pod, a kube-dns. Alapesetben minden pod ezt a pod-ot használja DNS szerverként. Fontos funkciója, hogy minden egyes service-nek készít és fenntart egy DNS bejegyzést.

Ez azt jelenti, hogy amikor az sa-logic service-t elkészítettük, az kapott egy IP címet. A service neve – az IP címmel együtt – egy bejegyzésbe került a kube-dns adatbázisába. Ezáltal minden egyes pod le tudja fordítani az sa-logic nevet egy IP címre.

Rendben, tehát akkor folytassuk:

Az SA-WebApp kitelepítése (folytatás)

Hajtsuk végre a következő parancsot:

Kész. Ezután már csak az SA-WebApp pod-okat kell kiajánlanunk egy load balancer mögött. Ezzel meg tudjuk teremteni a kapcsolatot a react alkalmazásunk és a háttérrendszerek között.

Az SA-WebApp service

Nézzünk bele a service-sa-web-app-lb.yaml file-ba, amint látjuk minden ismerős. Így adjuk is ki a következő parancsot:

Az architektúránk ezennel elkészült. Van azonban még egy eltérésünk. Amikor az SA-Frontend pod-okat telepítettük a konténer image-ek az SA-WebApp-ot a  http://localhost:8080/sentiment címen érték el. Most viszont ezt a beállítást frissítenünk kell, hogy az SA-WebApp LoadBalancer service végpontjára mutasson.

Ennek az eltérésnek a kijavításához hozzá kell nyúlnunk a rendszer majdnem minden komponenséhez még egyszer, de ez nem is baj, legalább ismételünk.

Kezdjünk hozzá.

  1. Szerezzük be az SA-WebApp Loadbalancer IP címét az alábbi paranccsal:

  1. Használjuk fel az így beszerzett IP címet az sa-frontend/src/App.js file-ban az alábbiak szerint:

  1. Építsük fel újra a statikus file-jainkat egy “npm run build” paranccsal. (Ehhez az sa-frontend mappába kell navigálnunk).
  2. Építsük fel újra a konténer image-ünket:

  1. Töltsük fel az újonnan elkészült image-et a Docker hub-ra:

  1. Szerkesszük meg az sa-frontend-deployment.yaml file-t, hogy az új image-t használja fel.
  2. Hajtsuk végre az alábbi parancsot:

Végül frissítsük a böngészőnket, vagy ha bezártuk korábban akkor adjuk ki az alábbi parancsot:

Próbáljuk is ki, adjunk meg egy mondatot.

 

Kubernetes cikksorozatunk összefoglalója

Előző részek:

Kubernetes 3 óra alatt: részletes útmutató – 1. rész: Kiindulás a microservices alkalmazásokból

Kubernetes 3 óra alatt – 2. rész: konténerekbe szervezés

Kubernetes 3 óra alatt: részletes útmutató – 3. Rész: Kubernetes

A Kubernetes hasznos a csapatnak, hasznos a projektnek, egyszerűsíti a telepítést, a skálázhatóságot, a hibatűrést és lehetővé teszi, hogy bármely alacsony szintű infrastruktúrán ugyanazt futtassuk. Vagyis tudod mit? Inkább Supernetes-nek kéne hívni!

Az alábbi területeket fedtük le:

  • Felépítettünk, becsomagoltunk, és futtattunk ReactJS, Java és Python alkalmazásokat
  • Megismerkedtünk a Docker konténerekkel: hogyan definiálhatunk és építhetünk ilyeneket Dockerfile-ok segítségével
  • Konténer Registry-ket is használtunk: a Docker Hub-ot használtuk a példánkban
  • A Kubernetes legfontosabb részeit lefedtük:
    • Pod-ok
    • Deployment-ek
    • Leállás nélküli kitelepítések
    • Skálázható alkalmazások

A cikksorozatunkban megtanultakat bármely valós projektedben hasznosítani tudod, és természetesen további tudást is tehetsz mellé.