Kami telah mengikuti topik menggunakan systemd dalam bekas untuk masa yang lama. Pada tahun 2014, jurutera keselamatan kami Daniel Walsh menulis artikel
Dalam artikel ini kami akan menunjukkan perkara yang telah berubah dari semasa ke semasa dan cara Podman boleh membantu kami dalam perkara ini.
Terdapat banyak sebab untuk menjalankan systemd di dalam bekas, seperti:
- Bekas pelbagai perkhidmatan β ramai orang ingin mengeluarkan aplikasi berbilang perkhidmatan mereka daripada mesin maya dan menjalankannya dalam bekas. Adalah lebih baik, sudah tentu, untuk memecahkan aplikasi sedemikian ke dalam perkhidmatan mikro, tetapi tidak semua orang tahu bagaimana untuk melakukan ini atau hanya tidak mempunyai masa. Oleh itu, menjalankan aplikasi seperti perkhidmatan yang dilancarkan oleh systemd dari fail unit sangat masuk akal.
- Fail Unit Systemd β Kebanyakan aplikasi yang berjalan di dalam bekas dibina daripada kod yang sebelum ini dijalankan pada mesin maya atau fizikal. Aplikasi ini mempunyai fail unit yang ditulis untuk aplikasi ini dan memahami cara ia harus dilancarkan. Jadi adalah lebih baik untuk memulakan perkhidmatan menggunakan kaedah yang disokong, daripada menggodam perkhidmatan init anda sendiri.
- Systemd ialah pengurus proses. Ia mengurus perkhidmatan (menutup, memulakan semula perkhidmatan, atau membunuh proses zombi) lebih baik daripada alat lain.
Yang berkata, terdapat banyak sebab untuk tidak menjalankan systemd dalam bekas. Yang utama ialah systemd/journald mengawal output bekas, dan alat seperti
Kedatangan Podman
Kami gembira untuk melaporkan bahawa keadaan akhirnya bergerak ke hadapan. Pasukan yang bertanggungjawab untuk menjalankan kontena di Red Hat memutuskan untuk membangunkan
Ramai orang melakukan ini.
Podman saya dan saya sama sekali tidak menentang bekas berasaskan systemd. Lagipun, Systemd ialah subsistem init Linux yang paling biasa digunakan, dan tidak membenarkannya berfungsi dengan betul dalam bekas bermakna mengabaikan bagaimana beribu-ribu orang biasa menjalankan kontena.
Podman tahu apa yang perlu dilakukan untuk menjadikan systemd berfungsi dengan betul dalam bekas. Ia memerlukan perkara seperti memasang tmpfs pada /run dan /tmp. Dia suka persekitaran "bekas" didayakan dan mengharapkan kebenaran menulis ke bahagian direktori cgroupnya dan ke folder /var/log/journald.
Apabila anda memulakan bekas di mana perintah pertama adalah init atau systemd, Podman secara automatik mengkonfigurasi tmpfs dan Cgroups untuk memastikan systemd bermula tanpa masalah. Untuk menyekat mod pelancaran automatik ini, gunakan pilihan --systemd=false. Sila ambil perhatian bahawa Podman hanya menggunakan mod systemd apabila ia melihat bahawa ia perlu menjalankan perintah systemd atau init.
Berikut adalah petikan daripada manual:
lelaki podman lari
...βsystemd=true|false
Menjalankan bekas dalam mod systemd. Didayakan secara lalai.
Jika anda menjalankan perintah systemd atau init di dalam bekas, Podman akan mengkonfigurasi titik pelekap tmpfs dalam direktori berikut:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
Juga isyarat berhenti lalai ialah SIGRTMIN+3.
Semua ini membolehkan systemd berjalan dalam bekas tertutup tanpa sebarang pengubahsuaian.
NOTA: systemd cuba menulis ke sistem fail cgroup. Walau bagaimanapun, SELinux menghalang bekas daripada melakukan ini secara lalai. Untuk mendayakan penulisan, dayakan parameter boolean container_manage_cgroup:
setsebool -P container_manage_cgroup true
Sekarang lihat rupa Dockerfile untuk menjalankan systemd dalam bekas menggunakan Podman:
# cat Dockerfile
FROM fedora
RUN dnf -y install httpd; dnf clean all; systemctl enable httpd
EXPOSE 80
CMD [ "/sbin/init" ]
Itu sahaja.
Sekarang kami memasang bekas:
# podman build -t systemd .
Kami memberitahu SELinux untuk membenarkan systemd mengubah suai konfigurasi Cgroups:
# setsebool -P container_manage_cgroup true
By the way, ramai orang lupa tentang langkah ini. Nasib baik, ini hanya perlu dilakukan sekali dan tetapan disimpan selepas but semula sistem.
Sekarang kita hanya memulakan bekas:
# 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.
Itu sahaja, perkhidmatan sedang berjalan dan berjalan:
$ curl localhost
<html xml_lang="en" lang="en">
β¦
</html>
NOTA: Jangan cuba ini di Docker! Di sana anda masih perlu menari dengan tamborin untuk melancarkan bekas jenis ini melalui daemon. (Medan dan pakej tambahan diperlukan untuk menjadikan ini semua berfungsi dengan lancar dalam Docker, atau ia perlu dijalankan dalam bekas istimewa. Untuk butiran, lihat
Beberapa lagi perkara menarik tentang Podman dan systemd
Podman berfungsi lebih baik daripada Docker dalam fail unit systemd
Jika bekas perlu dimulakan apabila sistem but, maka anda hanya boleh memasukkan arahan Podman yang sesuai ke dalam fail unit systemd, yang akan memulakan perkhidmatan dan memantaunya. Podman menggunakan model fork-exec standard. Dalam erti kata lain, proses kontena adalah anak kepada proses Podman, jadi systemd boleh memantaunya dengan mudah.
Docker menggunakan model pelayan pelanggan, dan arahan CLI Docker juga boleh diletakkan terus dalam fail unit. Walau bagaimanapun, apabila klien Docker menyambung kepada daemon Docker, ia (pelanggan) menjadi satu lagi proses pengendalian stdin dan stdout. Sebaliknya, systemd tidak tahu tentang sambungan antara klien Docker dan bekas yang berjalan di bawah kawalan daemon Docker, dan oleh itu, dalam model ini, systemd pada asasnya tidak dapat memantau perkhidmatan.
Mengaktifkan systemd melalui soket
Podman mengendalikan pengaktifan melalui soket dengan betul. Oleh kerana Podman menggunakan model fork-exec, ia boleh memajukan soket ke proses bekas anaknya. Docker tidak boleh melakukan ini kerana ia menggunakan model pelayan pelanggan.
Perkhidmatan varlink yang Podman gunakan untuk berkomunikasi dengan pelanggan jauh ke bekas sebenarnya diaktifkan melalui soket. Pakej cockpit-podman, yang ditulis dalam Node.js dan sebahagian daripada projek cockpit, membolehkan orang ramai berinteraksi dengan bekas Podman melalui antara muka web. Daemon web yang menjalankan cockpit-podman menghantar mesej ke soket varlink yang systemd mendengar. Systemd kemudian mengaktifkan program Podman untuk menerima mesej dan mula menguruskan bekas. Mengaktifkan systemd melalui soket menghapuskan keperluan untuk daemon yang sentiasa berjalan apabila melaksanakan API jauh.
Selain itu, kami sedang membangunkan pelanggan Podman lain yang dipanggil podman-remote, yang melaksanakan CLI Podman yang sama tetapi memanggil varlink untuk menjalankan bekas. Podman-remote boleh berjalan di atas sesi SSH, membolehkan anda berinteraksi dengan selamat dengan bekas pada mesin yang berbeza. Dari masa ke masa, kami merancang untuk mendayakan podman-remote untuk menyokong MacOS dan Windows bersama-sama Linux, supaya pembangun pada platform tersebut boleh menjalankan mesin maya Linux dengan Podman varlink berjalan dan mempunyai pengalaman penuh bahawa bekas dijalankan pada mesin tempatan.
SD_NOTIFY
Systemd membenarkan anda menangguhkan pelancaran perkhidmatan tambahan sehingga perkhidmatan kontena yang mereka perlukan bermula. Podman boleh memajukan soket SD_NOTIFY ke perkhidmatan kontena supaya perkhidmatan memberitahu systemd bahawa ia sedia untuk beroperasi. Dan sekali lagi, Docker, yang menggunakan model pelayan pelanggan, tidak boleh melakukan ini.
Dalam rancangan
Kami merancang untuk menambah perintah podman generate systemd CONTAINERID, yang akan menjana fail unit systemd untuk mengurus bekas tertentu yang ditentukan. Ini sepatutnya berfungsi dalam kedua-dua mod akar dan tanpa akar untuk bekas yang tidak mempunyai hak istimewa. Kami juga telah melihat permintaan untuk masa jalan systemd-nspawn yang serasi dengan OCI.
Kesimpulan
Menjalankan systemd dalam bekas adalah keperluan yang boleh difahami. Dan terima kasih kepada Podman, kami akhirnya mempunyai masa jalan kontena yang tidak bercanggah dengan systemd, tetapi menjadikannya mudah untuk digunakan.
Sumber: www.habr.com