Systemdni konteynerda ishga tushirish

Biz konteynerlarda systemd dan foydalanish mavzusini uzoq vaqtdan beri kuzatib kelmoqdamiz. 2014 yilda bizning xavfsizlik muhandisimiz Daniel Uolsh maqola yozgan edi Docker konteynerida tizimni ishga tushirish, va bir necha yil o'tgach - boshqa, deb nomlangan Imtiyozli bo'lmagan konteynerda tizimni ishga tushirish, unda u vaziyat unchalik yaxshilanmaganini aytdi. Xususan, u "afsuski, hatto ikki yil o'tgach, agar siz "Docker system" ni Google orqali qidirsangiz, birinchi navbatda uning o'sha eski maqolasi chiqadi. Demak, biror narsani o'zgartirish vaqti keldi." Bundan tashqari, biz allaqachon gaplashdik Docker va systemd ishlab chiquvchilari o'rtasidagi ziddiyat.

Systemdni konteynerda ishga tushirish

Ushbu maqolada biz vaqt o'tishi bilan nima o'zgarganini va Podman bu masalada bizga qanday yordam berishi mumkinligini ko'rsatamiz.

Systemd-ni konteyner ichida ishga tushirishning ko'plab sabablari bor, masalan:

  1. Multiservisli konteynerlar - ko'p odamlar o'zlarining multixizmat dasturlarini virtual mashinalardan olib tashlashni va ularni konteynerlarda ishga tushirishni xohlashadi. Albatta, bunday ilovalarni mikroservislarga ajratish yaxshiroq bo'lar edi, lekin buni qanday qilishni hamma ham bilmaydi yoki shunchaki vaqt yo'q. Shuning uchun, birlik fayllaridan systemd tomonidan ishga tushirilgan xizmatlar kabi ilovalarni ishga tushirish juda mantiqiy.
  2. Tizimli birlik fayllari - Konteynerlar ichida ishlaydigan ilovalarning aksariyati avval virtual yoki jismoniy mashinalarda ishlagan koddan tuzilgan. Ushbu ilovalar ushbu ilovalar uchun yozilgan va ularni qanday ishga tushirish kerakligini tushunadigan birlik fayliga ega. Shunday qilib, o'zingizning boshlang'ich xizmatingizni buzishdan ko'ra, qo'llab-quvvatlanadigan usullardan foydalangan holda xizmatlarni boshlash yaxshiroqdir.
  3. Systemd - bu jarayon menejeri. U xizmatlarni boshqaradi (o'chiradi, xizmatlarni qayta ishga tushiradi yoki zombi jarayonlarini o'ldiradi) boshqa vositalarga qaraganda yaxshiroq.

Ya'ni, konteynerlarda systemd ishlamaslik uchun ko'p sabablar bor. Asosiysi, systemd/journald konteynerlar va shunga o'xshash vositalarning chiqishini nazorat qiladi Kubernetes yoki openshift konteynerlar jurnalni to'g'ridan-to'g'ri stdout va stderr-ga yozishini kuting. Shuning uchun, agar siz yuqorida aytib o'tilganlar kabi orkestratsiya vositalari orqali konteynerlarni boshqarmoqchi bo'lsangiz, tizimga asoslangan konteynerlardan foydalanishni jiddiy o'ylab ko'rishingiz kerak. Bundan tashqari, Docker va Moby ishlab chiquvchilari ko'pincha konteynerlarda systemd dan foydalanishga keskin qarshilik ko'rsatishadi.

Podmanning kelishi

Vaziyat nihoyat oldinga siljiganini xabar qilishdan xursandmiz. Red Hat-da konteynerlarni ishlatish uchun mas'ul bo'lgan jamoa rivojlanishga qaror qildi o'zingizning konteyner dvigatelingiz. U ism oldi podman va Docker bilan bir xil buyruq qatori interfeysini (CLI) taklif qiladi. Va deyarli barcha Docker buyruqlari Podman'da xuddi shu tarzda ishlatilishi mumkin. Biz tez-tez seminarlar o'tkazamiz, ular hozir deb ataladi Dockerni Podmanga o'zgartirish, va birinchi slayd yozishni talab qiladi: taxallus docker=podman.

