Nemrég megjelent a TrueNAS Scale 24.10 "Electric Eel" következő fő verziója. Az egyik fontos újítás, hogy az alkalmazások kezeléséhez lecserélték a nehézkes Kubernetest a kevesebb erőforrást igénylő Docker-re. Korábban kubernetesnél megszokott Helm Chart alapú alkalmazásokat telepíthettünk a hivatalos tárolóból, vagy ha az elérhető alkalmazásokon kívül bővíteni szerettük volna a lehetőségeinket, úgy hozzáadhattuk a TrueCharts nevezetű community alkalmazás katalógust. Ennek a lehetősége az Electric Eel kiadását megelőzően a TrueNAS és a TrueCharts fejlesztők konfliktusa után nagyon hirtelen szűnt meg a TrueCharts repó elérhetetlenné tételével.
A TrueNAS-ban ha egy új alkalmazást szeretnénk, akkor a GUI segítségével kiválaszthatjuk azt az alkalmazás katalógusból, vagy ha ott nem elérhető, akkor az Apps -> Discover Apps -> Custom App gomb segítségével paraméterezhetünk és összekattintgathattuk egy appot. Ez korábban is így volt, amikor a TrueNAS egy custom chartot hozott létre és így van ez most is, amikor egy Docker konténert indítunk.
Mindez eléggé nehezen kivitelezhető és nyomon követhető, vagy ha tesztelésképpen törlünk, majd újra létrehozzuk az appot, akkor újra végig kell járnunk a telepítés lépéseit. Ha Portainert vagy Dockge-t használunk, akkor legalább a compose fájlokat újra felhasználhatjuk, de azokat nekünk kell tárolni és a verziókezelés továbbra sem megoldott, meg kell a gui és a manuális munka a törléshez, létrehozáshoz, ráadásul a Portainer/Dockge maga is része annak a Docker környezetnek, amelyet használunk.
Hirdetés
Egyszerű Docker hostokon a konténereket Terraform segítségével managelem. Az app Docker compose-hoz hasonló leíró fájlokban tárolódik gitben. A Jenkins build szerver innen checkoutolja ki, majd futtatja rá a docker hostra, létrehozva a konténer környezetet. A Terraform core úgy képes API-val kommunikálni, ha úgynevezett providereken keresztül megtanítjuk neki. Ilyen provider létezik rengeteg mindenhez, aminek API-ja van: Azure, AWS és Docker is. Természetesen van TrueNAS-hoz is, csakhogy ez az appokat soha nem kezelte még.
Most, hogy a TrueNAS Docker alapú lett, talán már lehetséges, hogy a TrueNAS-t egyszerű Docker hostként kezelve beillesszem a meglévő automatizmusomba. Az alábbi koncepciótesztben ennek a lehetőségét vizsgáljuk meg és talán ötletet adok az otthoni környezet indusztriális módon történő karbantartásához.
Első lépésként azt kell kipróbálni, hogy lehetséges-e CLI-ből Terraform segítségével konténert deployolni. A Docker parancsok rootként mind működnek, ami előfeltétele ennek. A legegyszerűbb módon ezt úgy tudjuk kipróbálni, hogy az általam írt modul példáját egyszerűen lefuttatjuk. A szükséges parancsok (git, wget, unzip) mind elérhetőek command lineból:
Az nginx konténer ezzel sikeresen elindult, majd a curl visszaadta a tárolt html-t. Sajnos ez a konténer valamiért nem regisztrálódik a TrueNAS UI-on. A létrehozott Docker resourceokat eltüntethetjük az apply sor megismétlésével a -destroy kapcsoló megadása után.
Második lépésben a TrueNAS instance-ot be kell állítani Jenkins agentként. Ehhez először egy külön datasetet hoztam létre (az éles rendszeren nem szeretném build információ tárolására a root disket használni), majd Jenkins userre van szükség, illetve a publikus SSH kulcs feltöltésére. Mindkettő elvégezhető a Credentials -> Users menüpont alatt, ahol a későbbiekben akár korlátozható az is, hogy milyen parancsot futtathat a user passwordless rootként:
Ahhoz, hogy a Jenkins build szerveren a TrueNAS-t agentként beállítsuk, szükséges a Java futtatókörnyezet, ami viszont nem elérhető a TrueNAS-on és nem is telepíthető a letiltott Debian csomagkezelőből. Alternatívaként ezért azt letöltöttem, majd kicsomagoltam a jenkins home-ba.
Utolsó lépésként hozzáadtam Jenkinsben új agentként a truenas szerveremet a Manage Jenkins -> Nodes alatt, ügyelve néhány paraméterre, amit alább bekereteztem:
A Terraform maga egyetlen binárisból áll, amit letölthetünk és a jenkins user által elérhető helyre mentünk, miután kicsomagoltuk. Esetemben ez a /mnt/data/jenkins_home/bin/ alá történt.
Végül visszatérhetünk a Jenkinshez és új pipeline-t kérünk a New Item -> Pipeline segítségével, és az oldal alján inline kódnak az alábbi szkriptet adjuk. A label segítségével szabályozzuk, hogy melyik Jenkins nodeunkra fusson a pipeline, majd az első stage-ben kicheckoutoljuk a git kódot, amely tartalmazza az nginx példát, majd a második stage-ben hívjuk a terraformot:
pipeline {
agent {
label 'truezen'
}
options {
disableConcurrentBuilds()
buildDiscarder(
logRotator(
artifactDaysToKeepStr: '60',
artifactNumToKeepStr: '10',
daysToKeepStr: '60',
numToKeepStr: '10'
)
)
}
stages {
stage ('Checkout and init'){
steps {
git url: 'https://github.com/kzl86/terraform-docker-docker_container.git', branch: 'main'
}
}
stage ('Deploy terraform'){
steps {
script {
sh """
cd "${WORKSPACE}"/examples/nginx
sudo /mnt/data/jenkins_home/bin/terraform init
sudo /mnt/data/jenkins_home/bin/terraform plan -var "nginx_mount_source=${WORKSPACE}/examples/nginx"
sudo /mnt/data/jenkins_home/bin/terraform apply -var "nginx_mount_source=${WORKSPACE}/examples/nginx" -auto-approve
"""
}
}
}
}
}
Ennek eredményeképpen hasonló kimenetet látunk, mint a legelső esetben: a Terraform sikeresen alkalmazta a megadott kódot és az nginx konténer elindult:
Ha a böngészőben megnyitjuk a kódban megadott portot, akkor újra láthatjuk a korábbi oldalt:
Összefoglalásképpen tehát megtudtuk, hogy lehetséges a TrueNAS-t egyszerű Docker hostként használni és Jenkins segítségével Terraformmal gitből deployolni. Nem nehéz belátni ennek az előnyét, hogy egyrészt szigorú verziókezelésben tartjuk a rendszert és csakis az fut, amit mi szeretnénk, nincs meglepetésszerű chart vagy konténer image frissítés, ami után ha nem működik, akkor elkezdhetünk debugolni.
Ebben a rendszerben ha frissíteni szeretnénk egy appunk image-ét, akkor egyszerűen kommitoljuk az új verziót, majd futtatjuk a Jenkinst és a Terraform gondoskodik a konténer image-ének cseréjéről és újraindításáról. Ha szükséges, akkor ugyanilyen egyszerűen és gyorsan vissza is állíthatjuk. (Ha pedig webhook-ot állítunk be, akkor még a Jenkins job futtatása sem szükséges, elég egy kommit a repóba.)