Kubernetes-es cikksorozatunkat Rinor Maloku “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ó.
Egy komponens egy konténerbe
A Kubernetes konténereket kezel. Értelemszerűen a korábban futtatott alkalmazás komponenseinket konténerekbe kell szervezni ahhoz, hogy a Kubernetes-szel vezérelni tudjuk őket.
De mik is azok a konténerek? A legjobb, ha a Docker dokumentációhoz fordulunk:
“Egy konténer egy pillekönnyű, egyedülálló, futtatható szoftver alkotóelem, amely minden a futtatáshoz szükséges elemet tarttalmaz: kódot, futtatókörnyezetet, rendszer komponenseket, library-ket és konfigrációs beállításokat. A konténer-technológia alkalmazható Linux-ra és Windows-ra készített alkalmazásoknál, és a konténerbe zárt szoftver környezettől függetlenül ugyanúgy fog működni bárhol is futtatjuk őket.”
Vagyis a konténerizált szoftver ugyanúgy fut a lokális gépünkön, mint az éles szerveren – különbségek nélkül.
Készítsük el a React-os alkalmazásunk konténer image-ét
A Docker technológia legelemibb alkotórésze a Dockerfile. A Dockerfile-ban írjuk le, hogy a konténer mit tartalmazzon. Ehhez minden esetben egy alap image-ből indulunk ki, majd parancsok sorozatával erre az alap image-re (base image) építjük a saját alkalmazásunkat.
Mielőtt belevágnánk a Dockerfile írásába, röviden tekintsük át, hogy milyen lépések voltak szükságesek a React-os komponensünk életrekeltéséhez:
- Építsük fel a statikus állományokat (npm run build)
- Indítsuk el az Nginx szervert
- Másoljuk az elkészült statikus állományokat az Nginx szerver kiszolgáló nginx/html mappájába
Gyakorlatilag ezt a lépéssorozatot kell leírnunk a Dockerfile-ban.
Hozzuk létre az sa-frontend komponens Dockerfile-ját
Mivel az Nginx mögött álló csapat már elkészített és elérhetővé tett egy alap image-et, így a feladatunk gyakorlatilag két lépésre redukálódik le:
- Induljunk ki egy alap Nginx image-ből
- Másoljuk át az sa-frontend/build mappájának tartalmát a konténeren belülre az nginx/html mappájába
A Dockerfile tehát így néz ki:
FROM nginx COPY build /usr/share/nginx/html
Ennyire egyszerű.
Felmerülhet a kérdés, hogy honnan tudtam, hova kell pontosan másolni a statikus file-okat a konténeren belül. Nos, ezt a Docker Hub-on található Nginx-es dokumentáció fedi fel.
A konténer elkészítése és a központi tárba küldése
Mielőtt elkészítjük az első image-ünket fontos, hogy legyen egy központi hely, ahol tárolhatjuk és bárhonnan elérhetjük. Ehhez egy Docker Registry-re van szükségünk. Szerencsére a Docker Hub nyújt ilyen szolgáltatást.
Telepítsük fel lokálisan a Docker-t, majd regisztráljunk a Docker Hub-on. Lépjünk be a Docker Hub-ba. Ezt a parancssorból így tehetjük meg:
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
Miután ezzel megvagyunk navigáljunk az sa-frontend mappába. Adjuk ki a következő parancsot (lecserélve a $DOCKER_USER_ID-t a saját Docker Hub felhasználó névvel):
docker build -f Dockerfile -t $DOCKER_USER_ID/sentiment-analysis-frontend .
Valójában a -f Dockerfile részt el is hagyhatjuk, hiszen a megfelelő mappában állunk.
Végül küldjük fel az elkészült image-et a központi távoli registry-be:
docker push $DOCKER_USER_ID/sentiment-analysis-frontend
Ellenőrizd le, hogy az image valóban felkerült a Docker Hub-ba.
Futtassuk az elkészült konténer image-et
Az elkészült image-et (melyre a $DOCKER_USER_ID/sentiment-analysis-frontend névvel hivatkozhatunk) innentől kezdve bárki letöltheti és futtathatja:
docker pull $DOCKER_USER_ID/sentiment-analysis-frontend docker run -d -p 80:80 $DOCKER_USER_ID/sentiment-analysis-frontend
A Docker konténerünk fut!
Mielőtt továbblépnénk kicsit nézzük meg, mi az a 80:80. Az első 80-as a hoszt 80-as port-ját jelenti. A második port azt a port-ot jelenti amelyen a konténer az oda irányított hívásokat fogadja.
Az összerendelés tehát <hostPort> a <containerPort>-hez. Maga az alkalmazás – mivel lokáisan futtatod elérhető a http://localhost:80 címen.
Ha bármi oknál fogva a localhost névre történő hivatkozás nem működik, az alábbi paranccsal megnézheted a Docker hosztod IP-jét és erre is hivatkozhatsz. A parancs:
docker-machine ip
A Dockerignore file és használata
Megfigyelhettük, hogy maga a build-elés folyamata NAGYON lassú volt. TÚL lassú. A magyarázat a következő: mi a mappa teljes tartalmát átadtuk a build daemon-nak, így az szépen beletette a konténerbe, amit csak az sa-frontend mappában talált:
sa-frontend: | .dockerignore | Dockerfile | package.json | README.md +---build +---node_modules +---public ---src
Holott nekünk egyedül csak a /build mappa tartalmára volt szükségünk. Mit tehetünk?
A szoftverfejlesztés egyéb bugyraiból talán már ismert .gitignore mintájára a Docker is hasonló megoldást nyújt: a .dockerignore file használatát javasolja. Itt felsorolhatunk minden olyan file-t és mappát, amit ki szeretnénk hagyni a build végeredményéből. Esetünkben ezek:
node_modules src public
Az egyetlen szabály, hogy a .dockerignore file-nak ugyanabban a mappában kell lennie, mint ahol a Dockerfile található.
Ezek után a build folyamat pár másodpercre rövidül le.
Folytassuk a konténeresítést a Java alkalmazással.
Tegyük konténerbe a Java alkalmazást
Mivel szinte már mindent megtanultál az előző fejezetben a konténer készítésről, így megpihenhetsz, ez a fejezet nagyon rövid lesz.
Nyisd ki az sa-webapp mappában lévő Dockerfile-t, és ott csak két sort találsz, ami még nem lehet ismerős:
ENV SA_LOGIC_API_URL http://localhost:5000 … EXPOSE 8080
Az ENV kulcsszó egy környezeti változót definiál a Docker konténeren belül. Ez teszi lehetővé, hogy parancssori futtatáskor átadjunk egy URL-t a futtatni kívánt konténernek.
E mellett a másik sor az EXPOSE-zal egyszerűen a 8080-as port-ot nyitja meg a konténerben.
A folyamat innentől kezdve a korábbi build és push folyamtot követi.
Tegyük konténerbe a Python alkalmazást
Az sa-logic mappába lépve a Dockerfile-ban nincs újdonság. Kövessük a fenti lépéseket, hogy a végén Docker Mester-nek hívhassuk magunkat.
A mappában található README.md segítséget nyújt esetleges elakadás esetén.
Teszteljük a teljes konténerizált alkalmazást
Te mernéd élesíteni a fentieket tesztelés nélkül? Hát én sem. Fussunk velük egy kört.
- Futtassuk az sa-logic konténert és konfiguráljuk úgy, hogy az 5050-es porton figyeljen:
docker run -d -p 5050:5000 $DOCKER_USER_ID/sentiment-analysis-logic
- Futtassuk az sa-webapp konténert és konfiguráljuk úgy, hogy a 8080-as porton figyeljen. E mellett adjuk meg az sa-logic API URL-jét is:
docker run -d -p 8080:8080 -e SA_LOGIC_API_URL='http://<container_ip or docker machine ip>:5000' $DOCKER_USER_ID/sentiment-analysis-web-app
- Végül futtassuk az sa-frontend konténert:
docker run -d -p 80:80 $DOCKER_USER_ID/sentiment-analysis-frontend
Kész is vagyunk. Nyissuk meg a böngészőnkben a localhost:80-at.
A fenti ábra mutatja, hol is tartunk, hogyan néz ki a konténerizált alkalmazásunk.
Mit is tanultunk meg ebben a részben? Miért is van szükség a Kubernetes-re?
Ebben a részben megtanultuk a Dockerfile-ok használatát és hogy hogyan tudjuk a készítendő docker image-ek méretét csökkenteni. Valamint azt, hogyan lehet az elkészült image-eket egy központi felhő alapú tárházban tárolni. Végül, hogy hogyan is lehet elindítani egy konténerekbe szervezett microservice alapú alkalmazást lokálisan.
Szóval akkor miért is van szükségünk még ezeken felül a Kubernetes-re?
Erre a következő és egyben utolsó részben adunk választ.