Ko'pchilik buni qiladi.

Mening Podman va men tizimga asoslangan konteynerlarga qarshi emasmiz. Axir, Systemd eng ko'p qo'llaniladigan Linux init quyi tizimi bo'lib, uning konteynerlarda to'g'ri ishlashiga yo'l qo'ymaslik minglab odamlarning konteynerlarni ishlatishga odatlanganligiga e'tibor bermaslikni anglatadi.

Podman tizimning konteynerda to'g'ri ishlashi uchun nima qilish kerakligini biladi. Bu /run va /tmp ga tmpfs o'rnatish kabi narsalarga muhtoj. U "konteynerlangan" muhitni yoqishni yaxshi ko'radi va guruh katalogining o'z qismiga va /var/log/journald jildiga yozish ruxsatlarini kutadi.

Birinchi buyruq init yoki systemd bo'lgan konteynerni ishga tushirganingizda, Podman tizimning muammosiz ishga tushishini ta'minlash uchun tmpfs va Cgroups-ni avtomatik ravishda sozlaydi. Ushbu avtomatik ishga tushirish rejimini bloklash uchun --systemd=false opsiyasidan foydalaning. E'tibor bering, Podman faqat systemd yoki init buyrug'ini ishga tushirish kerakligini ko'rganda systemd rejimidan foydalanadi.

Qo'llanmadan parcha:

odam podman yuguradi
...

–systemd=true|false

Konteynerni systemd rejimida ishga tushirish. Sukut bo'yicha yoqilgan.

Agar siz konteyner ichida systemd yoki init buyrug'ini ishlatsangiz, Podman quyidagi kataloglarda tmpfs ulanish nuqtalarini sozlaydi:

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

Shuningdek, standart to'xtash signali SIGRTMIN+3 bo'ladi.

Bularning barchasi systemd ga hech qanday o'zgartirishlarsiz yopiq konteynerda ishlash imkonini beradi.

QAYD: systemd cgroup fayl tizimiga yozishga harakat qiladi. Biroq, SELinux konteynerlarga sukut bo'yicha buni amalga oshirishga yo'l qo'ymaydi. Yozishni yoqish uchun container_manage_cgroup boolean parametrini yoqing:

setsebool -P container_manage_cgroup rost

Endi Podman yordamida konteynerda systemd ishga tushirish uchun Dockerfile qanday ko'rinishini ko'rib chiqing:

# cat Dockerfile

FROM fedora

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

EXPOSE 80

CMD [ "/sbin/init" ]

Hammasi shu.

Endi biz konteynerni yig'amiz:

# podman build -t systemd .

Biz SELinux-ga systemd-ga Cgroups konfiguratsiyasini o'zgartirishga ruxsat berishini aytamiz:

# setsebool -P container_manage_cgroup true

Aytgancha, ko'p odamlar bu qadamni unutishadi. Yaxshiyamki, bu faqat bir marta bajarilishi kerak va tizimni qayta ishga tushirgandan so'ng sozlama saqlanadi.

Endi biz konteynerni ishga tushiramiz:

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

Hammasi shu, xizmat ishlamoqda:

$ curl localhost

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

…

</html>

QAYD: Buni Docker-da sinab ko'rmang! U erda siz hali ham daemon orqali bunday idishlarni ishga tushirish uchun daf bilan raqsga tushishingiz kerak. (Bularning barchasi Docker-da muammosiz ishlashi uchun qo'shimcha maydonlar va paketlar talab qilinadi yoki u imtiyozli konteynerda ishga tushirilishi kerak. Tafsilotlar uchun qarang. maqola.)

Podman va systemd haqida yana bir nechta ajoyib narsalar

Podman tizim birligi fayllarida Dockerga qaraganda yaxshiroq ishlaydi

Agar tizim yuklanganda konteynerlarni ishga tushirish kerak bo'lsa, u holda siz xizmatni ishga tushiradigan va uni kuzatib boradigan tizim birligi fayliga tegishli Podman buyruqlarini kiritishingiz mumkin. Podman standart fork-exec modelidan foydalanadi. Boshqacha qilib aytganda, konteyner jarayonlari Podman jarayonining bolalaridir, shuning uchun systemd ularni osongina kuzatishi mumkin.

