fbpx
Kubernetes a gyakorlatban: a Deploymentek ShiwaForce Admin 2018. november 20

Kubernetes a gyakorlatban: a Deploymentek

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:

apiVersion: extensions/v1beta1

kind: Deployment                                        # 1

metadata:

name: sa-frontend

spec:

replicas: 2                                            # 2

minReadySeconds: 15

strategy:

  type: RollingUpdate                                  # 3

  rollingUpdate:

    maxUnavailable: 1                                  # 4

    maxSurge: 1                                        # 5

template:                                              # 6

  metadata:

    labels:

      app: sa-frontend                                 # 7

  spec:

    containers:

      - image: rinormaloku/sentiment-analysis-frontend

        imagePullPolicy: Always                        # 8

        name: sa-frontend

        ports:

          - containerPort: 80

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:

kubectl apply -f sa-frontend-deployment.yaml

deployment "sa-frontend" created

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

kubectl get pods

NAME                           READY STATUS RESTARTS AGE

sa-frontend                    1/1 Running 0 2d

sa-frontend-5d5987746c-ml6m4   1/1 Running 0 1m

sa-frontend-5d5987746c-mzsgg   1/1 Running 0 1m

sa-frontend2                   1/1 Running 0 2d

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:

kubectl apply -f deploy-frontend-green-pods.yaml --record

deployment "sa-frontend" configured

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

kubectl rollout status deployment sa-frontend

Waiting for rollout to finish: 1 old replicas are pending termination...

Waiting for rollout to finish: 1 old replicas are pending termination...

Waiting for rollout to finish: 1 old replicas are pending termination...

Waiting for rollout to finish: 1 old replicas are pending termination...

Waiting for rollout to finish: 1 old replicas are pending termination...

Waiting for rollout to finish: 1 of 2 updated replicas are available...

deployment "sa-frontend" successfully rolled out

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:

minikube service sa-frontend-lb

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:

kubectl rollout history deployment sa-frontend

deployments "sa-frontend"

REVISION  CHANGE-CAUSE

1         <none>    

2         kubectl.exe apply --filename=sa-frontend-deployment-green.yaml --record=true

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:

kubectl rollout undo deployment sa-frontend --to-revision=1

deployment "sa-frontend" rolled back

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:

kubectl apply -f sa-logic-deployment.yaml --record

deployment "sa-logic" created

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:

kubectl apply -f service-sa-logic.yaml

service "sa-logic" created

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:

- image: rinormaloku/sentiment-analysis-web-app

imagePullPolicy: Always

name: sa-web-app

env:

  - name: SA_LOGIC_API_URL

    value: "http://sa-logic"

ports:

  - containerPort: 8080

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:

kubectl apply -f sa-web-app-deployment.yaml --record

deployment "sa-web-app" created

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:

kubectl apply -f service-sa-web-app-lb.yaml

service "sa-web-app-lb" created

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:
minikube service list

|-------------|----------------------|-----------------------------|

|  NAMESPACE  | NAME         | URL       |

|-------------|----------------------|-----------------------------|

| default     | kubernetes         | No node port       |

| default     | sa-frontend-lb       | http://192.168.99.100:30708 |

| default     | sa-logic         | No node port       |

| default     | sa-web-app-lb        | http://192.168.99.100:31691 |

| kube-system | kube-dns             | No node port |

| kube-system | kubernetes-dashboard | http://192.168.99.100:30000 |

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

      fetch('http://192.168.99.100:31691/sentiment', { /* shortened for brevity */})

          .then(response => response.json())

          .then(data => this.setState(data));

  }
  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:
docker build -f Dockerfile -t $DOCKER_USER_ID/sentiment-analysis-frontend:minikube.
  1. Töltsük fel az újonnan elkészült image-et a Docker hub-ra:
docker push $DOCKER_USER_ID/sentiment-analysis-frontend:minikube
  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:
kubectl apply -f sa-frontend-deployment.yaml

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

minikube service sa-frontend-lb

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

Kubernetes a gyakorlatban – szolgáltatások (Services)

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
    • Service-ek
    • Deployment-ek
    • Leállás nélküli kitelepítések
    • Skálázható alkalmazásokat készítettünk
    • És mindeközben átmigráltunk egy microservice-ekre épülő alkalmazást a Kubernetes platform-ra.

Cikksorozatunkban szilárd alapokkal láttunk el, így az itt megtanultakat bármely valós projektedben is hasznosítani tudod. Mindemellett további tudást is tehetsz emellé.