Eseguite systemd in un containeru

Avemu seguitu u tema di utilizà systemd in cuntenituri per un bellu pezzu. Torna in 2014, u nostru ingegnere di sicurità Daniel Walsh hà scrittu un articulu Running systemd in un Docker Container, è un paru d'anni dopu - un altru, chì era chjamatu Running systemd in un containeru micca privilegiatu, in quale hà dichjaratu chì a situazione ùn avia micca migliuratu assai. In particulare, hà scrittu chì "sfurtunatamente, ancu dui anni dopu, se google "sistema Docker", a prima cosa chì vene hè u so vechju articulu. Allora hè ora di cambià qualcosa ". Inoltre, avemu digià parlatu cunflittu trà Docker è sviluppatori systemd.

Eseguite systemd in un containeru

In questu articulu vi mustraremu ciò chì hà cambiatu cù u tempu è cumu Podman pò aiutà in questa materia.

Ci hè parechje motivi per eseguisce systemd in un containeru, cum'è:

  1. Containers multiservizi - assai persone volenu tirà e so applicazioni multi-servizi fora di e macchine virtuali è eseguite in cuntenituri. Saria megliu, sicuru, per rompe tali applicazioni in microservizi, ma micca tutti ùn sanu micca cumu fà questu o simpricimenti ùn anu micca u tempu. Dunque, eseguisce tali applicazioni cum'è servizii lanciati da systemd da i schedari unità hè sensu perfettu.
  2. File di unità Systemd - A maiò parte di l'applicazioni chì funzionanu in i cuntenituri sò custruiti da codice chì prima funzionava in macchine virtuali o fisiche. Queste applicazioni anu un schedariu unità chì hè statu scrittu per queste applicazioni è capisce cumu si deve esse lanciatu. Allora hè sempre megliu per inizià i servizii cù metudi supportati, invece di pirate u vostru propiu serviziu init.
  3. Systemd hè un gestore di prucessu. Gestisce i servizii (spegne, riavvia i servizii, o uccide i prucessi di zombie) megliu cà qualsiasi altru strumentu.

Dice questu, ci sò parechje ragioni per ùn eseguisce systemd in cuntenituri. U principale hè chì systemd/journald cuntrolla l'output di cuntenituri, è arnesi cum'è Kubernetes o turnu apertu aspettate chì i cuntenituri scrivenu log direttamente à stdout è stderr. Dunque, sè vo site per gestisce i cuntenituri per mezu di strumenti d'orchestrazione cum'è quelli citati sopra, duvete cunsiderà seriamente l'usu di cuntenituri basati in systemd. Inoltre, i sviluppatori di Docker è Moby sò spessu opposti fermamente à aduprà systemd in cuntenituri.

A Venuta di Podman

Semu felici di informà chì a situazione hè finalmente avanzata. A squadra rispunsevuli di gestisce i cuntenituri in Red Hat hà decisu di sviluppà u vostru propiu mutore di containeru. Hà avutu un nome podman è offre a stessa interfaccia di linea di cumanda (CLI) cum'è Docker. È quasi tutti i cumandamenti Docker ponu esse usatu in Podman in u listessu modu. Avemu spessu cunducendu seminarii, chì sò avà chjamati Cambia Docker à Podman, è a prima diapositiva chjama à scrive: alias docker = podman.

Parechje persone facenu questu.

U mo Podman è eiu ùn sò in nisun modu contr'à i cuntenituri basati in systemd. Dopu tuttu, Systemd hè u subsistema init Linux più comunmente utilizatu, è ùn permettenu micca di travaglià bè in cuntenituri significa ignurà cumu migghiara di persone sò abituati à correre cuntenituri.

Podman sapi ciò chì deve fà per fà u sistema di travaglià bè in un containeru. Hè bisognu di cose cum'è a muntagna di tmpfs in /run è /tmp. Li piace à avè l'ambiente "containerized" attivatu è aspetta permessi di scrittura à a so parte di u cartulare cgroup è à u cartulare /var/log/journald.

Quandu avete principiatu un containeru in quale u primu cumandamentu hè init o systemd, Podman cunfigura automaticamente tmpfs è Cgroups per assicurà chì systemd principia senza prublemi. Per bluccà stu modu di lanciamentu automaticu, utilizate l'opzione --systemd=false. Per piacè nutate chì Podman usa solu u modu systemd quandu vede chì hà bisognu di eseguisce un cumandamentu systemd o init.

Eccu un estratto da u manuale:

omu podman corre
...

–systemd=true|false

Eseguisce un containeru in modu systemd. Abilitatu per difettu.

Se eseguite un cumandimu systemd o init in un containeru, Podman cunfigurà i punti di muntagna tmpfs in i seguenti cartulari:

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

Ancu u signale di stop predeterminatu serà SIGRTMIN + 3.

Tuttu chistu permette à systemd di eseguisce in un containeru chjusu senza alcuna mudificazione.

