Käivitame systemd konteineris

Oleme juba pikka aega jälginud systemd kasutamist konteinerites. Juba 2014. aastal kirjutas meie turvaengineer Daniel Walsh artikli systemd käitamine Docker konteineris, ja paar aastat hiljem teise, mille pealkiri oli systemd käitamine mitterikkal konteineris, 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 konfliktist Docker ja systemd arendajate vahel.

Käivitame systemd konteineris

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:

  1. 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.
  2. 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.
  3. 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 Kubernetes või OpenShift 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 oma konteinerimootori. Selle nimeks sai Podman 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 Vahetame Docker'i Podmani vastu, 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 artiklis.)

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

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster