Jalankan systemd dalam wadah

Kami telah mengikuti topik menggunakan systemd dalam wadah untuk waktu yang lama. Kembali pada tahun 2014, insinyur keamanan kami Daniel Walsh menulis sebuah artikel yang disebut Running systemd di dalam Docker Container , dan beberapa tahun kemudian artikel lain yang disebut Running systemd dalam wadah yang tidak istimewa , di mana ia menyatakan bahwa situasinya tidak sangat meningkat. Secara khusus, ia menulis bahwa “sayangnya, dan dua tahun kemudian, jika Anda menggunakan sistem Docker di Google, hal pertama yang muncul adalah artikel lamanya yang sama. Jadi sudah waktunya untuk mengubah sesuatu. ” Selain itu, kami sudah membicarakan tentang konflik antara pengembang Docker dan systemd .



Dalam artikel ini kami akan menunjukkan apa yang telah berubah dari waktu ke waktu dan bagaimana Podman dapat membantu kami dalam masalah ini.

Ada banyak alasan untuk menjalankan systemd di dalam sebuah wadah, seperti:

  1. Wadah multiservice - banyak orang ingin mendapatkan aplikasi multiservice mereka dari mesin virtual dan menjalankannya dalam wadah. Akan lebih baik, tentu saja, untuk memecah aplikasi seperti itu ke dalam layanan microser, tetapi tidak semua orang bisa melakukannya atau tidak ada waktu. Oleh karena itu, meluncurkan aplikasi tersebut dalam bentuk layanan yang diluncurkan oleh systemd dari file unit masuk akal.
  2. File unit Systemd - sebagian besar aplikasi yang menjalankan kontainer dikompilasi dari kode yang sebelumnya dijalankan pada mesin virtual atau fisik. Aplikasi ini memiliki file unit yang ditulis untuk aplikasi ini dan memahami cara menjalankannya. Jadi lebih baik memulai layanan menggunakan metode yang didukung, daripada meretas layanan init Anda sendiri.
  3. Systemd adalah manajer proses. Ia mengelola layanan (dimatikan, memulai kembali layanan, atau merayapi proses zombie) lebih baik daripada alat lain.

Ada banyak alasan untuk tidak menjalankan systemd dalam wadah. Yang utama adalah systemd / journald mengontrol output dari container, sementara tool seperti Kubernetes atau OpenShift mengharapkan container untuk menulis log langsung ke stdout dan stderr. Oleh karena itu, jika Anda bermaksud untuk mengelola wadah melalui alat orkestrasi seperti yang disebutkan di atas, maka Anda perlu mempertimbangkan dengan serius penggunaan wadah berdasarkan sistemd. Selain itu, para pengembang Docker dan Moby sering sangat menentang menggunakan systemd dalam wadah.

Podman Datang


Kami dengan senang hati mengumumkan bahwa situasinya akhirnya bergerak turun. Tim yang bertanggung jawab untuk meluncurkan kontainer di Red Hat memutuskan untuk mengembangkan mesin kontainer mereka sendiri . Dia mendapat nama Podman dan menawarkan antarmuka baris perintah (CLI) yang sama dengan Docker. Dan hampir semua perintah Docker dapat digunakan dengan cara yang sama di Podman. Kami sering mengadakan seminar, yang sekarang disebut Change Docker to Podman , dan slide pertama mendorong Anda untuk mendaftar: alias docker = podman.

Banyak yang melakukannya.

Podman saya dan saya sama sekali tidak menentang kontainer berbasis sistem. Bagaimanapun, Systemd paling sering digunakan sebagai init-subsistem Linux, dan tidak membiarkannya bekerja secara normal dalam wadah berarti mengabaikan cara ribuan orang digunakan untuk menjalankan wadah.

Podman tahu apa yang harus dilakukan untuk membuat systemd berfungsi dengan baik dalam wadah. Dia membutuhkan hal-hal seperti me-mount tmpfs di / run dan / tmp. Dia suka ketika lingkungan "wadah" diaktifkan, dan dia sedang menunggu izin menulis ke bagiannya dari direktori cgroup dan ke folder / var / log / journald.

Ketika memulai sebuah wadah di mana init atau systemd adalah perintah pertama, Podman secara otomatis mengkonfigurasi tmpfs dan Cgroups sehingga systemd mulai tanpa masalah. Untuk memblokir mode mulai otomatis ini, gunakan opsi --systemd = false. Harap dicatat bahwa Podman menggunakan mode systemd hanya ketika ia melihat bahwa perlu untuk mengeksekusi perintah systemd atau init.

Berikut ini kutipan dari manual:

manusia podman lari
...

–Systemd = true | false

Menjalankan wadah dalam mode systemd. Diaktifkan secara default.

Jika perintah systemd atau init dijalankan di dalam wadah, Podman akan mengonfigurasi titik pemasangan tmpfs di direktori berikut:

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

Juga, SIGRTMIN + 3 akan digunakan sebagai sinyal berhenti secara default.

Semua ini memungkinkan systemd untuk bekerja dalam wadah tertutup tanpa modifikasi apa pun.

CATATAN: systemd sedang mencoba menulis ke sistem file cgroup. Namun, SELinux secara default mencegah kontainer melakukan ini. Untuk mengaktifkan penulisan, aktifkan parameter batch container_manage_cgroup:

