Oleme juba pikka aega jälginud systemd kasutamist konteinerites. Juba 2014. aastal kirjutas meie turvaengineer Daniel Walsh artikli , ja paar aastat hiljem teise, mille pealkiri oli , milles ta märkis, et olukord ei ole just kuigi palju paranenud. Eriti ütles ta, et "kahjuks, isegi kaks aastat hiljem, kui googeldada 'Docker system', tuleb esimesena esile ikka see vana artikkel. On aeg midagi muuta." Lisaks oleme me juba kunagi rääkinud .
Selles artiklis näitame, mis on vahepeal muutunud ja kuidas Podman võiks meid aidata.
On palju põhjuseid, miks käivitada systemd konteineris, näiteks:
- Mitte üksnes teenuse konteinerid – paljud soovivad oma mitme teenusega rakendused välja võtta virtuaalmasinatest ja käivitada need konteinerites. Loomulikult oleks parem jagada need rakendused mikroteenusteks, kuid mitte kõik oskavad seda veel teha või lihtsalt ei ole aega. Seetõttu on selliste rakenduste käitamine systemd teenustena, mis käivitatakse unit-failidest, täiesti mõistlik.
- Systemd unit-failid – enamasti töötab rakendused, mis on konteinerites, koodist, mis varem töötas virtuaalsetes või füüsilistes masinates. Nendel rakendustel on ühikfail, mis on kirjutatud nende rakenduste jaoks ja mõistab, kuidas neid käivitada. Seetõttu on parem teenuseid käivitada toetatud meetodite abil, mitte omaenda init-teenust häkkides.
- Systemd on protsessihaldur. See haldab teenuseid (peatab, taaskäivitab teenuseid või sahkab zombiprotsesse) paremini kui ükski teine tööriist.
Samas on palju põhjusi, miks mitte käivitada systemd konteinerites. Peamine on see, et systemd/journald kontrollib konteinerite väljundit, samas kui tööriistad nagu või arvestavad, et konteinerid kirjutavad logi otse stdout ja stderr. Seetõttu, kui kavatsete hallata konteinerite kaudu orkestreerimistööristu nagu ülaltoodud, peaksite tõsiselt kaaluma systemd-põhiste konteinerite kasutamise küsimust. Lisaks on Docker ja Moby arendajad sageli olnud kategooriliselt vastu systemd kasutamisele konteinerites.
Podmani tulek
Meil on hea meel teatada, et olukord on lõpuks liikuma hakanud. Red Hatis konteinerite käivitamise eest vastutav meeskond otsustas välja töötada . Selle nimeks sai ja see pakub sama käsurealiidest (CLI) nagu Docker. Peaaegu kõiki Docker'i käske saab kasutada ka Podmanis. Korraldame sageli seminare, mis kannavad nüüd nime , ja esimene slaid kutsub üles seadistama: alias docker=podman.
Paljud teevadki seda.
Meie Podman'i puhul ei ole me mingil juhul vastu systemd põhistele konteineritele. Lõppude lõpuks kasutatakse systemd sagedamini kui muid alglaadimissüsteeme Linuxis, ja selle mitte lubamine konteinerites korralikult töötada tähendaks ignoreerimist, kuidas tuhanded inimesed on harjunud konteineritega töötama.
Podman teab, mida teha, et systemd tööta korralikult konteineris. Tal on vaja selliseid asju nagu tmpfs mountimine /run ja /tmp. Talle meeldib, kui "konteinerikeskkond" on sisse lülitatud, ning ta ootab kirjutamisõigusi oma osa cgroup kataloogis ja kaustas /var/log/journald.
Konteineri käivitamisel, kus esimene käsk on init või systemd, seadistab Podman automaatselt tmpfs ja Cgroups, et systemd käivitamine sujuks probleemideta. Selle automaatse käivitamise blokeerimiseks kasutatakse valikut —systemd=false. Pange tähele, et Podman kasutab systemd-režiimi ainult siis, kui ta näeb, et tuleb käivitada systemd või init käsk.
Siin on lõik käsiraamatust:
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 mount-punktid järgmistes kataloogides:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
Samuti kasutatakse vaikimisi peatumise signaalina SIGRTMIN+3.
See kõik võimaldab systemd-l töötada isoleeritud konteineris ilma mingite muudatusteta.
MÄRKUS: systemd üritab kirjutada cgroup failisüsteemi. Siiski keelab SELinux vaikimisi konteineritel selle tegemise. Kirjutamise lubamiseks aktiveerige loogiline parameeter container_manage_cgroup:
setsebool -P container_manage_cgroup true
Nüüd vaadake, kuidas 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" ]
Ja kõik.
Nüüd kogume konteineri:
# podman build -t systemd .
Lubame SELinux'i, et lubada systemd-l muuda Cgroups'i konfiguratsiooni:
# setsebool -P container_manage_cgroup true
Paljud, muide, unustavad selle sammu. Õnneks tuleb seda teha vaid üks kord ja seaded säilivad pärast süsteemi taaskäivitamist.
Nüüd käivitame 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äivitatud ja töötab:
$ curl localhost
<html xml_lang="en" lang="en">
…
</html>
MÄRKUS: Ärge proovige seda Docker'is! Seal on ikka veel vaja tantsida šamaaniga, et selliseid konteine demoniga käivitada. (Vajalikud on täiendavad väljad ja paketid, et kõike sujuvalt tööle saada Docker'is, või tuleb käivitada privileeritud konteineris. Lisainfot leiate .)
Veel paar lahedat asja Podmani ja systemd kohta
Podman töötab systemd unit-failides paremini kui Docker
Kui konteinerid tuleb süsteemi käivitamisel käivitada, saab lihtsalt lisada vastavad Podman'i käsud systemd unit-faili, mis käivitab teenuse ja jälgib seda. Podman kasutab käitamise standardmudelit (fork-exec). Teisisõnu, konteineriprotsessid on Podman'i protsessi suhtes alamprotsessid, mistõttu systemd saab neid hõlpsasti jälgida.
Docker kasutab klient-server mudelit, ning Docker CLI-käsklusi saab otse paigaldada ka unit-faili. Kuid pärast Docker kliendi ühendamist Docker-daemoniga muutub see lihtsalt veel üheks protsessiks, mis käsitleb stdin ja stdout. Ahnest systemd pole aimugi Docker kliendi ja konteineri vahelisest seosest, mis töötab Docker-daemoni all, seetõttu ei saa systemd selle mudeli kohaselt teenust monitoorida.
systemd aktiveerimine läbi socket'i
Podman toetab socket'i kaudu aktiveerimist õigesti. Kuna Podman kasutab fork-exec mudelit, suudab ta edastada socket'i oma laste konteineriprotsessidele. Docker seda ei oska, kuna kasutab klient-server mudelit.
Varlink teenus, mida Podman kasutab kaugclientside suhtlemiseks konteineritega, aktiveeritakse tegelikult kaudu soketi. Paketiga cockpit-podman, mis on kirjutatud Node.js-s ja kuulub cockpit projekti, saavad inimesed suhtelda Podmani konteineritega läbi veebiliidese. Veebi demon, millel töötab cockpit-podman, saadab sõnumeid varlink soketile, mida kuulab systemd. Seejärel aktiveerib systemd Podman programmi sõnumite saamiseks ja konteinerite haldamise alustamiseks. Systemdi aktiveerimine soketi kaudu võimaldab vältida pidevalt töö käigus oleva deemoniga kaug-API rakendamisel.
Lisaks arendame veel ühte Podman kliendi nimega podman-remote, mis rakendab sama Podman CLI, kuid kutsub varlinki konteinerite käivitamiseks. Podman-remote saab töötada SSH-seansside peal, võimaldades turvaliselt suhelda konteineritega erinevates masinates. Aja jooksul plaanime kasutada podman-remote'i, et toetada MacOS ja Windows koos Linuxiga, et arendajad nendel platvormidel saaksid käivitada Linuxi virtuaalmasina töökindla Podman varlinkiga ja tunneksid, et konteinerid töötavad kohalikus masinas.
SD_NOTIFY
Systemd võimaldab tõsta abiteenuste käivitamise aega kuni hetkeni, mil vajaliku konteineriseeritud teenuse käivitamine algab. Podman võib suunata SD_NOTIFY pistiku konteineriseeritud teenusesse, et see teenus teavitaks systemd-d oma valmidusest tööks. Ja jälle, Docker, mis kasutab kliendi-serveri mudelit, ei oska seda teha.
Plaanides
Plaanime lisada käsu podman generate systemd CONTAINERID, mis genereerib systemd teenuse faili konkreetse konteineri haldamiseks. See peaks töötama nii root- kui ka rootless-režiimides, et võimaldada juurdepääsu mitteprivilegeeritud konteineritele. Oleme isegi näinud taotlust OCI-ühilduva systemd-nspawn keskkonna loomise jaoks.
Kokkuvõte
Systemd käivitamine konteineris on täiesti loogiline vajadus. Ja tänu Podmanile on meil lõpuks konteinerite käivituskeskkond, mis ei ole systemd'iga vastuolus, vaid võimaldab selle kasutamist hõlpsalt.
Allikas: habr.com
