Ne kemi ndjekur prej kohësh temën e përdorimit të systemd në kontejnerë. Që në vitin 2014, inxhinieri ynë i sigurisë Daniel Walsh shkroi një artikull , dhe disa vite më vonë – një tjetër, që quhej , në të cilin ai konstatoi se situata nuk kishte përmirësuar shumë. Sipas tij, "për fat të keq, dhe dy vjet më vonë, nëse kërkoni 'Docker system', artikulli i tij i vjetër shfaqet në radhën e parë. Pra, është koha për të bërë një ndryshim". Për më tepër, ne kemi folur më parë për .
Në këtë artikull, ne do të tregojmë se çfarë ka ndryshuar gjatë kësaj kohe dhe si na ndihmon Podman për këtë çështje.
Ekzistojnë shumë arsye për të ekzekutuar systemd brenda një kontejneri, siç janë:
- Konteinerë multi-shërbimesh – shumë duan të nxjerrin aplikacionet e tyre multi-shërbimore nga makinave virtuale dhe t'i ekzekutojnë ato në kontejnerë. Sigurisht, do të ishte më mirë t'i ndanin aplikacionet e tilla në mikro-shërbime, por nuk të gjithë dinë ta bëjnë këtë ose thjesht nuk kanë kohë. Pra, ekzekutimi i aplikacioneve të tilla si shërbime të ekzekutuara nga systemd nga skedarët e njësive ka kuptim.
- Skedarët e njësive Systemd – shumica e aplikacioneve që punojnë brenda kontejnerëve janë ndërtuar nga kodi që deri më tani është ekzekutuar në makina virtuale ose fizike. Këto aplikacione kanë një skedar njësie që është shkruar për këto aplikacione dhe e di se si duhet t'i ekzekutojë. Prandaj, është më mirë të ekzekutoni shërbimet duke përdorur metoda që mbështeten, sesa të hakeroni vetë shërbimin tuaj të parë.
- Systemd është një menaxher procesesh. Ai menaxhon shërbimet (ndalon, rikthen shërbimet ose eliminon proceset e zvarritjes) më mirë se çdo mjet tjetër.
Megjithatë, ekzistojnë shumë arsye për të mos ekzekutuar systemd në kontejnerë. Arsyja kryesore është se systemd/journald kontrollon daljet e kontejnerëve, dhe mjete si ose presin që kontejnerët të shkruajnë log në stdout dhe stderr. Prandaj, nëse planifikoni të menaxhoni kontejnerët nëpërmjet mjeteve të orkestrimit të përmendura më lart, duhet të mendoni seriozisht mbi çështjen e përdorimit të kontejnerëve të bazuar në systemd. Për më tepër, zhvilluesit e Docker dhe Moby shpesh janë shprehur kundër përdorimit të systemd në kontejnerë.
Arritja e Podman-it
Me gëzim ju njoftojmë se situata më në fund ka përparuar. Ekipi në Red Hat përgjegjës për implementimin e kontejnerëve ka vendosur të zhvillojë . Ai u quajt dhe ofron një ndërfaqe të ngjashme me linjën e komandës (CLI) si Docker. Në të vërtetë, shumica e komandave të Docker mund të përdoren gjithashtu në Podman. Ne shpesh organizojmë seminare që tani quhen , dhe slajdi i parë inkurajon të shkruani: alias docker=podman.
Shumë njerëz e bëjnë këtë.
Ne me Podman nuk jemi në asnjë mënyrë kundër kontejnerëve të bazuar në systemd. Në fund të fundit, Systemd përdoret më shpesh si nën-sistemi init i Linux, dhe të mos i lejojmë të funksionojë normalisht në kontejnerë do të thotë të injorojmë mënyrën se si mijëra njerëz janë mësuar të nisen kontejnerët.
Podman di se çfarë duhet bërë për të lejuar që systemd të funksionojë normalisht në kontejner. Atij i nevojiten gjëra të tilla si montimi i tmpfs në /run dhe /tmp. Atij i pëlqen kur është aktivizuar ambienti 'konteiner', dhe pret të drejtat për të shkruar në pjesën e saj të dosjes cgroup dhe në dosjen /var/log/journald.
Kur nisni një kontejner, në të cilin komanda e parë është init ose systemd, Podman automatikisht konfiguron tmpfs dhe Cgroups në mënyrë që nisja e systemd të kalojë pa probleme. Për të bllokuar këtë mënyrë automatikisht të nisjes, përdoret opsioni —systemd=false. Vini re se Podman përdor mënyrën systemd vetëm kur sheh që duhet të ekzekutohet komanda systemd ose init.
Ja një përmbledhje nga manuali:
man podman run
…–systemd=true|false
Nisja e kontejnerit në mënyrën systemd. Aktivizuar nga e drejta.
Nëse në brendësi të kontejnerit ekzekutohet një komandë systemd ose init, Podman do të konfigurojë pikat e montimit tmpfs në kataloget e mëposhtme:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
Po ashtu, si sinjal ndalimi do të përdoret SIGRTMIN+3 nga e drejta.
E gjithë kjo lejon që systemd të funksionojë në një kontejner të mbyllur pa asnjë modifikim.
SHËNIM: systemd përpiqet të shkruajë në sistemin e dosjeve cgroup. Megjithatë, SELinux nga e drejta ndalon kontejnerët të bëjnë këtë. Për të lejuar shkrimin, aktivizoni parametrin logjik container_manage_cgroup:
setsebool -P container_manage_cgroup true
Tani shikoni si duket Dockerfile për të nisur systemd në kontejner duke përdorur Podman:
# cat Dockerfile
FROM fedora
RUN dnf -y install httpd; dnf clean all; systemctl enable httpd
EXPOSE 80
CMD [ "/sbin/init" ]
Kjo është gjithçka.
Tani po ndërtojmë kontejnerin:
# podman build -t systemd .
Tregoni SELinux që të lejojë systemd të modifikojë konfigurimin e Cgroups:
# setsebool -P container_manage_cgroup true
Shumë, për fat të keq, e harrojnë këtë hap. Fatmirësisht, mjafton ta bësh vetëm një herë dhe konfigurimi ruhet pas rindizjes së sistemit.
Tani thjesht e nisim kontejnerin:
# 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.
Të gjitha, shërbimi u nis dhe funksionon:
$ curl localhost
<html xml_lang="en" lang="en">
…
</html>
SHËNIM: Mos provo ta përsërisësh këtë në Docker! Aty ende nevojiten disa hile për të nxjerrë këtë lloj kontejneri përmes demonit. (Kujtohen fusha dhe paketa të tjera që duhen për ta bërë këtë të punojë pa probleme në Docker, ose do të duhet ta nisim në një kontejner me privilegje. Detajet shiko në .)
Një çift gjërash të tjera të shkëlqyera mbi Podman dhe systemd
Podman funksionon më mirë se Docker në skedarët e njësive systemd
Nëse kontejnerët duhet të nisen gjatë ngarkimit të sistemit, mund të vendosni thjesht komandat përkatëse të Podman në skedarin e njësisë systemd, i cili do të nisë shërbimin dhe do ta monitorojë. Podman përdor modelin standart të fork-exec. Në mënyrë tjetër, proceset e kontejnerit janë fëmijë të procesit të Podman, kështu që systemd mund t'i monitorojë lehtësisht.
Docker përdor modelin klient-server, dhe komandat CLI të Docker gjithashtu mund të vendosen drejtpërdrejt në skedarin e njësisë. Megjithatë, pasi klienti Docker lidhet me demonin Docker, ai (klienti) bëhet thjesht një tjetër proces që përpunon stdin dhe stdout. Nga ana tjetër, systemd nuk ka asnjë ide për lidhjen midis klientit Docker dhe kontejnerit që funksionon nën menaxhimin e demonit Docker, dhe prandaj në këtë model systemd nuk mund të monitorojë shërbimin.
Aktivizimi i systemd përmes socketit
Podman e menaxhon saktësisht aktivizimin përmes socketit. Duke qenë se Podman përdor modelin fork-exec, ai mund të kalojë socketin në proceset e tij fëmijë të kontejnerit. Docker nuk e bën këtë, sepse përdor modelin klient-server.
Shërbimi varlink, i cili Podman përdor për të krijuar ndërveprime me klientët e largët me konteinerët, në të vërtetë aktivizohet përmes një socket-i. Paketa cockpit-podman, e shkruar në Node.js dhe pjesë e projektit cockpit, lejon njerëzit të ndërveprojnë me konteinerët Podman përmes një ndërfaqeje në internet. Demon web-i, mbi të cilin funksionon cockpit-podman, dërgon mesazhe në socket-in varlink, i cili dëgjohet nga systemd. Më pas, systemd aktivizon programin Podman për të marrë mesazhet dhe fillon menaxhimin e konteinerëve. Aktivizimi i systemd përmes socket-it lejon të shmanget nevoja për një demon që punon vazhdimisht duke realizuar API të largët.
Përveç kësaj, ne po zhvillojmë një klient tjetër për Podman, të quajtur podman-remote, i cili implementon të njëjtin CLI të Podman, por thërret varlink për të nisur konteinerët. Podman-remote mund të funksionojë mbi seancat SSH, duke mundësuar ndërveprime të sigurta me konteinerët në makina të ndryshme. Me kalimin e kohës, ne planifikojmë të aktivizojmë podman-remote për të mbështetur MacOS dhe Windows përveç Linux-it, në mënyrë që zhvilluesit në këto platforma të mund të ekzekutojnë një makinë virtuale Linux me Podman varlink në funksionim dhe të kenë një ndjenjë të plotë që konteinerët po ekzekutohen në makinën lokale.
SD_NOTIFY
Systemd lejon të vonohet nisja e shërbimeve ndihmëse deri sa të fillojë shërbimi i konteinerizuar që iu nevojitet. Podman mund të kalojë socket-in SD_NOTIFY në shërbimin e konteinerizuar, në mënyrë që ky shërbim të njoftojë systemd për gatishmërinë e tij për të punuar. Edhe një herë, Docker, duke përdorur modelin klient-server, nuk e bën këtë.
Planet
Ne planifikojmë të shtojmë komandën podman generate systemd CONTAINERID, e cila do të gjenerojë një skedë unit për systemd për të menaxhuar një konteiner të caktuar. Kjo duhet të funksionojë si në modet root, ashtu edhe në ato rootless për konteinerët e pa privilegjuar. Ne kemi parë madje një kërkesë për të krijuar një ambient ekzekutimi të përputhshëm me OCI për systemd-nspawn.
Përfundim
Nisja e systemd në një konteiner është një nevojë e qartë. Dhe falë Podman, ne përfundimisht kemi një ambient ekzekutimi konteinerësh që nuk është në konflikt me systemd, por e lehtëson përdorimin e tij.
Burimi: habr.com
