A systemd indítása konténerben

Már régóta figyeljük a systemd konténerben való használatának témáját. Már 2014-ben a biztonsági mérnökünk, Daniel Walsh, írt egy cikket A systemd futtatása egy Docker-konténerben, majd néhány évvel később egy másikat, amelynek címe volt A systemd futtatása nem privilegizált konténerben, amelyben megállapította, hogy a helyzet nem sokat javult. Különösen azt írta, hogy "sajnos, két évvel később, ha rákeresünk a 'Docker system' kifejezésre, az első, ami felbukkan, az a régi cikk. Azt jelenti, hogy itt az ideje valamit változtatni". Ezen kívül már beszéltünk a konfliktusról a Docker és a systemd fejlesztői között.

A systemd indítása konténerben

Ezért a cikkben megmutatjuk, mi változott azóta és hogyan segíthet nekünk ebben a kérdésben a Podman.

Rengeteg oka van annak, hogy a systemd-t konténerben futtassuk, ilyenek például:

  1. Több szolgáltatású konténerek – sokan szeretnék a több szolgáltatásból álló alkalmazásaikat virtuális gépekből eltávolítani és konténerekben futtatni. Természetesen jobb lenne, ha ilyen alkalmazásokat mikroszolgáltatásokra bontanánk, de ezt még nem mindenki tudja, vagy egyszerűen nincs rá ideje. Ezért ezeknek az alkalmazásoknak a systemd révén egységfájlokból való futtatása teljesen értelmes.
  2. Systemd egységfájlok – a konténerben futó legtöbb alkalmazás kódja olyan programokból áll, amelyeket korábban virtuális vagy fizikai gépeken futtattak. Ezeknek az alkalmazásoknak van egy egységfájlja, amelyet ezekhez az alkalmazásokhoz írtak és tudja, hogyan kell azokat elindítani. Ezért a szolgáltatásokat jobb támogatott módszerekkel elindítani, nem pedig saját init-rendszerük feltörésével.
  3. A systemd egy folyamatszabályozó. Jobban kezeli a szolgáltatásokat (leállítja, újraindítja a szolgáltatásokat vagy megöli a zombiként működő folyamatokat), mint bármely más eszköz.

Ugyanakkor számos ok van arra is, hogy ne futtassuk a systemd-t konténerekben. A fő ok az, hogy a systemd/journald ellenőrzi a konténerek kimenetét, míg olyan eszközök, mint a Kubernetes vagy OpenShift arra számítanak, hogy a konténerek közvetlenül a stdout és stderr-ba írnak naplózást. Ezért, ha a konténereket a fent említett orchestration eszközök révén szeretnék kezelni, komolyan el kell gondolkodni a systemd alapú konténerek használatán. Ezen kívül a Docker és Moby fejlesztői gyakran ellenezték a systemd használatát a konténerekben.

A Podman megjelenése

Örömmel értesítjük, hogy a helyzet végre elmozdult a holtpontról. A Red Hat csapata, amely a konténerek indításáért felel, úgy döntött, hogy kifejleszti saját konténermotorját. A neve Podman , és ugyanazt a parancssori felületet (CLI) kínálja, mint a Docker. Szinte minden Docker parancsot pontosan ugyanúgy lehet használni a Podman-nal. Gyakran tartunk workshopokat, amelyek mostantól a következő nevet viselik: Docker cseréje Podman-ra, és az első diája arra buzdít, hogy írja be: alias docker=podman.

Sokan ezt meg is teszik.

A Podman esetében semmilyen ellenséges érzésünk sincs a systemd alapú konténerekkel szemben. A Systemd gyakran a Linux init-alrendszereként működik, és ha nem hagyjuk, hogy normálisan működjön a konténereken belül, az figyelmen kívül hagyja, ahogyan ezrek szokták indítani a konténereket.

