Startējam systemd konteinerā

Mēs jau sen sekojam tēmai par systemd izmantoÅ”anu konteineros. Vēl 2014. gadā mÅ«su droŔības inženieris Daniel Walsh uzrakstÄ«ja rakstu Running systemd within a Docker Container, bet pāris gadus vēlāk – citu, kas saucās Running systemd in a non-privileged container, kurā viņŔ norādÄ«ja, ka situācija nemaz nav uzlabojusies. Proti, viņŔ rakstÄ«ja, ka 'diemžēl, pat divus gadus vēlāk, ja googlē Ā«Docker systemĀ», tad pirmais, kas parādās, ir viņa vecais raksts. Tātad, ir pienācis laiks kaut ko mainÄ«t'. Turklāt mēs jau reiz stāstÄ«jām par konfliktu starp Docker un systemd izstrādātājiem.

Startējam systemd konteinerā

Å ajā rakstā mēs parādÄ«sim, kas ir mainÄ«jies pagājuÅ”ajā laikā un kā mums var palÄ«dzēt Å”ajā jautājumā Podman.

Ir daudz iemeslu, lai palaistu systemd iekŔējos konteineros, piemēram:

  1. Multiservisa konteineri – daudzi vēlas izņemt savas multiservisa lietotnes no virtuālajām maŔīnām un palaist tās konteineros. Protams, bÅ«tu labāk Ŕādas lietotnes sadalÄ«t mikroservisos, bet ne visi to spēj vai vienkārÅ”i nav laika. Tāpēc palaist Ŕādas lietotnes kā pakalpojumus, ko palaidÄ«s systemd no vienÄ«bas failiem, ir pilnÄ«gi saprātÄ«gi.
  2. Systemd vienÄ«bas faili – lielākā daļa lietotņu, kas darbojas iekŔējos konteineros, ir saliktas no koda, kas iepriekÅ” tika palaists uz virtuālajām vai fiziskām maŔīnām. Å Ä«m lietotnēm ir vienÄ«bas fails, kas tika rakstÄ«ts Ŕīm lietotnēm un saprot, kā tās jāsāk. Tādējādi, pakalpojumus ir labāk palaist, izmantojot atbalstÄ«tus risinājumus, nevis laužot savu paÅ”u init dienestu.
  3. Systemd ir procesu vadītājs. Tas pārvalda pakalpojumus (izbeidz, restarts pakalpojumus vai iznīcina zīmobrisus) labāk nekā jebkurŔ cits instruments.

Tomēr ir arÄ« daudzi iemesli, lai nepalaistu systemd konteineros. Galvenais ir tas, ka systemd/journald kontrolē konteineru izvadi, un tādas rÄ«ces kā Kubernetes vai OpenShift paredz, ka konteineri rakstÄ«s žurnālus tieÅ”i stdout un stderr. Tāpēc, ja plānojat pārvaldÄ«t konteinerus, izmantojot minētos orÄ·estrācijas rÄ«kus, tad ir nopietni jādomā par systemd pamata konteineru izmantoÅ”anu. Turklāt Docker un Moby izstrādātāji bieži ir bijuÅ”i kategoriski pret systemd izmantoÅ”anu konteineros.

Podman ienākŔana

Ar prieku paziņojam, ka situācija beidzot ir pārvietojusies no miruŔās punktu. Komanda, kas Red Hat ir atbildÄ«ga par konteineru palaiÅ”anu, ir nolēmusi izstrādāt savu paÅ”u konteineru dzinēju. Tas saņēmis nosaukumu Podman un piedāvā tādu paÅ”u komandu rindu (CLI) saskarni kā Docker. Un praktiski visas Docker komandas var izmantot arÄ« Podman. Mēs bieži rÄ«kojam seminārus, kas tagad saucas Mainām Docker uz Podman, un pirmajā slaidā aicina rakstÄ«t: alias docker=podman.

Daudzi to arī dara.

Mēs ar savu Podman neesam pret konteineriem, kas balstās uz systemd. Galu galā Systemd biežāk tiek izmantots kā init-sistēma Linux, un ļaut tam normāli nedarboties konteineros nozÄ«mē ignorēt, kā tÅ«kstoÅ”iem cilvēku ir pieraduÅ”i palaist konteinerus.

Podman zina, ko darÄ«t, lai systemd normāli darbotos konteinerā. Tam nepiecieÅ”amas tādas lietas kā tmpfs montēŔana uz /run un /tmp. Tam patÄ«k, kad ir aktivizēta "konteineru" vide, un tas gaida rakstīŔanas tiesÄ«bas savā cgroup kataloga daļā un mapē /var/log/journald.

Palaidot konteineru, kurā pirmā komanda ir init vai systemd, Podman automātiski konfigurē tmpfs un Cgroups, lai systemd palaiÅ”ana noritētu bez problēmām. Lai bloķētu Å”o automātisko palaiÅ”anas režīmu, tiek izmantota opcija —systemd=false. Ņemiet vērā, ka Podman izmanto systemd režīmu tikai tad, kad redz, ka jāpaveic systemd vai init komanda.

Šeit ir izvilkums no rokasgrāmatas:

man podman run
…

–systemd=true|false

Konteinera palaiÅ”ana systemd režīmā. Pēc noklusējuma ir ieslēgta.

Ja konteinerā tiek izpildÄ«ta systemd vai init komanda, Podman konfigurēs tmpfs montēŔanas punktus Ŕādos katalogos:

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

ArÄ« kā apstāŔanās signāls pēc noklusējuma tiks izmantots SIGRTMIN+3.

Viss tas ļauj systemd darboties slēgtā konteinerā bez jebkādām modifikācijām.

Piezīme: systemd mēģina veikt ierakstus cgroup failu sistēmā. Tomēr SELinux pēc noklusējuma aizliedz konteineriem to darīt. Lai atļautu ierakstus, ieslēdziet loģisko parametru container_manage_cgroup:

setsebool -P container_manage_cgroup true

Tagad aplūkosim, kā izskatās Dockerfile systemd palaiŔanai konteinerā, izmantojot Podman:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Tas arī viss.

Tagad uzkrājam konteineru:

# podman build -t systemd .

Sakām SELinux atļaut systemd modificēt Cgroups konfigurāciju:

# setsebool -P container_manage_cgroup true

Daudzi, starp citu, aizmirst par Å”o soli. Par laimi, to nepiecieÅ”ams izdarÄ«t tikai vienu reizi, un iestatÄ«jumi tiek saglabāti arÄ« pēc sistēmas restartēŔanas.

Tagad vienkārŔi uzsākam konteineru:

# 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.

Viss, pakalpojums ir uzsācies un darbojas:

$ curl localhost

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

…

</html>

PIEZÄŖME: Neaizmirstiet to izmēģināt Docker’ā! Tur joprojām ir nepiecieÅ”amas dažādas manipulācijas, lai palaiž Ŕāda veida konteinerus caur demonizēto. (NepiecieÅ”ami papildu lauki un pakotnes, lai viss bez problēmām darbotos Docker, vai arÄ« tas bÅ«s jāpalaiž privileģētā konteinerā. SÄ«kāk skatiet rakstā.)

Vēl pāris interesantu lietu par Podman un systemd

Podman darbojas labāk nekā Docker systemd vienības failos

Ja konteinerus jāuzsāk pie sistēmas ielādes, var vienkārÅ”i ievietot attiecÄ«gās Podman komandas systemd vienÄ«bas failā, kas uzsāks pakalpojumu un uzraudzÄ«s to. Podman izmanto standarta izpildes modeli (fork-exec). Citiem vārdiem sakot, konteineru procesi ir meitas procesi attiecÄ«bā pret Podman procesu, tāpēc systemd to viegli var uzraudzÄ«t.

Docker izmanto klienta-servera modeli, un Docker CLI komandas var arÄ« ievietot tieÅ”i vienÄ«bas failā. Tomēr, kad Docker klients pieslēdzas Docker demonam, tas (klients) kļūst par vēl vienu procesu, kas apstrādā stdin un stdout. Savukārt, systemd vispār nezina par saikni starp Docker klientu un konteineru, kas darbojas Docker demona vadÄ«bā, tāpēc Å”ajā modelÄ« systemd principā nevar uzraudzÄ«t pakalpojumu.

systemd aktivācija caur soketu

Podman pareizi apstrādā aktivāciju caur soketu. Tā kā Podman izmanto fork-exec modeli, tas var nodot soketu saviem meitas konteineru procesiem. Docker tā nemāk, jo izmanto klienta-servera modeli.

Varlink serviss, ko Podman izmanto, lai mijiedarbotos ar attālajiem klientiem un konteineriem, patiesībā tiek aktivizēts caur soketu. Pakotne cockpit-podman, kas ir rakstīta Node.js un ietilpst cockpit projekta sastāvā, ļauj cilvēkiem mijiedarboties ar Podman konteineriem caur tīmekļa interfeisu. Tīmekļa demons, uz kura darbojas cockpit-podman, sūta ziņojumus uz varlink soketu, kuru klausās systemd. Pēc tam systemd aktivizē Podman programmu, lai saņemtu ziņojumus un sāktu pārvaldīt konteinerus. Systemd aktivizācija caur soketu ļauj iztikt bez pastāvīga darba demona attālināto API realizācijā.

Turklāt mēs izstrādājam vēl vienu klientu Podmanam, ko sauc podman-remote, kas Ä«steno to paÅ”u Podman CLI, bet izmanto varlink, lai palaistu konteinerus. Podman-remote var darboties virs SSH sesijām, ļaujot droÅ”i mijiedarboties ar konteineriem dažādās maŔīnās. Laika gaitā mēs plānojam izmantot podman-remote, lai atbalstÄ«tu MacOS un Windows kopā ar Linux, lai izstrādātāji Å”ajās platformās varētu palaist Linux virtuālo maŔīnu ar darbojoÅ”os Podman varlink un iegÅ«t pilnÄ«gu sajÅ«tu, ka konteineri izpildās uz vietējās maŔīnas.

SD_NOTIFY

Systemd ļauj atlikt palÄ«gservisu uzsākÅ”anu lÄ«dz brÄ«dim, kad ir uzsākts nepiecieÅ”amais tiem konteinerizētais serviss. Podman var nodot SD_NOTIFY soketu konteinerizētajam servisam, lai tas paziņotu systemd par savu gatavÄ«bu strādāt. Un atkal, Docker, kas izmanto klienta-servera modeli, tā nedara.

Plāni

Mēs plānojam pievienot komandu podman generate systemd CONTAINERID, kas Ä£enerēs systemd vienÄ«bas failu konkrēta noteikta konteinca pārvaldÄ«bai. Tam jādarbojas gan root-, gan rootless režīmos nepilnvarotiem konteineriem. Mēs pat esam redzējuÅ”i pieprasÄ«jumu izveidot OCI savietojamu systemd-nspawn izpildes vidi.

Secinājums

Systemd palaiŔana konteinerā ir pilnīgi saprotama vajadzība. Un, pateicoties Podman, mums beidzot ir konteineru palaiŔanas vide, kas nav naidīga pret systemd, bet ļauj to vienkārŔi izmantot.

Avots: habr.com

Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem šŸ”„ Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem | ProHoster