Pokrenite systemd u kontejneru

Već duže vrijeme pratimo temu korištenja systemd-a u kontejnerima. Još 2014. godine naš sigurnosni inženjer Daniel Walsh napisao je članak Pokretanje systemd unutar Docker kontejnera, a par godina kasnije - još jedan, koji se zvao Pokretanje systemd-a u neprivilegovanom kontejneru, u kojem je naveo da se situacija nije mnogo popravila. Konkretno, napisao je da „nažalost, i dvije godine kasnije, ako proguglate „Docker sistem“, prvi iskoči isti njegov stari članak. Dakle, vrijeme je za promjenu." Osim toga, o tome smo već govorili sukob između Docker-a i systemd programera.

Pokrenite systemd u kontejneru

U ovom članku ćemo pokazati što se promijenilo od tada i kako nam Podman može pomoći u tom pitanju.

Postoji mnogo razloga za pokretanje systemd unutar kontejnera, kao što su:

  1. Multiservisni kontejneri – mnogi ljudi žele izvući svoje multi-servisne aplikacije iz virtuelnih mašina i pokrenuti ih u kontejnerima. Bilo bi bolje, naravno, takve aplikacije razbiti u mikroservise, ali još uvijek ne znaju svi kako to učiniti ili jednostavno nema vremena. Dakle, pokretanje ovih aplikacija kao usluga koje pokreće systemd iz jediničnih datoteka ima savršenog smisla.
  2. Systemd fajlovi jedinica - većina aplikacija koje se pokreću unutar kontejnera izgrađena je od koda koji je prethodno pokrenut na virtuelnim ili fizičkim mašinama. Ove aplikacije imaju jediničnu datoteku koja je napisana za ove aplikacije i razumije kako ih treba pokrenuti. Stoga je ipak bolje pokrenuti servise koristeći podržane metode nego hakirati vlastitu init uslugu.
  3. Systemd je menadžer procesa. Upravlja uslugama (isključuje, ponovo pokreće usluge ili ubija zombije) bolje od bilo kojeg drugog alata.

Imajući to u vidu, postoji mnogo razloga da ne pokrenete systemd u kontejnerima. Glavni je da systemd/journald kontroliše izlaz kontejnera i alata poput Kubernet ili openshift kontejneri očekuju da pišu dnevnike direktno u stdout i stderr. Dakle, ako ćete upravljati kontejnerima pomoću alata za orkestraciju poput onih iznad, onda morate ozbiljno razmisliti o korištenju kontejnera baziranih na systemd-u. Osim toga, Docker i Moby programeri su se često oštro protivili korištenju systemd-a u kontejnerima.

Podman dolazi

Sa zadovoljstvom možemo objaviti da je situacija konačno krenula naprijed. Tim odgovoran za upravljanje kontejnerima u Red Hatu odlučio je da se razvije vlastiti kontejnerski motor. Imao je ime podman i nudi isti interfejs komandne linije (CLI) kao Docker. I skoro sve Docker komande se mogu koristiti u Podmanu na isti način. Često održavamo seminare koji se sada zovu Promijenite Docker u Podman, a prvi slajd poziva na pisanje: alias docker=podman.

Mnogi ljudi upravo to rade.

Moj Podman i ja ni na koji način nismo protiv kontejnera baziranih na systemd-u. Na kraju krajeva, Systemd se češće koristi kao init podsistem Linuxa, a sprečavanje njegovog pravilnog rada u kontejnerima znači ignorisanje načina na koji su hiljade ljudi naviknute na pokretanje kontejnera.

Podman zna šta treba učiniti da bi systemd ispravno radio u kontejneru. Potrebne su joj stvari poput montiranja tmpfs-a na /run i /tmp. Ona voli da ima omogućeno "kontejnerizirano" okruženje i čeka dozvole za pisanje u svoj dio direktorija cgroup i u /var/log/journald folder.

Prilikom pokretanja kontejnera sa init ili systemd kao prvom komandom, Podman automatski konfiguriše tmpfs i Cgroups tako da se systemd neometano pokreće. Da biste onemogućili ovaj način automatskog pokretanja, koristite opciju --systemd=false. Imajte na umu da Podman koristi systemd mod samo kada vidi da treba pokrenuti naredbu systemd ili init.

Evo izvoda iz priručnika:

čovjek podman trči
...

–systemd=true|false

Pokretanje kontejnera u systemd modu. Omogućeno prema zadanim postavkama.

Ako se naredba systemd ili init izvodi unutar kontejnera, Podman će postaviti tmpfs tačke montiranja u sljedeće direktorije:

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

Također SIGRTMIN+3 će se koristiti kao zadani stop signal.

Sve ovo omogućava systemd-u da radi u zatvorenom kontejneru bez ikakvih modifikacija.

