Biz uzun müddətdir systemd-in konteynerlərdə istifadəsi mövzusu ilə maraqlanırıq. 2014-cü ildə təhlükəsizlik mühəndisimiz Daniel Walsh məqalə yazmışdı , bir neçə il sonra isə adlandırdığı digər bir məqalə yazmışdı , burada o, vəziyyətin çox da yaxşılaşmadığını qeyd etdi. Xüsusilə, o, "təəssüf ki, iki ildən sonra, əgər "Docker system" axtarsanız, ilk olaraq həmin köhnə məqalə ortaya çıxır. Deməli, bir şey etmək zamanı gəldi" yazmışdı. Üstəlik, biz daha əvvəl .
danışmışıq. Bu məqalədə biz, son dövrlərdə nə baş verdiyini və Bu məsələdə Podman-ın bizə necə kömək edə biləcəyini göstərəcəyik.
Systemd-i konteynerdə işlətməyin bir çox səbəbi var, məsələn:
- Çoxservisli konteynerlər – bir çox insan çoxservisli tətbiqlərini virtual maşınlardan çıxarıb konteynerlərdə işlətmək istəyir. Bunun üçün əlbəttə ki, bu cür tətbiqləri mikrosistemlərə parçalamaq daha yaxşıdır, lakin hamı bunu hələ bacarmır və ya sadəcə vaxtı yoxdur. Ona görə də bu cür tətbiqləri systemd vasitəsilə unit fayllarından işə salmaq tamamilə mənalıdır.
- Systemd unit faylları – konteyner daxilində çalışan əksər tətbiqlər, əvvəlcə virtual və ya fiziki maşınlarda işlədilən kodlardan ibarətdir. Bu tətbiqlərin hər birinin özləri üçün yazılmış unit faylı var və bu fayl onları necə işə salmağı başa düşür. Beləliklə, servisleri desteklenen metodlardan istifadə edərək çalışdırmaq daha yaxşıdır, öz init xidmətinizi sındırmadan.
- Systemd – proseslərin idarəedicisidir. O, servisləri idarə edir (işləməyini dayandırır, servisləri yenidən işə salır və ya zombilər proseslərini öldürür) və bu işi hər hansı digər alətdən daha yaxşı yerinə yetirir.
Ancaq konteynerlərdə systemd işlətməmək üçün də bir çox səbəb var. Əsas səbəb isə odur ki, systemd/journald konteynerlərin çıxışını idarə edir, amma və böyük ölçüdə hansısa alətlər konteynerlərin logları birbaşa stdout və stderr-ə yazılmasını gözləyirlər. Ona görə də əgər you konteynerləri yuxarıda qeyd olunan orkestrasiya vasitələri ilə idarə etməyə niyyətiniz varsa, systemd ilə bazalı konteynerlərdən istifadə məsələsini ciddi şəkildə düşünməlisiniz. Üstəlik, Docker və Moby inkişaf etdiriciləri tez-tez konteynerlərdə systemd istifadəsinə qarşı olduqca sərt iddialarda bulunmuşlar.
Podman'nın gəlişi
Xoş xəbərləri sizinlə paylaşmaqdan məmnunluq duyuruq ki, vəziyyət nəhayət ki, durğunluqdan çıxdı. Red Hat komandası konteynerlərin başlatılması ilə bağlı öz inkişaf etdirmək qərarına gəldi. O, adlandırıldı və Docker-inki ilə eyni komanda xətti (CLI) interfeysi təqdim edir. Və demək olar ki, Docker-ın bütün əmrləri eyni şəkildə Podman-da da istifadə oluna bilər. Biz tez-tez adlı seminarlar keçiririk və ilk slayd məsləhət görür: alias docker=podman.
Bir çoxları bu cür edir.
Biz Podman'ımızla systemd əsaslı konteynerlərə tamamilə etiraz etmirik. Axı Systemd, Linux'un init sistemləri arasında daha çox istifadə olunur və onun konteynerlərdə düzgün işləməsinə mane olmaq, minlərlə insanın konteynerləri başlatma üsulunu görməzdən gəlmək deməkdir.
Podman, systemd'nin konteynerdə düzgün işləməsi üçün nə etməli olduğunu bilir. Bunun üçün /run və /tmp-də tmpfs montajı kimi şeylərə ehtiyacı var. O, "konteyner" mühitinin aktiv olmasını istəyir və cgroup kataloqunun öz hissəsinə yazma icazəsini gözləyir, həmçinin /var/log/journald qovluğuna yazma icazəsi tələb edir.
Konteyner işə salındıqda, ilk əmrin init və ya systemd olduğu halda, Podman avtomatik olaraq tmpfs və Cgroups'u systemd'nin problemsiz işə düşməsi üçün konfiqurasiya edir. Bu avtomatik işə salma rejimini bloklamaq üçün —systemd=false seçimi istifadə olunur. Yalnız systemd və ya init əmri icra ediləcəyini gördükdə Podman systemd rejimindən istifadə edir.
İşte təlimatdan bir excerpt:
man podman run
…–systemd=true|false
Konteyneri systemd rejimində işə salır. Standart olaraq aktivdir.
Konteynerdə systemd və ya init əmri icra olunursa, Podman aşağıdakı kataloqlarda tmpfs montaj nöqtələrini tənzimləyəcək:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
Həmçinin, dayandırma siqnalı olaraq standart olaraq SIGRTMIN+3 istifadə olunacaq.
Bütün bunlar systemd'nin dəyişməz konteynerdə işləməsinə imkan tanıyır.
QEYD: systemd cgroup fayl sisteminə yazmağa çalışır. Lakin SELinux standart olaraq konteynerlərin bunu etməsinə icazə vermir. Yazma icazəsini vermək üçün container_manage_cgroup loqik parametrini aktiv edin:
setsebool -P container_manage_cgroup true
İndi Podman istifadə edərək systemd-ni konteynerdə işə salmaq üçün Dockerfile necə görünür, baxaq:
# cat Dockerfile
FROM fedora
RUN dnf -y install httpd; dnf clean all; systemctl enable httpd
EXPOSE 80
CMD [ "/sbin/init" ]
Bütün bunlar bitti.
İndi konteyneri yığırıq:
# podman build -t systemd .
SELinux'a systemd'ye Cgroups konfiqurasiyasını dəyişməyə icazə verməyi söyləyirik:
# setsebool -P container_manage_cgroup true
Bir çoxları bu addımı unudur. Xoşbəxtlikdən, bunu sadəcə bir dəfə etmək kifayətdir və konfiqurasiya sistem yenidən başladıldıqdan sonra saxlanılır.
İndi sadəcə konteyneri işə salırıq:
# 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.
Hər şey, xidmət başladı və işləyir:
$ curl localhost
<html xml_lang="en" lang="en">
…
</html>
QEYD: Bunu Docker'da etməyə çalışmayın! Orada bu cür konteynerləri demonla işə salmaq üçün hələ də çətinliklər var. (Bütün bunların Docker'da problemsiz işləməsi üçün əlavə sahələr və paketlər lazım ola bilər, ya da bunu imtiyazlı konteynerdə işə salmaq lazım olacaq. Ətraflı məlumat üçün baxın .)
Podman və systemd haqqında bir neçə maraqlı şey
Podman, systemd unit fayllarında Docker'dan daha yaxşı işləyir
Əgər konteynerləri sistem yüklənərkən işə salmaq lazımdırsa, Podman'ı uyğun əmrləri systemd unit faylına əlavə edərək, o, xidməti işə salacaq və onu izləyəcək. Podman icra edərkən standart fork-exec modelini istifadə edir. Başqa sözlə, konteyner prosesləri Podman’ın prosesi ilə övlad olur, buna görə də systemd onları asanlıqla izləyə bilər.
Docker müştəri-server modelini istifadə edir və Docker CLI komandaları birbaşa unit faylında yerləşdirilə bilər. Lakin Docker müştərisi Docker demonuna qoşulduqdan sonra, o (müştəri) sadəcə stdin və stdout-u idarə edən bir proses halına gəlir. Öz növbəsində, systemd Docker müştəri ilə Docker demonunun idarə etdiyi konteyner arasındakı əlaqə haqqında heç bir məlumat sahibi deyil, buna görə də bu model çərçivəsində systemd prinsip etibarilə xidməti izləyə bilmir.
systemd-nin socket vasitəsilə aktivləşdirilməsi
Podman socket vasitəsilə aktivləşdirməni düzgün yerinə yetirir. Podman fork-exec modelindən istifadə etdiyi üçün, o, socket-i öz alt konteyner proseslərinə keçirdə bilir. Docker isə müştəri-server modelindən istifadə etdiyindən belə etməyi bacarmır.
Podman-ın uzaq müştərilərlə konteynerlər arasındakı əlaqə üçün istifadə etdiyi varlink xidməti əslində socket vasitəsilə aktivləşdirilir. Node.js-də yazılan cockpit-podman paketi, cockpit layihəsinin bir hissəsi olan, Podman konteynerləri ilə veb interfeysi vasitəsilə qarşılıqlı əlaqə yaratmağa imkan tanıyır. Cockpit-podman-ın çalışdığı veb demon, systemd tərəfindən dinlənilən varlink socket-ə mesajlar göndərir. Daha sonra systemd Podman proqramını mesajları qəbul etmək və konteynerləri idarə etməyə başlamaq üçün aktivləşdirir. Socket vasitəsilə systemd-nin aktivləşdirilməsi, uzaq API-nin həyata keçirilməsi zamanı daima işləyən bir demon olmadan mümkündür.
Bundan əlavə, Podman üçün podman-remote adlı bir müştəri də hazırlanır ki, bu da eyni Podman CLI-ni həyata keçirir, lakin konteynerləri işə salmaq üçün varlink-i çağırır. Podman-remote SSH sessiyaları üzərində işləyə bilir, bu da müxtəlif maşınlar üzərində konteynerlərlə təhlükəsiz qarşılıqlı əlaqəyə imkan tanıyır. Zamanla podman-remote-ni MacOS və Windows ilə birlikdə Linux dəstəyinə inteqrasiya etməyi planlaşdırırıq ki, bu platformalarda inkişaf etdiricilər Podman varlink ilə işləyən Linux virtual maşınını işə sala bilsinlər və konteynerlərin yerli maşında işlədiyini tam hiss etsinlər.
SD_NOTIFY
Systemd lazımsız xidmətlərin işə salınmasını, onların tələb etdiyi konteynerleşdirilmiş xidmət işə salındıqda yerinə yetirmək üçün gecikdirməyə imkan tanıyır. Podman konteynerleşdirilmiş xidmətə SD_NOTIFY socket-i təqdim edərək, bu xidmətin systemd-yə işləməyə hazır olduğunu bildirməyə imkan verir. Yenə də Docker, müştəri-server modelini istifadə etdiyi üçün bununla bağlı heç bir işi bacarmır.
Planlar
Biz podman generate systemd CONTAINERID komandasını əlavə etməyi planlaşdırırıq ki, bu da xüsusi bir konteyneri idarə etmək üçün systemd unit faylını yaradır. Bu, həm root-, həm də rootless rejimlərdə qeyri-ixtiyari konteynerlər üçün işləməlidir. Hətta biz OCI uyğun systemd-nspawn iş mühitinin yaradılması ilə bağlı bir tələb görmüşdük.
Nəticə
Containerdə systemd-nin işlədilməsi tamamilə aydındır. Podman sayəsində, sonunda, systemd ilə müxalifət etməyən və onu rahatlıqla istifadə etməyə imkan verən konteyner iş mühiti var.
Mənbə: habr.com
