Mi az a Kubernetes?
A Kubernetes (röviden: k8s) egy nyílt forráskódú konténer alapú alkalmazáskezelő szoftver, amellyel automatizálható az alkalmazások telepítése, skálázása és menedzselése. Eredetileg a Google mérnökei kezdték el a fejlesztését, jelenleg a Cloud Native Computing Foundation gondozza. Számos konténeres megoldást használó infrastruktúrát támogat, többek között a Dockert is.
Minimum 3 szerverre van szükség a biztonságos üzemeltetéséhez.
Mi az a microk8s?
A Canonical által készített (mint az Ubuntu Linux) MicroK8s az egyik legegyszerűbb és leggyorsabb módja a Kubernetes üzembe helyezésének.
Ha nincs szükségünk a magas rendelkezésre állásra (HA), már egy szerverrel is belevághatunk. Fejlesztői vagy teszt környezetekhez ez elég is. Ha éles rendszert építünk vele, ezt is fel tudjuk skálázni több node-os clusterre.
Vágjunk is bele! Mi a mai menü?
Csinálunk egy egygépes kubernetes szervert, amin két alkalmazást (igazából négy, de erről később) fogunk futtatni. A kedvenc wiki alkalmazásomat a dokuwikit, és a kedvenc monitoring alkalmazásomat a zabbixot. A zabbixot nem kell bemutatnom, több cikket is írtam róla. A dokuwikit pedig azért szeretem, mert faék egyszerű alkalmazás, csak egy php-t beszélő webszerverre van szükség hozzá.
Egy kis segítség: ha a yaml fájlokat a virtuális szerver /vagrant mappájába hozzátok létre, akkor a VM törlése után is megmaradnak. Így később is fel tudjátok használni.
Még egy apróság. Bár a microk8s-t fel lehet telepíteni az asztali operációs rendszerekre is (Linux, Windows, MacOS), én jobban szeretem, ha egy erre dedikált virtuális gépen (VM) gyakorolok. Így nem hagyok szemetet a sajátomon. Ennek a VM-nek a létrehozásában segít a Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.define "microk8s" do |microk8s|
microk8s.vm.network "private_network", ip: "192.168.56.95", :name => 'vboxnet0', :adapter => 2
microk8s.vm.box = "ubuntu/jammy64"
microk8s.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
vb.cpus = 2
end
microk8s.vm.provision "shell", inline: <<-SHELL
apt-get update && apt-get upgrade -y
apt-get install -y snapd curl mc
apt-get dist-upgrade -y
apt-get clean
echo -e "export PATH=$PATH:/snap/bin\nalias ll='ls -l'\nalias kubectl='microk8s kubectl'" >> /home/vagrant/.bashrc
echo -e "export PATH=$PATH:/snap/bin\nalias ll='ls -l'\nalias kubectl='microk8s kubectl'" >> /root/.bashrc
echo "microk8s" > /etc/hostname
echo "192.168.56.95 microk8s" >> /etc/hosts
hostname -F /etc/hostname
snap install microk8s --classic
/snap/bin/microk8s status --wait-ready
/snap/bin/microk8s enable dashboard
/snap/bin/microk8s enable dns
/snap/bin/microk8s enable metrics-server
/snap/bin/microk8s enable hostpath-storage
reboot
SHELL
end
end
Aki olvasta a korábbi vagrantos cikkeimet, annak ismerős lehet a fájl tartalma. Annyi újdonság került bele, ami megkönnyíti a microk8s telepítését, így mire lefut a „vagrant up microk8s
” parancsunk (nálam 5 perc volt), munkára készen áll a microk8s alapú kubernetes szerverünk. Az utolsó parancs újraindítja a gépet, így várjunk még kb 1 percet. Addig olvassatok tovább, van mit mesélnem 🙂
Szóval, lesz egy naprakész Ubuntu 22.04 alapú VM-ünk 2 GB memóriával, 2 CPU-val. A külső IP címe 192.168.56.95 lesz. Az alap microk8s ki lett bővítve pár modullal: dns, dashboard, metrics-server és hostpath-storage.
A dns-re ne úgy tekintsetek, mint egy szokványos dns-re, ez a konténerek házon belüli megtalálásában fog segíteni nekünk. A dashboard egy népszerű webes felület a kuberneteshez. A metrics-server méri a felhasznált erőforrásokat, és szép ábrákat készít a dashboardra. A hostpath-storage pedig arra szolgál, hogy az alkalmazásaink által gyártott adatokat el tudjuk menteni, azok nem fognak elveszni a konténerek (podok) leállása után.
A továbbiakban nem konténerként fogom nevezni az appokat tartalmazó „dobozokat”, hanem hivatalos nevén pod-nak. A Pod-ok a legkisebb telepíthető számítási egységek, amelyeket a Kubernetesben hozhat létre és kezelhet.
Talán már nálatok is kész a microk8s szerver telepítése, lépjetek be a „vagrant ssh microk8s
” parancs kiadásával. A sikeres belépés után a szokásos ubuntus üdvözlő képernyő fogad minket.
Kezdjük egy „sudo -s
” paranccsal.
Mivel a kubernetes szolgáltatásoknak is időre van szüksége az elinduláshoz, adjuk ki a „microk8s status
” parancsot. Amikor ezt látjátok, akkor használatra készen áll a kubernetesünk:
Számunkra az „enabled” blokk alatti modulok a fontosak, ott kell szerepelni az összes, korábban említett modulnak (dns, dashboard, metrics-server és hostpath-storage).
A kubernetes dashboard localhoston már elérhető, de ezen a szerveren ugye nincs grafikus felület, így meg kell oldanunk, hogy az asztali gépünkről is elérjük. Erre több módszer is létezik, a hivatalos weboldal ezt a parancsot javasolja: „microk8s dashboard-proxy
„. Eleinte én is ezt használtam (mert nem ismertem más módszert 🙂 ), de ezzel van egy kis probléma:
- elfoglalja a konzolt
- néha elszáll
A konzol foglalás megoldható, vagy háttérbe teszem, vagy screenbe, vagy indítok egy másik konzolt, ám az elszállásra nincs gyógyszer. Ezért én másik megoldást kerestem. Készítettem egy „service
-t” a dashboard számára, így állandóan elérhető kintről az általam megadott porton.
Hozzunk létre egy fájlt „dashboard-service.yml” néven ezzel a tartalommal:
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard-external
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
spec:
type: NodePort
ports:
- targetPort: 8443
port: 8443
nodePort: 30443
name: http
selector:
k8s-app: kubernetes-dashboard
Nincs más hátra, mint betölteni a kubernetesbe: „kubectl apply -f dashboard-service.yml
„
service/kubernetes-dashboard-external created
Egy fontos megjegyzés: a microk8s szerver direktben nem ismeri a kubectl parancsot, elé kell tenni a microk8s szót is, ám én csináltam erre egy aliast, ami még a Vagrantfile-ban a telepítés közben létrehozza az aliast, így ha kiguglizunk egy kubernetes parancsot, csont nélkül le fog futni ebben a környezetben is. Szintén fontos megemlítenem, hogy yaml fájlokkal fogunk dolgozni, így minden „behúzás” két szóköz, ha valahová többet, vagy kevesebbet rakunk, reklamálni fog a kubectl!
Hogyan érhetjük el a kubernetes dashboardot?
Csak nyissuk meg a kedvenc böngészőnkkel ezt a linket: https://192.168.56.95:30443/
Az IP cím a Vagrantfile-ban volt definiálva, a port pedig a dashboard-service.yml-ben.
Szuper! De mi a jelszó, akarom mondani a token?
Kérdezzük meg ezzel a paranccsal: „kubectl -n kube-system describe secret microk8s-dashboard-token | grep ^token | cut -d ":" -f 2
„.
Kapunk egy jó hosszú, 917 karakterből álló tokent. Ezt másoljuk be az „Enter token” mezőbe, majd enter, vagy katt a „Sign in” gombra.
Ez a képernyő fog fogadni minket:
A Workloads alatti menüpontok üresek, a Service alatt csak egy kubernetes nevű bejegyzés lesz, ezzel nekünk semmi dolgunk. A Config and Storage alatt már két számunkra érdektelen bejegyzést fogunk látni. A Cluster alatt már sokkal több dolgot találunk, mondanom se kell, nem kell vele foglalkoznunk.
És hol van a nemrég létrehozott service? Aki alaposan megnézte a dashboard-service.yml fájlt, észrevehetett benne egy namespace: kube-system sort. Ha a dashboard tetején a default névtér helyett kiválasztjuk a kube-system névteret, és rákattintunk a bal oldali Services almenüre, akkor több másik mellett ott lesz a mi kubernetes-dashboard-external szervizünk is. Bátran kattintsunk rá (vagy ide).
Térjünk vissza a default névtérre. De mi is a a névtér (namespace)?
A Kubernetesben a névterek mechanizmust biztosítanak az erőforráscsoportok egyetlen fürtön belüli elkülönítésére. Az erőforrások nevének egyedinek kell lennie egy névtéren belül, de nem a névtereken belül.
forrás
Elsőre kissé nyakatekertnek tűnik, leegyszerűsítve, ha a yaml fájlokban nem adod meg a névteret, akkor alapból a defaultba fog kerülni. Kis rendszernél ez teljesen megfelelő, pláne ha csak egyedül használod.
Ám ahogy nő a kubernetesben futó alkalmazások száma, netalán a rendszergazdák száma is, érdemes elkülöníteni egymástól a dolgokat. Pl. csinálhatsz prod, uat, teszt névtereket, vagy a komplexebb alkalmazásokhoz saját névteret. A lehetőségek végtelenek. Az egyszerűség kedvéért ma maradjunk a default névtérnél.
Sok a duma, jöhetne az első alkalmazás telepítése!
Hozzunk létre egy „dokuwiki-deployment.yml
” nevű fájlt az alábbi tartalommal:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dokuwiki
namespace: default
labels:
app: dokuwiki
type: frontend
storage: local
spec:
replicas: 1
selector:
matchLabels:
app: dokuwiki
strategy:
type: Recreate
template:
metadata:
labels:
app: dokuwiki
type: frontend
storage: local
spec:
containers:
- name: dokuwiki-pod
image: lscr.io/linuxserver/dokuwiki:latest
envFrom:
- configMapRef:
name: dokuwiki
volumeMounts:
- mountPath: /config
name: dokuwikidata
volumes:
- name: dokuwikidata
persistentVolumeClaim:
claimName: dokuwiki-pvc
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: dokuwiki
namespace: default
labels:
app: dokuwiki
type: frontend
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30180
name: http
selector:
app: dokuwiki
---
apiVersion: v1
kind: ConfigMap
metadata:
name: dokuwiki
namespace: default
labels:
app: dokuwiki
type: frontend
data:
PUID: "1000"
PGID: "1000"
TZ: Europe/Budapest
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: dokuwiki-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data/pvc/dokuwiki"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dokuwiki-pvc
namespace: default
labels:
app: dokuwiki
type: local-storage
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Mondanom se kell, a fájlnevek nincsenek kőbe vésve, a tartalmuk a fontos. Én próbálom úgy elnevezni őket, hogy ránézésre is lehessen tudni, mit tartalmaznak.
Gyakorlatilag öt különálló részt tartalmaz, azaz akár öt fájlba is tehetnénk őket. Ám így egyszerűbb, és különben is egymáshoz tartoznak. Ha több fájlt szeretnénk egybe tenni, válasszuk el őket három kötőjellel (---
).
Nincs más hátra, mint betölteni a kubernetesbe: „kubectl apply -f dokuwiki-deployment.yml
„:
Máris élettel teli lett a dashboardunk:
Ha rögtön megnyitottátok a dashboardot, akkor más színeket is láthattatok. Sárga a függőben lévő feladat, piros a hibára futott. Mondanom se kell, de ami zöld, azzal minden rendben van.
Az első működő weboldalunkat itt érjük el: http://192.168.56.95:30180/. Első alkalommal futtassuk le a varázslót: http://192.168.56.95:30180/install.php. Ám most nem a dokuwiki a téma, később írok róla egy külön cikket. A dokuwiki nyitólapja:
Be kell szúrnom egy újabb magyarázatot.
Nagyon előre szaladtam, és nem magyaráztam el a különbséget a Pod -> Replication Controller -> Replica Set -> Deployment között. Szándékosan nyilaztam őket a legegyszerűbbtől a legbonyolultabbig.
Mint már említettem, a kubernetesben a pod a legkisebb elem, tipikusan egy konténert tartalmaz. Ha ezzel az erőforrással hozunk létre egy konténert (nem ajánlott!), akkor működni fog egészen addig, amíg össze nem omlik, vagy ki nem nyírja egy szórakozott kollégánk 🙂 Ezzel ugyanis vége a történetnek, a kubernetes le se szarja. Ez akkor is előfordulhat, amikor a szervert újraindítjuk frissítés miatt, nincs mechanizmus, ami átmozgatná másik vasra.
A következő a Replication Controller. Itt bevezették a skálázás fogalmát, ami azt jelenti, hogy az előre beállított számú podot fogja futtatni a teljes clusterben. Akkor is, ha az az érték „1”, és pont azt a szervert indítjuk újra, ahol épp futott. Magyarul, a pod erőforrás hibáit ezzel kiküszöbölték.
Mára elavulttá vált, helyette bevezették a Replica Set nevű erőforrást. Ám önmagában ezt sem érdemes használnunk, máris eljutottunk a Deployment-hez.
Ez rengeteg lehetőséggel segíti az appjaink üzemeltetését, én egy dolgot emelnék ki: ha változtatunk egy paramétert a yaml fájlban, és újra futtatjuk a „kubectl apply -f valami.yml
” parancsot, a kubernetes létrehoz egy új replica set-et, kinyírja a korábbi podo(ka)t, majd elindít egy vagy több új podot a megváltozott paraméterekkel. Ilyen változás lehet a konténer image verziószámának változása is.
Mire jó ez a gyakorlatban? Ha úgy látjuk, hogy az új paraméterekkel nem stimmel valami, akkor egy kattintással (vagy egy paranccsal) vissza tudunk állni az utolsó stabil állapotra.
Nézzünk erre egy példát, kattintunk a dashboard Replica Set menüpontjára. Ezt fogjuk látni:
Csináljunk egy apró módosítást, módosítsuk a dokuwiki-deployment.yml fájlban az image értékét lscr.io/linuxserver/dokuwiki:latest-ról nginx:latest-re. Majd ismét töltsük be a kubernetesbe „kubectl apply -f dokuwiki-deployment.yml
„:
Láthatjuk, hogy csak egy erőforrás változott, a deployment.apps/dokuwiki configured lett, azaz újra konfigurálta. Ha újra ránézünk a dokuwikire, azt fogjuk látni, hogy az nginx webszerver üdvözlő oldala jön be helyette:
Természetesen a valóságban nem szoktuk az „A” appot „B”-re cserélni, most csak demonstrálni szerettem volna a replicationset működését. Képzeljük el azt, hogy kaptunk egy új verziót a fejlesztőktől, és most szeretnénk az éles szerveren frissíteni.
Nézzünk meg újra a dashboard Replica Set menüpontját. Ezt fogjuk látni:
Két dokuwiki látszik a korábbi egy helyett. Az alsó egy órája jött létre, annál még a dokuwiki images látszik, a felsőnél már az nginx images. Ám a legfontosabb különbség a Pods oszlop alatt látszik. A jelenleg futó verziónál (nginx) 1/1 látható, míg a korábbi dokuwikinél 0/0.
Mivel egy példányt definiáltunk a yaml fájlunkban (replicas: 1), és sikeres volt az új pod betöltése, ezért így jön ki a matek, egyszerre nem futhat se több, se kevesebb podunk, mint amit előre megadtunk (1).
Tételezzük fel, hogy a fejlesztő elrontott valamit, és a weboldal nem úgy viselkedik, ahogy elvárjuk tőle. Nincs más választásunk, mint visszaállni a régebbi, de legalább működő változatra (természetesen a valóságban ennek ki kellene derülni a tesztelési fázisban, de ugye az elmélet meg a gyakorlat ritkán találkozik egymással 🙂 ).
A visszaállást megtehetjük parancssorból. Előbb listázzuk ki az elérhető replicaseteket: „kubectl get rs
” (hasonlót láthattunk a webes felületen is):
Most álljunk vissza a korábbi változatra: „kubectl rollout undo deployment/dokuwiki
„:
Újra csekkoljuk: „kubectl get rs
„:
Ugyanez így néz ki a webes felületen:
Volna egy másik módszer is, talán egyszerűbb is, és amúgy sem árt a yaml fájlt aktualizálni, írjuk vissza a jó imaget (esetünkben az eredeti lscr.io/linuxserver/dokuwiki:latest-et), majd csak töltsük be (kubectl apply -f dokuwiki-deployment.yml)-t.
Erről ennyit. Tudunk telepíteni/módosítani, hogyan lehet törölni?
Mi sem egyszerűbb ennél, így törölhetjük a dokuwikit (és az összes hozzá tartozó erőforrást): „kubectl delete -f dokuwiki-deployment.yml
„:
A szokásos kimenet, csak minden erőforrás törlődött (deleted). Ha a dashboardon is ellenőrzöd, a kezdeti üres állapotot fogod látni.
Fontos tudni, hogy törléskor megmaradnak a pod által létrehozott fájlok. Természetesen ez is beállítás kérdése, de miért akarnánk, hogy törlődjenek? Így, ha újra betöltjük a dokuwikit, minden adat és beállítás a helyén marad. Tegyük is meg, tudok még mesélni a többi erőforrásról „kubectl apply -f dokuwiki-deployment.yml
„.
Ha a dashboard tetején található keresőbe beírjuk a dokuwiki szót, majd nyomunk egy entert, hét erőforrást fogunk látni: Deployments, Pods, Replica Sets, Services, Config Maps, Persistent Volumes, Persistent Volumes (nem elírás, duplán látszik). Hogy lehet 7 erőforrása a dokuwikinek, amikor a yaml fájlban csak ötöt definiáltunk?
Emlékeztek még arra, amikor elmeséltem a Pod -> Replication Controller -> Replica Set -> Deployment közötti különbségeket?
Nos, mi a Deploymentet használjuk, ami definiál egy Replica Set-et, ami létrehoz egy Pod-ot. Így már kijön a matek 😀
Ezeket kiveséztük, beszéltem a service-ről is, ugye ennek köszönhetjük, hogy mi is hozzáférünk a weboldalhoz, maradt három erőforrás: Config Maps, Persistent Volumes (2*).
Mire jó a Config Maps?
Változókat definiálhatunk, és hozzárendelhetjük egy vagy több podhoz is. A dokuwikinek nincs sok változója, íme:
Mire jó a Persistent Volumes (PV, PVC)?
A Persistent Volumes cluster szintű erőforrás, a mi esetünkben azt a mappát állítjuk be vele, ami a dokuwiki fájlokat fogja tárolni (/data/pvc/dokuwiki). Látszik, hogy mekkora területet használhat fel (5 GiB). És a legfontosabb paraméter, a Reclaim policy. Ennek az értéke Retain, ez azt jelenti, hogy a PV törlésekor megtartja a fájlokat:
Középtájon látszik is, hogy mihez van kötve, a dokuwiki-pvc-hez:
Itt is látszik, hogy 5 GiB-ot használhat fel a pod. Ennek az a lényege, hogy egy PV-hez több PVC is tartozhat, és a PVC-k által felhasználható terület nem lehet több, mint a PV által megadott tárterület.
Végszó
Kissé hosszúra sikerült az első kubernetes cikkem, ezért a beharangozott zabbix szervert majd egy másik cikkben fogom bemutatni. És természetesen a microk8s-ről is is fogok még beszélni.