NAPOMENA: systemd pokušava da upiše u sistem datoteka cgroup. Međutim, SELinux sprečava kontejnere da to rade prema zadanim postavkama. Da dozvolite pisanje, omogućite logički parametar container_manage_cgroup:

setsebool -P container_manage_cgroup istina

Sada pogledajte kako izgleda Dockerfile za pokretanje systemd-a u kontejneru koristeći Podman:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

To je sve.

Sada sakupljamo kontejner:

# podman build -t systemd .

Recite SELinuxu da dozvoli systemd-u da modificira konfiguraciju Cgroups:

# setsebool -P container_manage_cgroup true

Mnogi, inače, zaborave na ovaj korak. Srećom, dovoljno je to učiniti samo jednom i postavka se čuva nakon ponovnog pokretanja sistema.

Sada samo pokrećemo kontejner:

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

To je to, servis je pokrenut i radi:

$ curl localhost

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

…

</html>

NAPOMENA: Ne pokušavajte ovo na Dockeru! Još uvijek treba plesati s tamburom da se ovakvim kontejnerima probije demon. (Biće potrebna dodatna polja i paketi da bi ovo funkcionisalo besprekorno u Dockeru, ili će se morati pokrenuti u privilegovanom kontejneru. Pogledajte detalje u članak.)

Još par cool stvari o Podmanu i systemd-u

Podman radi bolje od Dockera u sistemskim datotekama jedinica

Ako kontejnere treba pokrenuti pri pokretanju sistema, onda možete jednostavno umetnuti odgovarajuće Podman komande u systemd jediničnu datoteku, koja će pokrenuti servis i nadgledati ga. Podman koristi standardni fork-exec model. Drugim riječima, kontejnerski procesi su djeca Podman procesa, tako da ih systemd može lako pratiti.

Docker koristi klijent-server model, a Docker CLI komande se također mogu postaviti direktno u jediničnu datoteku. Međutim, nakon što se Docker klijent poveže sa Docker demonom, on (klijent) postaje samo još jedan proces koji rukuje stdin i stdout. Zauzvrat, systemd nema pojma o vezi između Docker klijenta i kontejnera koji pokreće Docker demon, pa stoga, unutar ovog modela, systemd u principu ne može nadgledati uslugu.

Aktiviranje systemd preko socketa

Podman ispravno rukuje aktivacijom utičnice. Budući da Podman koristi fork-exec model, može proslijediti soket svojim podređenim kontejnerskim procesima. Docker to ne može učiniti jer koristi klijent-server model.

Varlink usluga koju Podman koristi da omogući udaljenim klijentima da komuniciraju sa kontejnerima zapravo se poziva preko utičnice. Cockpit-podman paket, napisan u Node.js-u i dio projekta pilotske kabine, omogućava ljudima interakciju sa Podman kontejnerima putem web sučelja. Web daemon koji pokreće cockpit-podman šalje poruke na varlink socket koji systemd sluša. Systemd tada aktivira Podman program za primanje poruka i početak upravljanja kontejnerima. Aktiviranje systemd-a preko utičnice eliminira potrebu za konstantno pokrenutim demonom prilikom implementacije udaljenih API-ja.

Također razvijamo još jedan Podman klijent koji se zove podman-remote koji implementira isti Podman CLI ali poziva varlink za pokretanje kontejnera. Podman-remote može raditi na vrhu SSH sesija, omogućavajući vam sigurnu interakciju sa kontejnerima na različitim mašinama. Vremenom planiramo da koristimo podman-remote za podršku MacOS-a i Windows-a zajedno sa Linuxom, tako da programeri na tim platformama mogu pokrenuti Linux virtuelnu mašinu koja pokreće Podman varlink i imati potpuno iskustvo pokretanja kontejnera na lokalnom računaru.

SD_NOTIFY

Systemd vam omogućava da odgodite početak pomoćnih usluga dok se ne pokrene kontejnerska usluga koja im je potrebna. Podman može proslijediti SD_NOTIFY utičnicu na kontejnerski servis tako da usluga obavijesti systemd da je spremna za rad. I opet, Docker, koji koristi model klijent-server, ne zna kako.

U planovima

Planiramo da dodamo naredbu podman generate systemd CONTAINERID koja će generirati systemd jediničnu datoteku za upravljanje datim kontejnerom. Ovo bi trebalo da radi i u root iu režimu bez root-a za neprivilegovane kontejnere. Čak smo vidjeli zahtjev za OCI usaglašenim systemd-nspawn runtime.

zaključak

Pokretanje systemd-a u kontejneru je razumljiva potreba. I zahvaljujući Podmanu, konačno imamo runtime kontejnera koji ne suprotstavlja systemd, ali ga čini lakim za korištenje.

izvor: www.habr.com

Dodajte komentar