A Podman tudja, mit kell tenni annak érdekében, hogy a systemd normálisan működjön a konténerben. Számára szükséges dolgok például a tmpfs csatolása a /run és /tmp mappákhoz. Szereti, ha a "konténeres" környezet be van kapcsolva, és várja a írási jogokat a cgroup mappájában és a /var/log/journald mappában.

Amikor olyan konténert indítunk, amelyben az első parancs az init vagy a systemd, a Podman automatikusan beállítja a tmpfs-t és a Cgroups-ot, hogy a systemd indítása problémamentes legyen. Ezt az automatikus indítást a —systemd=false opcióval lehet letiltani. Vegye figyelembe, hogy a Podman csak akkor használja a systemd módot, ha arra látja, hogy systemd vagy init parancsot kell végrehajtani.

Íme egy részlet a kézikönyvből:

man podman run
…

–systemd=true|false

Konténer indítása systemd módban. Alapértelmezés szerint engedélyezve van.

Ha a konténerben systemd vagy init parancs fut, a Podman beállítja a tmpfs csatolási pontjait a következő mappákban:

/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal

A leállítási jelzéshez alapértelmezésként a SIGRTMIN+3 jelzés használható.

Mindez lehetővé teszi a systemd működését egy zárt konténerben bármilyen módosítás nélkül.

MEGJEGYZÉS: a systemd megpróbál írni a cgroup fájlrendszerbe. Azonban az SELinux alapértelmezés szerint megtiltja a konténerek számára ezt. A írás engedélyezéséhez kapcsolja be a container_manage_cgroup logikai paramétert:

setsebool -P container_manage_cgroup true

Most nézzük meg, hogyan néz ki a Dockerfile a systemd konténerben történő indításához a Podman használatával:

# cat Dockerfile

FROM fedora

RUN dnf -y install httpd; dnf clean all; systemctl enable httpd

EXPOSE 80

CMD [ "/sbin/init" ]

Ennyi.

Most összegyűjtjük a konténert:

# podman build -t systemd .

Kérjük, engedélyezze az SELinux-t, hogy a systemd módosíthassa a Cgroups konfigurációját:

# setsebool -P container_manage_cgroup true

Sokan elfelejtik ezt a lépést. Szerencsére ezt csupán egyszer kell elvégezni, és a beállítások megmaradnak a rendszer újraindítása után.

Most egyszerűen elindítjuk a konténert:

# podman run -ti -p 80:80 systemd

systemd 239 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid)

Detected virtualization container-other.

Detected architecture x86-64.

Welcome to Fedora 29 (Container Image)!

Set hostname to <1b51b684bc99>.

Failed to install release agent, ignoring: Read-only file system

File /usr/lib/systemd/system/systemd-journald.service:26 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.

Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)

[  OK ] Listening on initctl Compatibility Named Pipe.

[  OK ] Listening on Journal Socket (/dev/log).

[  OK ] Started Forward Password Requests to Wall Directory Watch.

[  OK ] Started Dispatch Password Requests to Console Directory Watch.

[  OK ] Reached target Slices.

…

[  OK ] Started The Apache HTTP Server.

Kész, a szolgáltatás elindult és működik:

$ curl localhost

<html  xml_lang="en" lang="en">

…

</html>

MEGJEGYZÉS: Ne próbálja meg ezt Docker-en! Ott továbbra is szükség van némi „bábozásra”, hogy ilyen típusú konténereket futtasson a démonon keresztül. (További mezőkre és csomagokra lesz szükség ahhoz, hogy mindez zökkenőmentesen működjön Docker alatt, vagy privilegizált konténerben kell futtatni. Részletekért lásd: a Spotify döntéshozatali módszertanáról. Egyre több felhasználó preferálja a zenehallgatást mobilon a streaming szolgáltatásban, de a cégnél túlnyomórészt webprogramozók dolgoznak. A Spotify elemezte ezt a helyzetet, és úgy döntött, hogy több mobilfejlesztőt vesz fel, valamint átnevezi a webes szakembereket új irányba:.)

