- Nitro adalah supervisor proses dan sistem init superringkas yang dapat diterapkan pada embedded, server, desktop, dan container
- Menyimpan status sistem hanya di RAM sehingga dapat berjalan tanpa masalah bahkan pada file system read-only, serta menawarkan desain berbasis event yang cepat dan efisien
- Metode konfigurasinya berupa struktur direktori skrip yang sederhana, sehingga layanan dapat dikelola tanpa file konfigurasi yang rumit atau proses build tambahan
- Mendukung fitur yang dioptimalkan untuk container dan lingkungan embedded seperti layanan terparameterisasi, restart yang tangguh, dan logging andal per layanan
- Menjamin fleksibilitas dan kontrol yang tinggi, seperti kendali jarak jauh melalui alat nitroctl dan kontrol operasi berbasis sinyal
Ikhtisar
Nitro adalah supervisor proses superringkas yang juga dapat digunakan sebagai pid 1 di Linux
Bidang penggunaan utamanya adalah sebagai berikut
- init untuk mesin Linux dengan berbagai kegunaan seperti embedded, desktop, dan server
- init untuk Linux initramfs
- init untuk lingkungan container seperti Docker/Podman/LXC/Kubernetes
- daemon supervisi yang berjalan tanpa hak istimewa pada sistem POSIX
Konfigurasinya menggunakan struktur skrip berbasis direktori, dengan lokasi bawaan /etc/nitro
Persyaratan
- Memerlukan dukungan socket Unix pada kernel
- Memerlukan
tmpfsatau direktori/runyang dapat ditulisi
Kelebihan dibanding sistem lain
- Semua informasi status hanya disimpan di RAM sehingga dapat berjalan pada root file system read-only tanpa trik tambahan
- Mode operasi berbasis event tanpa polling memberikan efisiensi
- Tidak ada alokasi memori dinamis saat runtime
- File descriptor tidak akan terus-menerus terkuras tanpa batas
- Hanya memerlukan satu biner self-contained (opsional dengan biner kontrol tambahan)
- Tidak perlu konversi atau kompilasi file konfigurasi; layanan hanyalah direktori sederhana yang berisi skrip
- Mendukung rantai restart dan logging layanan
- Tetap berjalan normal meskipun jam sistem tidak akurat
- Dapat dijalankan melalui
/etc/ttysdi FreeBSD - Dengan musl libc, dimungkinkan membuat biner static yang sangat kecil
Manajemen layanan
-
Tiap direktori layanan (bawaannya di dalam
/etc/nitro) dapat berisi file berikutsetup: skrip (opsional) yang dijalankan sebelum layanan dimulai; layanan hanya dapat dimulai jika skrip selesai normal (0)run: skrip operasi layanan; selama belum berakhir, layanan dianggap hidup; jika tidak diimplementasikan, diperlakukan sebagai layanan one-shotfinish: skrip (opsional) yang dijalankan setelahrunberakhir; status keluar dan nilai sinyal diteruskan sebagai argumenlog: symbolic link yang menunjuk ke direktori layanan lain; outputrundipipe ke input layanan tersebut (dapat dimanfaatkan untuk rantai logging)down: jika file ini ada, nitro tidak akan menaikkan layanan ini secara default- Jika nama direktori diakhiri dengan '@', direktori itu diabaikan dan dapat digunakan sebagai layanan berparameter
- Nama layanan harus kurang dari 64 karakter, dan tidak boleh mengandung
/,,, atau karakter baris baru
-
Utilitas
chpstdari runit berguna saat menulis skriprun
Layanan khusus
LOG: layanan default untuk mencatat log semua layanan yang tidak memiliki linklogSYS:SYS/setupdijalankan sebelum semua layanan dimulai, sehingga dapat digunakan untuk mengimplementasikan urutan startup layananSYS/finish: dijalankan sebelum masuk ke tahap shutdown keseluruhanSYS/final: dijalankan setelah semua proses berakhirSYS/fatal: jika ada, dijalankan alih-alih keluar saat terjadi error fatalSYS/reincarnate: dijalankan sebagai pengganti shutdown, misalnya dapat dimanfaatkan untuk reimplementasi initramfs
Layanan terparameterisasi
- Direktori layanan yang diakhiri dengan '@' diabaikan oleh nitro, tetapi dapat ditentukan langsung melalui symbolic link atau perintah
nitroctl - Parameter setelah '@' diteruskan ke tiap skrip sebagai argumen pertama
- Contoh: jika ada symbolic link
agetty@/rundanagetty@tty1, maka yang dijalankan adalahagetty@/run tty1 - Saat memasukkan
nitroctl up agetty@tty2, dapat dijalankanagetty@/run tty2(terlepas dari ada atau tidaknya direktori)
- Contoh: jika ada symbolic link
Mode operasi
- Seluruh lifecycle terdiri dari tiga tahap: boot, menjalankan layanan (supervisi), dan shutdown
- Boot: jika layanan khusus
SYSada,setupdijalankan lebih dulu, lalu semua layanan non-down dijalankan - Jika layanan berhenti, layanan akan di-restart, tetapi jika restart sebelumnya terlalu cepat maka akan menunggu 2 detik
- Sinyal shutdown dapat dikirim melalui
nitroctl RebootatauShutdown- Dalam hal ini urutannya adalah
SYS/finish→ SIGTERM ke semua layanan (menunggu maksimal 7 detik) → SIGKILL →SYS/final→ urutan shutdown
- Dalam hal ini urutannya adalah
- Untuk supervisor bagi container atau tanpa hak istimewa, hanya proses yang akan dihentikan
- Boot: jika layanan khusus
Kontrol dengan nitroctl
- Alat CLI nitroctl dapat digunakan untuk mengendalikan nitro dari jarak jauh
Contoh perintah:
- list: menampilkan daftar layanan, status, PID, uptime, dan status keluar terakhir
- up/down/start/stop/restart: kontrol untuk memulai, menghentikan, dan me-restart layanan
- pengiriman sinyal: p(SIGSTOP), c(SIGCONT), h(SIGHUP), a(SIGALRM), i(SIGINT), q(SIGQUIT), 1(SIGUSR1), 2(SIGUSR2), t(SIGTERM), k(SIGKILL)
- pidof: menampilkan PID layanan yang ditentukan
- rescan: membaca ulang direktori layanan, menerapkan layanan yang ditambahkan atau dihapus
- Shutdown/Reboot: mematikan atau me-reboot seluruh sistem
Kontrol melalui sinyal
- Dapat dikendalikan dengan mengirim sinyal langsung ke proses nitro
- SIGHUP: pemindaian ulang layanan (rescan)
- SIGINT: reboot
- SIGTERM: shutdown (jika nitro bukan pid 1)
Nitro sebagai init di Linux
- Nitro adalah biner mandiri yang dapat langsung digunakan untuk boot sebagai pid 1 di Linux
- Akan me-mount
/devdan/runbila perlu, sedangkan operasi lainnya ditangani diSYS/setup - Event Ctrl-Alt-Del memicu reboot yang teratur
Menggunakan Nitro sebagai init di container Docker
- Nitro dapat dibangun secara statis sehingga mudah disertakan ke dalam container
- Agar jalur socket bawaan dapat digunakan,
/runharus ada di dalam container - Jika socket kontrol diproses sebagai bind mount, kontrol jarak jauh dari luar melalui nitroctl dapat dilakukan
Nitro di FreeBSD
- Nitro dapat disupervisi oleh FreeBSD init dengan menambahkan baris berikut ke
/etc/ttys/etc/nitro "/usr/local/sbin/nitro" "" on
Penulis
- Leah Neukirchen leah@vuxu.org
Ucapan terima kasih
- Dikembangkan di atas analisis mendetail terhadap sistem supervisi proses yang sudah ada seperti daemontools, freedt, runit, perp, dan s6
Lisensi
- Lisensi 0BSD (lihat file LICENSE untuk detail)
1 komentar
Komentar Hacker News
Ingin melihat perbandingan dengan runit. runit adalah sistem init yang sangat minimal namun nyaris lengkap. Ada banyak kemiripan seperti direktori kontrol, dependensi yang tidak deklaratif, susunan skrip yang mirip, dan pendekatan logging. Di halaman penjelasannya juga sempat disebut runit, dan disarankan dipakai bersama utilitas chpst. Sebagai pembeda, saya rasa bagus bahwa dengan satu direktori layanan, beberapa proses serupa (misalnya agetty) bisa dikelola secara terparametrisasi. reboot atau shutdown juga bisa dijalankan langsung lewat satu biner (
nitroctl). Sebaliknya, runit memakai struktur beberapa binerTahun lalu saya memensiunkan server-server terakhir yang masih dikelola dengan runit, dan rasanya cukup disayangkan. Sekitar 15 tahun lalu saat pertama kali menulis layanan runit sendiri, saya percaya inilah cara standar mengelola layanan di Linux. Lalu setelah meninggalkan Linux selama 5 tahun dan kembali, systemd sudah menjadi default. Saya sering mendengar penilaian buruk tentangnya, tetapi lama-kelamaan saya sadar banyak sentimen negatif yang sudah terdistorsi. Saat ini saya menjalankan layanan streaming kamera dan data suhu di Pi Zero untuk vivarium reptil, dan menyiapkannya dengan systemd ternyata sangat mudah. Di desktop OpenSuse maupun laptop kerja juga saya bisa menjalankan berbagai layanan dengan mudah menggunakan systemd. Saya jadi merasa, “adanya standar itu justru hal yang baik”
Ada perbandingan minimal yang cukup tepat antara runit dan nitro dalam slide presentasi Leah Neukirchen yang dirilis pada 2024 (PDF)
https://leahneukirchen.org/talks/#nitroyetanotherinitsy
Leah Neukirchen adalah sosok yang aktif di komunitas Void Linux. Saya menduga proyek ini akan sangat berkaitan dengan Void. Saya harap ada tulisan yang lebih resmi tentang cara menggunakan nitro di Void
Saya penasaran apakah tidak adanya “dependensi deklaratif” dianggap sebagai kelebihan. Saya sudah sering mendengar kritik terhadap systemd sebagai init, tetapi jarang melihat desain deklaratif itu sendiri dikritik. Saya ingin mendengar alasannya lebih rinci
Saya mengenal runit lewat Void Linux dan cukup nyaman memakainya sebagai sistem init, tetapi saya merasa UI dan dokumentasinya kurang. Terutama konfigurasi logging yang benar-benar sulit. Saya ingin mencoba alternatif yang sama-sama sederhana, tetapi punya default yang lebih masuk akal, UI yang lebih intuitif, dan dokumentasi yang lebih baik
Setiap kali melihat usulan menjalankan sistem init di dalam container, saya selalu bimbang. Kadang memang ada kasus yang dirancang karena kebutuhan nyata, tetapi sering juga justru membuat segalanya terlalu rumit (terutama di lingkungan Kubernetes dan cloud, di mana seharusnya desain pemisahannya dibuat lebih baik sejak awal). Kadang terasa seperti sekadar kebiasaan “toh semua orang pakai begini”, jadi saya selalu ragu apakah lebih baik “membuatnya lebih bagus” sambil ikut menyebarkan masalahnya, atau membiarkan orang gagal total dengan solusi yang ada sekarang
Saya pikir container aplikasi seharusnya mengikuti filosofi Unix: “lakukan satu hal dengan baik”. Tetapi jika di dalam container ada alasan apa pun untuk melakukan fork, maka menurut saya PID 1 haruslah init yang sungguhan
Dari pengalaman saya di bidang robotika, banyak container adalah sistem kompleks yang awalnya berjalan di bare metal lalu dipindahkan ke container. Ada banyak RPC tak terstruktur antarproses, sehingga tidak ada banyak manfaat untuk memecahnya menjadi banyak container terpisah. Untuk menjalankan banyak proses di dalam container aplikasi yang monolitik, berbagai pilihan seperti supervisor, runit, systemd, bahkan tmux sama-sama dipakai
Saya pernah memakai hosting yang menagih per container seperti Fly.io, Render, dan Google Cloud Run. Karena harga, kadang kita memang perlu menjalankan banyak proses dalam satu container
Fitur baru NixOS, modular-services, sudah masuk ke Nixpkgs. Ini akan membuat porting NixOS ke sistem init baru atau kernel baru jauh lebih mudah, jadi menurut saya sekarang adalah saat yang tepat untuk bereksperimen dengan hal seperti nitro
Saya ingin membandingkan dinit yang dipakai di Chimera Linux dengan nitro. Setelah membaca sekilas readme-nya, tampaknya pengelolaan dependensi layanan masih belum didukung
dinit: https://github.com/davmac314/dinit
Nitro tidak menangani dependensi layanan secara deklaratif. Tidak mungkin melihat grafik dependensi antarlayanan dengan rapi lewat satu perintah. Tetapi jika layanan yang dibutuhkan disebutkan di skrip setup, maka sistem akan memeriksa apakah layanan itu sudah hidup, lalu otomatis menunggu dan mencoba lagi. Kalau ingin melihat grafik dependensi, mau tak mau harus menulis skrip sendiri dengan grep atau semacamnya. Sebaliknya, saat suatu layanan mati, cukup mudah lupa untuk ikut mematikan layanan yang bergantung padanya, dan nitro sendiri tidak punya cara yang nyaman untuk mendeteksi hal seperti itu
Saya pernah memakai dinit di Artix Linux, dan itu benar-benar ringan serta mengesankan
Artix FAQ: https://artixlinux.org/faq.php
Proyek-proyek level rendah seperti ini sangat menarik untuk dilihat. Saya suka bahwa systemd memanfaatkan fitur-fitur khusus kernel Linux dengan baik, melampaui kerangka tradisional SysV·POSIX. Tetapi saya harap itu bukan akhir dari segalanya, dan semoga ide-ide baru serta inovasi terus bermunculan. Belakangan ini saya sendiri membuat setup otomasi manufaktur yang melakukan netboot langsung dari firmware UEFI ke kernel Linux, dengan hanya membenamkan satu biner init yang saya tulis sendiri dalam Go. Dengan hanya mengandalkan kode yang saya bawa sendiri dan bahasa tingkat tinggi untuk mengendalikan seluruh lingkungan OS, rasanya sangat membebaskan karena tidak perlu mengelola banyak subprocess dan beragam file konfigurasi teks
Sekitar 13 tahun lalu saya pernah membangun sistem init sendiri dalam C. Ternyata butuh usaha jauh lebih besar dari perkiraan, dan dipakai untuk mempercepat boot GUI dan backend di perangkat keras berspesifikasi rendah. Itu latihan pemrograman yang menyenangkan, tetapi kemudian saya sadar mungkin sebenarnya sudah ada solusi serupa. Seorang rekan di perusahaan yang sama bahkan membuat init lain, sehingga versi pertama saya nyaris ringan tanpa dependensi selain libc, sementara versinya berbasis libevent dan punya fitur yang lebih canggih
Saya agak terganggu karena nama dan fungsinya tumpang tindih dengan AWS Nitro
https://docs.aws.amazon.com/whitepapers/latest/security-design-of-aws-nitro-system/the-nitro-system-journey.html
Hanya namanya yang sama; sistem init dan hypervisor pada dasarnya benar-benar berbeda
Saya rasa hampir tidak akan menimbulkan masalah. Yang satu adalah sistem init yang bisa dipakai siapa saja, sedangkan AWS Nitro adalah fork KVM yang hanya dipakai secara internal oleh perusahaan
Saya penasaran seperti apa nitro dibandingkan dengan s6. Baru-baru ini saya menyiapkan sistem init di container Docker dengan s6, dan dengan s6-overlay saya harus membuat banyak file secara manual, serta ternyata tidak seintuitif yang saya bayangkan
tini juga layak dilihat: https://github.com/krallin/tini
Di Distrust, kami menulis sendiri sistem init super sederhana dalam rust dengan kurang dari 500 baris, dan beberapa klien memakainya di produksi untuk lingkungan enclave dengan persyaratan keamanan tinggi. Karena hanya memakai pustaka standar rust, auditnya jadi sangat mudah
https://git.distrust.co/public/nit
Tidak bisa menentukan dependensi, tidak ada pengaturan user/group, harus menentukan urutan secara manual, tidak ada eksekusi layanan paralel, tidak ada pengelolaan sumber daya. Sistem yang kekurangan semua ini sebaiknya jangan disebut sistem init. Itu cuma process supervisor yang sangat bare-bones