NOTA: systemd prova di scrive à u sistema di filesystem cgroup. Tuttavia, SELinux impedisce à i cuntenituri di fà questu per automaticamente. Per attivà a scrittura, attivate u paràmetru boolean container_manage_cgroup:

setsebool -P container_manage_cgroup true

Avà fighjate ciò chì u Dockerfile s'assumiglia per eseguisce systemd in un containeru cù Podman:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Eccu tuttu.

Avà assemblemu u cuntinuu:

# podman build -t systemd .

Dicemu à SELinux per permette à systemd di mudificà a cunfigurazione di Cgroups:

# setsebool -P container_manage_cgroup true

In modu, assai persone si scurdanu di stu passu. Fortunatamente, questu solu deve esse fattu una volta è u paràmetru hè salvatu dopu à rebooting u sistema.

Avà avemu principiatu solu u cuntinuu:

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

Eccu, u serviziu hè in funzione:

$ curl localhost

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

…

</html>

NOTA: Ùn pruvate micca questu nantu à Docker! Ci hè sempre bisognu di ballà cù un tamburinu per lancià stu tipu di cuntenituri attraversu u demoniu. (Campi supplementari è pacchetti seranu richiesti per fà tuttu ciò chì travaglia senza saldatura in Docker, o duverà esse eseguitu in un containeru privilegiatu. Per i dettagli, vede articulu.)

Un paru di cose più interessanti nantu à Podman è systemd

Podman funziona megliu cà Docker in i schedari di unità systemd

Se i cuntenituri anu da esse cuminciatu quandu u sistema di stivali, pudete simpricimenti inserisce i cumandamenti Podman appropritatu in u schedariu di unità systemd, chì hà da inizià u serviziu è monitorà. Podman usa u mudellu fork-exec standard. In altre parolle, i prucessi di cuntainer sò figlioli di u prucessu Podman, cusì systemd pò facilmente monitorà.

Docker usa un mudellu cliente-servitore, è i cumandamenti CLI di Docker ponu ancu esse posti direttamente in un schedariu di unità. Tuttavia, una volta chì u cliente Docker si cunnetta à u daemon Docker, (u cliente) diventa solu un altru prucessu di processazione stdin è stdout. À u turnu, systemd ùn hà micca idea di a cunnessione trà u cliente Docker è u cuntinuu chì corre sottu u cuntrollu di u demoniu Docker, è per quessa, in questu mudellu, systemd fundamentalmente ùn pò micca monitorà u serviziu.

Attivà systemd via socket

Podman gestisce correttamente l'attivazione via socket. Perchè Podman usa u mudellu fork-exec, pò trasmette u socket à i so prucessi di cuntainer di u zitellu. Docker ùn pò micca fà questu perchè usa un mudellu cliente-servitore.

U serviziu varlink chì Podman usa per cumunicà cù i clienti remoti à i cuntenituri hè in realtà attivatu via un socket. U pacchettu cockpit-podman, scrittu in Node.js è parte di u prughjettu di cockpit, permette à e persone di interagisce cù i cuntenituri Podman attraversu una interfaccia web. U daemon web in esecuzione cockpit-podman manda missaghji à un socket varlink chì systemd ascolta. Systemd dopu attiva u prugramma Podman per riceve missaghji è cumincià à gestisce i cuntenituri. L'attivazione di systemd sopra un socket elimina a necessità di un daemon in esecuzione constantemente durante l'implementazione di API remoti.

Inoltre, sviluppemu un altru cliente Podman chjamatu podman-remote, chì implementa a stessa Podman CLI ma chjama varlink per eseguisce cuntenituri. Podman-remote pò eseguisce nantu à e sessioni SSH, chì vi permettenu di interagisce in modu sicuru cù cuntenituri in diverse macchine. À u tempu, pensemu di attivà podman-remote per supportà MacOS è Windows à fiancu di Linux, in modu chì i sviluppatori nantu à queste piattaforme ponu eseguisce una macchina virtuale Linux cù Podman varlink in esecuzione è avè l'esperienza completa chì i cuntenituri funzionanu nantu à a macchina locale.

SD_NOTIFY

Systemd permette di differisce u lanciamentu di servizii ausiliari finu à chì u serviziu containerizatu chì necessitanu principia. Podman pò trasmette u socket SD_NOTIFY à u serviziu cuntainerizatu in modu chì u serviziu notifica à systemd chì hè prontu à operà. È dinò, Docker, chì usa un mudellu cliente-servitore, ùn pò micca fà questu.

In i piani

Avemu pensatu à aghjunghje u cumandamentu podman generate systemd CONTAINERID, chì generà un schedariu di unità systemd per gestisce un containeru specificu specificatu. Questu duverebbe travaglià in i modi radicali è senza radichi per i cuntenituri senza privilegi. Avemu ancu vistu una dumanda per un runtime systemd-nspawn compatible OCI.

cunchiusioni

Running systemd in un containeru hè un bisognu comprensibile. È grazie à Podman, avemu infine un runtime di cuntainer chì ùn hè micca cunflittu cù systemd, ma rende faciule d'utilizà.

Source: www.habr.com

Add a comment