setsebool -P container_manage_cgroup true

Sekarang lihat seperti apa Dockerfile menjalankan systemd dalam wadah saat menggunakan Podman:

# cat Dockerfile FROM fedora RUN dnf -y install httpd; dnf clean all; systemctl enable httpd EXPOSE 80 CMD [ "/sbin/init" ] 

Itu saja.

Sekarang ambil wadahnya:

 # podman build -t systemd . 

Kami memberi tahu SELinux untuk mengizinkan systemd memodifikasi konfigurasi Cgroups:

 # setsebool -P container_manage_cgroup true 

Omong-omong, banyak yang melupakan langkah ini. Untungnya, itu cukup untuk melakukan ini hanya sekali dan pengaturan disimpan setelah sistem reboot.

Sekarang jalankan saja wadahnya:

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

Semuanya, layanan dimulai dan berfungsi:

 $ curl localhost <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> … </html> 

CATATAN: Jangan mencoba mengulanginya di Docker! Di sana, tarian dengan rebana masih diperlukan untuk meluncurkan wadah tersebut melalui setan. (Kolom dan paket tambahan akan diperlukan untuk ini berfungsi dengan mulus di Docker, atau itu akan perlu dijalankan dalam wadah istimewa. Lihat artikel untuk detailnya .)

Beberapa hal keren tentang Podman dan systemd


Podman bekerja lebih baik daripada buruh pelabuhan dalam file unit systemd


Jika kontainer harus dimulai pada boot sistem, maka Anda dapat dengan mudah memasukkan perintah Podman yang sesuai ke file unit systemd, yang akan meluncurkan layanan dan memonitornya. Podman menggunakan model fork-exec standar. Dengan kata lain, proses kontainer berafiliasi dengan proses Podman, sehingga systemd dapat dengan mudah memantaunya.

Docker menggunakan model client-server, dan perintah Docker CLI juga dapat ditempatkan langsung di file unit. Namun, setelah klien Docker terhubung ke daemon Docker, itu (klien) menjadi hanya proses lain yang memproses stdin dan stdout. Pada gilirannya, systemd tidak tahu tentang koneksi antara klien Docker dan wadah yang menjalankan daemon Docker, dan oleh karena itu, dalam model ini, systemd tidak dapat secara mendasar memonitor layanan.

Aktivasi systemd melalui soket


Podman memenuhi aktivasi dengan benar melalui soket. Karena Podman menggunakan model fork-exec, ia dapat meneruskan soket ke proses wadah anaknya. Docker tidak tahu caranya, karena menggunakan model client-server.

Layanan varlink yang digunakan Podman untuk berinteraksi dengan klien jarak jauh dengan kontainer sebenarnya diaktifkan melalui soket. Paket kokpit-podman, ditulis dalam Node.js dan bagian dari proyek kokpit, memungkinkan orang untuk berinteraksi dengan wadah Podman melalui antarmuka web. Daemon web yang dijalankan oleh kokpit-podman mengirimkan pesan ke soket varlink yang didengarkan systemd. Setelah itu, systemd mengaktifkan program Podman untuk menerima pesan dan mulai mengelola kontainer. Mengaktifkan systemd melalui soket memungkinkan Anda melakukannya tanpa daemon yang berfungsi secara konstan saat menerapkan API jarak jauh.

Selain itu, kami sedang mengembangkan klien lain untuk Podman, yang disebut podman-remote, yang mengimplementasikan CLI Podman yang sama, tetapi memanggil varlink untuk meluncurkan kontainer. Podman-remote dapat bekerja di atas sesi SSH, yang memungkinkan Anda untuk berinteraksi dengan wadah dengan aman pada mesin yang berbeda. Seiring waktu, kami berencana untuk menggunakan podman-remote untuk mendukung MacOS dan Windows bersama dengan Linux, sehingga pengembang pada platform ini dapat menjalankan mesin virtual Linux dengan Podman varlink berjalan dan memiliki perasaan penuh bahwa kontainer berjalan di mesin lokal.

SD_NOTIFY


Systemd memungkinkan Anda untuk menunda peluncuran layanan tambahan hingga layanan kemas yang diperlukan dimulai. Podman dapat meneruskan soket SD_NOTIFY ke layanan kemas sehingga layanan memberitahukan sistem dan kesiapannya untuk bekerja. Dan lagi, Docker, menggunakan model client-server, tidak tahu caranya.

Dalam rencana


Kami berencana untuk menambahkan podman menghasilkan perintah systemd CONTAINERID, yang akan menghasilkan file unit systemd untuk mengelola wadah tertentu. Ini harus bekerja dalam mode root dan rootless untuk wadah yang tidak terjangkau. Kami bahkan melihat permintaan untuk membuat runtime systemd-nspawn yang kompatibel dengan OCI.

Kesimpulan


Menjalankan systemd dalam sebuah wadah adalah kebutuhan yang bisa dimengerti. Dan terima kasih kepada Podman, kami akhirnya memiliki lingkungan peluncur wadah yang tidak memusuhi systemd, tetapi membuatnya mudah digunakan.

Source: https://habr.com/ru/post/id468931/


All Articles