Docker mijoz-server modelidan foydalanadi va Docker CLI buyruqlari ham to'g'ridan-to'g'ri birlik fayliga joylashtirilishi mumkin. Biroq, Docker mijozi Docker demoniga ulangandan so'ng, u (mijoz) stdin va stdoutni qayta ishlash jarayoniga aylanadi. O'z navbatida, systemd Docker mijozi va Docker demoni nazorati ostida ishlaydigan konteyner o'rtasidagi aloqa haqida hech qanday tasavvurga ega emas va shuning uchun ushbu model doirasida systemd xizmatni tubdan kuzatib bora olmaydi.

Soket orqali tizimni faollashtirish

Podman rozetka orqali faollashtirishni to'g'ri boshqaradi. Podman fork-exec modelidan foydalanganligi sababli, u rozetkani o'zining pastki konteyner jarayonlariga yo'naltirishi mumkin. Docker buni qila olmaydi, chunki u mijoz-server modelidan foydalanadi.

Podman masofaviy mijozlar bilan konteynerlarga bog'lanish uchun foydalanadigan varlink xizmati aslida rozetka orqali faollashtirilgan. Node.js-da yozilgan va kokpit loyihasining bir qismi bo'lgan kokpit-podman paketi odamlarga veb-interfeys orqali Podman konteynerlari bilan muloqot qilish imkonini beradi. Kokpit-podman bilan ishlaydigan veb-demon xabarlarni tizim tinglaydigan varlink rozetkasiga yuboradi. Keyin Systemd xabarlarni qabul qilish va konteynerlarni boshqarishni boshlash uchun Podman dasturini faollashtiradi. Systemd-ni rozetka orqali faollashtirish masofaviy API-larni amalga oshirishda doimiy ishlaydigan demonga ehtiyojni yo'q qiladi.

Bundan tashqari, biz podman-remote deb nomlangan boshqa Podman mijozini ishlab chiqmoqdamiz, u bir xil Podman CLI-ni amalga oshiradi, lekin konteynerlarni ishga tushirish uchun varlinkni chaqiradi. Podman-remote SSH seanslari ustida ishlashi mumkin, bu sizga turli xil mashinalardagi konteynerlar bilan xavfsiz aloqa qilish imkonini beradi. Vaqt oβ€˜tishi bilan biz Linux bilan bir qatorda MacOS va Windows-ni qoβ€˜llab-quvvatlash uchun podman-remote-ni yoqishni rejalashtirmoqdamiz, shunda ushbu platformalarda ishlab chiquvchilar Podman varlink ishlayotgan Linux virtual mashinasini ishga tushirishlari va konteynerlar mahalliy mashinada ishlayotganidan toβ€˜liq tajribaga ega boβ€˜lishlari mumkin.

SD_NOTIFY

Systemd yordamchi xizmatlarni ishga tushirishni ular talab qiladigan konteynerli xizmat boshlangunga qadar kechiktirishga imkon beradi. Podman SD_NOTIFY rozetkasini konteynerli xizmatga yo'naltirishi mumkin, shunda xizmat tizimga ishlashga tayyorligi haqida xabar beradi. Va yana, mijoz-server modelidan foydalanadigan Docker buni qila olmaydi.

Rejalarda

Biz podman generator systemd CONTAINERID buyrug'ini qo'shishni rejalashtirmoqdamiz, bu esa belgilangan konteynerni boshqarish uchun tizimli birlik faylini yaratadi. Bu imtiyozsiz konteynerlar uchun ham ildiz, ham ildizsiz rejimlarda ishlashi kerak. Biz hatto OCI-mos keladigan systemd-nspawn ish vaqti uchun so'rovni ko'rdik.

xulosa

Systemd-ni konteynerda ishga tushirish tushunarli ehtiyojdir. Va Podman tufayli bizda nihoyat systemd bilan zid kelmaydigan, lekin undan foydalanishni osonlashtiradigan konteyner ish vaqti mavjud.

Manba: www.habr.com

a Izoh qo'shish