Még pár érdekes dolog a Podman-ről és a systemd-ről

A Podman jobban működik a Docker-nél a systemd egységfájlokban

Ha a konténereket a rendszer indításakor kell futtatni, egyszerűen be lehet illeszteni a megfelelő Podman parancsokat a systemd egységfájlba, amely elindítja a szolgáltatást és figyelemmel kíséri azt. A Podman a standard fork-exec végrehajtási modellt használja. Más szóval, a konténerfolyamatok alfolyamatok a Podman folyamatához képest, így a systemd egyszerűen figyelemmel tudja kísérni őket.

A Docker kliens-szerver modellt használ, és a Docker CLI parancsokat közvetlenül a egységfájlban is elhelyezheti. Azonban amikor a Docker kliens csatlakozik a Docker démonhoz, az (a kliens) egyszerűen csak egy újabb folyamat lesz, amely a stdin-t és stdout-t kezeli. A systemd viszont nem tud a Docker kliens és a Docker démon alá tartozó konténer közötti kapcsolatról, és ezért ebben a modellben a systemd alapvetően nem tudja figyelemmel kísérni a szolgáltatást.

A systemd aktiválása socket-en keresztül

A Podman megfelelően kezeli a socket alapú aktiválást. Mivel a Podman fork-exec modellt alkalmaz, képes a socketet átkonvertálni a gyermek konténerfolyataihoz. A Docker nem tudja ezt, mert kliens-szerver modellt használ.

A varlink szolgáltatás, amelyet a Podman használ a távoli kliensek kommunikációjához a tartályokkal, valójában socketen keresztül aktiválódik. A cockpit-podman csomag, amely Node.js-ben készült és a cockpit projekt része, lehetővé teszi, hogy az emberek a Podman konténerekkel webes felületen keresztül lépjenek kapcsolatba. A webdémon, amelyen a cockpit-podman fut, üzeneteket küld a varlink socketre, amelyet a systemd figyel. Ezt követően a systemd aktiválja a Podman programot az üzenetek fogadására és a konténerek kezelésének megkezdésére. A systemd socket általi aktiválása lehetővé teszi, hogy elkerüljük egy állandóan futó démon telepítését a távoli API-k implementálásakor.

Ezen kívül egy másik klienst is fejlesztünk a Podman számára, amelyet podman-remote-nak hívnak. Ez ugyanazt a Podman CLI-t valósítja meg, de varlinket hív a tartályok indításához. A podman-remote SSH-szekciók felett képes működni, lehetővé téve a biztonságos interakciót a különböző gépeken található tartályokkal. Idővel a podman-remote támogatást kap MacOS és Windows operációs rendszerekhez a Linux mellett, hogy a fejlesztők ezeken a platformokon Linux virtuális gépet tudjanak indítani a működő Podman varlink-kel, és teljes illúziójuk legyen arról, hogy a konténerek helyben futnak.

SD_NOTIFY

A Systemd lehetővé teszi, hogy a segédszolgáltatások indítását elhalasszuk addig, amíg nem indul el a szükséges tartályozott szolgáltatás. A Podman képes átadni az SD_NOTIFY socketet a tartályozott szolgáltatásnak, hogy értesítse a systemd-t a működőképességéről. Ismételten a Docker, amely kliens-szerver modellt használ, ezt nem tudja megvalósítani.

Tervekben

Tervezünk egy podman generate systemd CONTAINERID parancsot, amely systemd egységfájlt generál egy adott tartály kezeléséhez. Ennek a funkciónak mind a root, mind a rootless üzemmódban működnie kell a nem privilégizált konténerekhez. Még láttunk egy kérdést az OCI-kompatibilis systemd-nspawn futtatási környezet létrehozására.

Zárás

A systemd futtatása egy konténerben teljesen érthető igény. A Podman segítségével végre van egy olyan indító környezetünk, amely nem áll ellentétben a systemd-vel, hanem megkönnyíti annak használatát.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster