Oleme juba pikka aega jälginud systemd kasutamise teemat konteinerites. Juba 2014. aastal kirjutas meie turvainsener Daniel Walsh artikli , ja paar aastat hiljem – teise, mille pealkiri oli , kus ta märkis, et olukord pole just kuigi palju muutunud. Eriti märkis ta, et "kahjuks, isegi kaks aastat hiljem, kui googeldada 'Docker system', siis esimesena ilmub välja ikka see vana artikkel. Tundub, et on aeg midagi muuta". Lisaks oleme juba rääkinud .
Selles artiklis näitame, mis on vahepeal muutunud ja kuidas Podman selles osas abiks olla võib.
On mitmeid põhjuseid, miks käitada systemd konteineris, näiteks:
- Mitme teenuse konteinerid – paljud soovivad viia oma mitme teenuse rakendused virtuaalmasinatest konteineritesse. Ideaalis oleks parem need rakendused mikroteenusteks jagada, kuid mitte kõik ei oska seda veel teha või lihtsalt ei ole aega. Seega on nende rakenduste käitamine systemdi teenustena, kasutades unit-faile, absoluutselt mõistlik.
- Systemdi unit-failid – enamus rakendusi, mis töötavad konteinerites, on koostatud koodist, mis on varem töötanud virtuaal- või füüsilistes masinates. Neil rakendustel on unit-fail, mis on kirjutatud nende rakenduste jaoks ja teab, kuidas neid käivitada. Seega on teenuseid parem käivitada toetatud meetodite kaudu, mitte omaenda init-teenust häkkides.
- Systemd on protsesside haldur. See haldab teenuseid (lõpetab, taaskäivitab teenuseid või tapab zombiprotsessid) paremini kui ükski muu tööriist.
Samuti on palju põhjuseid, miks mitte käitada systemd konteinerites. Peamine põhjus on see, et systemd/journald kontrollib konteinerite väljundit ning sellised tööriistad nagu või eeldavad, et konteinerid kirjutavad logi otse stdout ja stderr. Seetõttu, kui plaanite hallata konteineri kaudu sellise orkestreerimise vahenditega, nagu ülaltoodud, tuleks tõsiselt kaaluda systemd-põhiste konteinerite kasutamise küsimust. Lisaks on Docker’i ja Moby arendajad sageli olnud teravalt vastu systemd kasutamisele konteinerites.
Podman'i tulek
Meil on hea meel teatada, et olukord on lõpuks liikuma hakanud. Red Hati meeskond, kes vastutab konteinerite käivitamise eest, otsustas välja töötada . Selle nimi on ja see pakub sama käsurealiidest (CLI) nagu Docker. Peaaegu kõik Docker'i käsud toimivad sama moodi ka Podman'is. Korraldame sageli töötubasid, mis nüüd kannavad nime , ja esimene slaid kutsub üles kirjutama: alias docker=podman.
Paljud nii ka teevad.
Meie Podman'iga ei ole me sugugi vastu systemd-põhistele konteineritele. Lõppude lõpuks kasutatakse Systemd sagedamini kui init-süsteemi Linuxis ja selle normaalse toimimise takistamine konteinerites tähendab ignoreerimist, kuidas tuhanded inimesed on harjunud konteinerite käivitamisega.
Podman teab, mida teha, et systemd töötaks konteineris korralikult. Selle jaoks on vajalikud sellised asjad nagu tmpfs'i mountimine /run ja /tmp. Systemd armastab, kui konteinerikeskkond on sisse lülitatud, ja see ootab kirjutamisõigusi oma cgroup'i katalooge ja /var/log/journald kausta.
Konteinerit käivitades, kus esimese käsuna on init või systemd, seadistab Podman automaatselt tmpfs'i ja Cgroups'i, et systemd käivitamine toimuks probleemideta. Selle automaatse käivitamisrežiimi blokeerimiseks kasutatakse valikut —systemd=false. Pidage meeles, et Podman kasutab systemd-režiimi ainult siis, kui see näeb, et tuleb käivitada systemd või init käsk.
Siin on katkendi manuaalist:
man podman run
…–systemd=true|false
Konteineri käivitamine systemd-režiimis. Vaikimisi on lubatud.
Kui konteineris käivitatakse systemd või init käsk, seadistab Podman tmpfs'i mountimispunktid järgmistesse kataloogidesse:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
Samuti kasutatakse vaikimisi stopp-signaalina SIGRTMIN+3.
Kõik see võimaldab systemd-l töötada suletud konteineris ilma mingite muudatusteta.
KÄSITLUS: systemd proovib kirjutada cgroup'i failisüsteemi. Kuid SELinux keelab vaikimisi konteineritel selle tegemise. Kirjutamise lubamiseks lülitage sisse loogiline parameeter container_manage_cgroup:
setsebool -P container_manage_cgroup true
Nüüd vaadake, milline näeb välja Dockerfile systemd käivitamiseks konteineris Podman'i kasutades:
# cat Dockerfile
FROM fedora
RUN dnf -y install httpd; dnf clean all; systemctl enable httpd
EXPOSE 80
CMD [ "/sbin/init" ]
See on kõik.
Nüüd kogume konteineri:
# podman build -t systemd .
Ütleme SELinux'ile, et lubada systemd'l cgroup'i konfiguratsiooni muuta:
# setsebool -P container_manage_cgroup true
Paljud unustavad selle sammu. Õnneks piisab sellest, kui teha see ainult üks kord ja seadistused salvestatakse pärast süsteemi taaskäivitamist.
Nüüd käivitame lihtsalt konteineri:
# 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õik, teenus on käivitunud ja töötab:
$ curl localhost
<html xml_lang="en" lang="en">
…
</html>
MÄRKUS: Ärge proovige seda Docker'is korrata! Seal on endiselt vaja palju keerukust, et selliseid konteinerite käivitamiseks demoniga. (Vajalikud on täiendavad väljad ja paketid, et see kõik Docker'is sujuvalt töötaks, või tuleb käivitada privileegitud konteineris. Täiendavad detailid vaata: .)
Veel paar ägedat asja Podmani ja systemd kohta
Podman töötab paremini systemd ühisfailides kui Docker
Kui konteinerid tuleb käivitada süsteemi käivitamisel, saab lihtsalt lisada vastavad Podmani käsklused systemd ühisfaili, see käivitab teenuse ja jälgib seda. Podman kasutab standardset harunemismudelit (fork-exec). Teisisõnu, konteinerite protsessid on Podmani protsessi alamprotsessid, seega on systemd'il neid lihtne jälgida.
Docker kasutab kliendi-serveri mudelit, ja Docker'i CLI käsklusi saab samuti otse paigutada ühisfaili. Kuid pärast seda, kui Docker'i klient on ühendatud Docker'i demoniga, on see (klient) lihtsalt veel üks protsess, mis töötleb stdin ja stdout. Omalt poolt ei tea systemd midagi seosest Docker'i kliendi ja konteineri vahel, mis töötab Docker'i demoni all, ja seetõttu ei saa systemd selle mudeli raames põhimõtteliselt teenust jälgida.
systemd aktiveerimine soketi kaudu
Podman töötab hästi soketi kaudu aktiveerimisega. Kuna Podman kasutab fork-exec mudelit, saab see soketi edastada oma alamprotsesside konteineritele. Docker nii ei oska, kuna kasutab kliendi-serveri mudelit.
Varlink teenus, mida Podman kasutab kaugklientide suhtlemiseks konteineritega, aktiveeritakse tegelikult läbi soketi. Node.js’is kirjutatud paket, cockpit-podman, mis on osa cockpit projektist, võimaldab inimestel suhelda Podman konteineritega läbi veebiliidese. Veebidemon, millel töötab cockpit-podman, saadab sõnumeid varlink soketile, mida kuulab systemd. Seejärel aktiveerib systemd Podman programmi sõnumite saamiseks ja konteinerite haldamiseks. Systemd aktiveerimine soketi kaudu võimaldab vältida pidevalt töötava deemoniga kaug-API rakendamist.
Lisaks arendame veel üht klienti Podmanile nimega podman-remote, mis rakendab sama Podman CLI, kuid kutsub varlink’i välja konteinerite käivitamiseks. Podman-remote saab töötada SSH-seansside peal, mis võimaldab turvaliselt suhelda konteineritega erinevates masinates. Aja jooksul plaanime kasutada podman-remote’i MacOS ja Windows toetamiseks koos Linuxiga, et arendajad nende platvormide peal võiksid käivitada Linuxi virtuaalmasina, kus töötab Podman varlink, ja tunda, et konteinerid töötavad kohalikul masinal.
SD_NOTIFY
Systemd võimaldab edasilükata abiteenuste käivitamist seni, kuni vajalik konteineriteenuse käivitamiseks saabub. Podman võib edastada soketi SD_NOTIFY konteineriteenusele, et see teavitaks systemd oma valmidusest. Ja taas, Docker, mis kasutab kliendi-server mudelit, ei oska seda teha.
Plaanis
Kavandame lisada käsu podman generate systemd CONTAINERID, mis genereerib systemd üksuse faili konkreetse määratud konteineri haldamiseks. See peaks toimima nii root- kui ka rootless-režiimides, et toetada mitteprivilegeeritud konteinerite haldamist. Oleme isegi näinud taotlust luua OCI-ühtne käituskeskkond systemd-nspawn.
Kokkuvõte
Systemd käivitamine konteineris on arusaadav vajadus. Ja tänu Podmanile on meil lõpuks konteinerite käitamise keskkond, mis ei ole systemd’ga vastuolus, vaid lubab selle hõlpsat kasutamist.
Allikas: habr.com
