Contents

Beralih ke Runit

Runit merupakan sebuah UNIX init scheme dengan service supervision. Pada dasarnya hal ini berarti Runit mampu menyediakan automatic starting sebuah services ketika sistem operasi dijalankan untuk pertamakali, serta automatic monitoring and restarting sebuah service jika terjadi sebuah interupsi.

Systemd vs Runit

Ketika artikel ini diterbitkan, systemd nyaris menguasai semua distro sistem operasi GNU/Linux. Misalnya Fedora, Debian, Ubuntu, dan banyak lagi lainnya sudah beralih dari init system sebelumnya lalu menggunakan systemd. Hal ini terjadi karena systemd menawarkan banyak hal yang terintegrasi, hampir segala hal pada sistem operasi akan di-handle olehnya.

/beralih-ke-runit/systemd-and-linux.png
Systemd and GNU/Linux

Kontroversi systemd

systemd memang menjadi kontroversi karena beberapa hal. Sebagian orang menganggap bahwa systemd tidak menghormati filosofi Unix. Saya ingat ketika awal sekali mengenal GNU/Linux, bahwa GNU/Linux adalah sistem operasi yang Unix-like dan Unix memiliki filosofi sebagai berikut :

  • Tugas sebuah program adalah melakukan satu hal, dan melakukannya dengan baik.
  • Sistem yang besar dan kompleks merupakan gabungan dari program-program kecil yang bekerja sama.
  • Teks adalah antarmuka yang universal.
  • Segala hal di Unix adalah file.

systemd dianggap tidak conform dengan filosofi Unix diatas sehingga banyak yang menolaknya. systemd awalnya dikembangkan oleh Lennart Pottering, seorang developer yang saat artikel ini diterbitkan tengah bekerja untuk Red Hat. Dia sebelumnya juga membuat program yang tak kalah kontroversial yaitu Avahi dan PulseAudio. Silahkan baca tentang Lennart Pottering di Wikipedia.

Beberapa kritik lain terhadap systemd misalnya karena systemd tidak hanya menjadi init system tapi juga mengambil ali banyak fungsi. Misalnya systemd berusaha mengatur network, cron, fstab, syslog atau rsyslog, ntp, dan banyak lainnya. Artinya systemd bukanlah sebuah program yang melakukan satu hal saja, tapi banyak hal. Kemudian, systemd dikritik karena logging file-nya tidak berbasis teks seperti Unix dan GNU/Linux pada umumnya, melainkan binary log file.

Runit Sebagai Alternatif

Berbagai penolakan tentu saja terjadi, tidak sedikit developer yang kemudian melakukan fork lalu mengembangkan distro GNU/Linux yang bebas dari systemd. Misalnya Artix Linux, yang merupakan fork dari project Arch Linux dengan maksud membebaskan pengguna Arch dari cengkeraman systemd. Artix menawarkan beberapa alternatif sebagai pengganti systemd, misalnya OpenRC, S6, dan tentu saja Runit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/etc/runit/sv/foo
├── log
│   ├── run
│   └── supervise
│       ├── control
│       ├── lock
│       ├── ok
│       ├── pid
│       ├── stat
│       └── status
├── run
└── supervise
    ├── control
    ├── lock
    ├── ok
    ├── pid
    ├── stat
    └── status

Pada distro Artix, biasanya direktori sebuah service akan terlihat seperti di atas. Anggaplah /etc/runit/sv adalah templatedir, dan /etc/runit/sv/foo adalah direktori konfigurasi service. Maka kelak service yang berjalan akan bernama sebagai foo juga. Dalam direktori foo biasanya kita hanya diwajibkan untuk membuat sebuah file executable bernama run, berisikan baris perintah untuk mengeksekusi program yang akan dijadikan sebagai sebuah service. Namun jika kita membutuhkan logging, kita dapat memanfaatkan svlogd dengan membuat sebuah direktori bernama log di dalam /etc/runit/sv/foo, kemudian buat lagi sebuah file bernama run di dalam direktori log tersebut. Isi dari file-file run tersebut akan kita bahas dibawah.


Beralih ke Runit

Dalam dokumentasi ini kita akan belajar tentang :

  1. Membuat sebuah runit template untuk untuk konfigurasi monitored service.
  2. Konfigurasi monitored service untuk pertamakali.
  3. Mengelola monitored service secara manual.

/beralih-ke-runit/runit-sv.png
runit sv

0. Prerequisites

Pastikan paket dari runit sudah terpasang pada sistem. Sebagian besar distro GNU/Linux biasanya memiliki paket tersebut pada repository mereka. Misalnya, jika kita menggunakan sebuah distro Arch-based maka kita dapat memasang paket dengan perintah berikut.

1
$ sudo pacman -Sy runit
Perhatian
Pada distro Artix biasanya kita tidak perlu melakukan pemasangan paket Runit. Kita diperkenankan memilih init system apa yang akan digunakan pada waktu mengunduh berkas ISO installer.

Periksa apakah runit telah terpasang pada sistem, dengan mencari sebuah process bernama runsvdir dengan perintah.

1
$ sudo ps -ef | grep runsvdir

Jika runit telah terpasang, harusnya akan keluar output seperti berikut.

1
root      1090     1  0 Dec15 ?        00:00:00 runsvdir -P /run/runit/service log:..............

Di sini runsvdir merupakan hal paling pertama dari beberapa lainnya yang akan kita pahami. runit memang diarancang untuk mengambil pendekatan yang terasa sangat Unixy, yaitu dengan cara memecah fungsionalitas utama menjadi beberapa utilities kecil yang masing-masing unitnya bertanggung jawab menjalankan sebuah tugas. Pendekatan tersebut membuat komponen-komponen kecilnya mampu dibentuk dengan beberapa metode sesuai dengan yang kita butuhkan. Core unit yang terdapat pada runit beberapa diantaranya adalah runsvdir, runsv, chpst, svlogd, dan sv. Nantinya, dalam dokumentasi ini kita akan mengkombinasikan beberapa hal diatas untuk kofigurasi runit dan menjalankan sebuah managed service.

1. Membuat sebuah Template

Hal pertama yang perlu kita lakukan adalah memperhatikan lebih dalam apa yang sebenarnya terjadi pada output runsvdir -P /run/runit/service log:...... Pada dasarnya, dalam output tersebut terdapat sebuah perintah yang mengawasi direktori /run/runit/service, karena di dalamnya terdapat file konfigurasi dari monitored service. Sebuah monitored service dikonfigurasi dengan menambahkan sebuah subdirektori ke dalam /run/runit/service berisikan sebuah berkas script run di dalamnya. Ketika runsvdir menemukan sebuah konfigurasi baru, maka ia akan menjalankan process runsvbaru untuk mengelola service. Ingat, bahwa salah satu Filosofi Unix berbunyi tugas sebuah program adalah melakukan satu hal, dan melakukannya dengan baik.

Pastikan bahwa direktori /etc/runit/sv/ ada. Di dalamnya kita akan membuat direktori baru bernama foo.

1
$ sudo mkdir -p /etc/runit/sv/foo

Lalu di dalam direktori tersebut kita buat sebuah file template bernama run untuk ilustrasi.

1
2
3
#!/bin/sh
exec 2>&1
exec chpst -u foo /opt/example/foo-service.sh

Jangan lupa file run harus menjadi executable dengan cara berikut.

1
$ sudo chmod +x /etc/runit/sv/foo/run

Script run di atas akan mengeksekusi script foo-service.sh yang nantinya akan kita buat di dalam direktori /opt/example. Terdapat juga chpst yang berfungsi agar nantinya eksekusi akan dijalankan oleh user bernama foo, kita akan buat juga usernya nanti.

Runit menawarkan svlogd untuk mengelola logfile dari sebuah service, kita akan mencoba membuatnya juga. Mari buat direktori baru bernama log.

1
$ sudo mkdir /etc/runit/sv/foo/log

Di dalam direktori tersebut, kita akan membuat file baru lagi bernama run berisikan script berikut.

1
2
#!/bin/sh
exec chpst -u foo svlogd -tt /var/log/foo

Pada script diatas svlogd akan menghasilkan output dari template yang sebelumnya kita buat. Output yang muncul akan ditampung pada direktori /var/log/foo yang kita buat nanti.

2. Menyiapkan Logging Directory

Buat sebuah direktori untuk menampung log dari service.

1
$ sudo mkdir -p /var/log/foo

Lalu kita membutuhkan user baru bernama foo sebagai ilustrasi.

1
$ sudo useradd foo

Direktori log seharusnya menjadi milik user foo supaya user tersebut mampu menulis di dalamnya, sehingga kita perlu merubah kepemilikannya dengan perintah berikut.

1
$ sudo chown foo:foo /var/log/foo

3. Membuat Program Ilustrasi

Buat sebuah direktori baru untuk meletakkan file program ilustrasi.

1
$ sudo mkdir -p /opt/example

Dari sini kita akan melanjutkan dengan membuat program sebagai ilustrasi bernama foo-service.sh yang terletak pada direktori /opt/example.

1
2
3
4
5
6
7
8
9
#!/bin/bash
echo "Menjalankan service..."
for i in {1..30}
do
    echo "Melakukan sesuatu..."
    sleep 1
done
echo "Oh tidak, program crash!" >&2
exit 1

Jangan lupa untuk menjadikan file tersebut executable seperti berikut.

1
$ sudo chmod +x /opt/example/foo-script.sh

Kemudian jadikan direktori serta file di dalamnya menjadi milik user foo.

1
$ sudo chown -R foo:foo /opt/example

Program foo-script.sh akan mensimulasikan sebuah process yang dieksekusi menggunakan runit sesuai dengan template yang sebelumnya telah kita buat. foo-script.sh akan crash setiap 30 detik, dan setiap output nya akan dicatat ke dalam log.

4. Mengelola Service

Kita tiba pada tahap menggunakan sv untuk pengelolaan service dari ilustrasi yang telah kita buat sebelumnya. Untuk menjalankan service kita perlu melakukan symlink direktori template ke dalam direktori runsvdir.

Enable service

1
$ sudo ln -s /etc/runit/sv/foo /run/runit/service

Ketika melakukan perintah ln -s diatas, direktori template dari service tersebut (/etc/runit/sv/foo) akan dijadikan sebagai titik link yang ditambahkan ke dalam direktori runsvdir pada /run/runit/service. Lalu runsvdir terus melakukan pengawasan pada service yang baru saja kita tambahkan. Sehingga pada saat process terinterupsi (misalnya oleh reboot atau kill) maka service tersebut akan kembali dinyalakan secara otomatis. Itulah yang dimaksud dengan supervision di dalam sebuah sistem init.

Memeriksa status service

Kemudian lakukan pemeriksaan, apakah service berhasil dijalankan.

1
$ sudo sv status /run/runit/service/foo

Jika berhasil, seharusnya akan keluar output seperti berikut.

1
run: foo: (pid 16998) 3s; run: log: (pid 16997) 3s

Menghentikan service

Coba hentikan service dengan perintah berikut.

1
$ sudo sv down /run/runit/service/foo

Jika berhasil dihentikan, maka akan keluar output seperti berikut.

1
ok: down: example: 1s, normally up

Menyalakan service

Nyalakan lagi kemudian periksa lagi statusnya dengan perintah seperti berikut ini.

1
2
$ sudo sv up /run/runit/service/foo
$ sudo sv status /run/runit/service/foo

Jika berhasil berjalan, maka akan muncul output sebagai berikut.

1
run: foo: (pid 18146) 16s; run: log: (pid 16997) 250s

Melihat logfile

Sekarang kita akan coba melihat apakah logging berhasil dilakukan.

1
$ sudo tail -f /var/log/foo/current

svlogd akan membuat sebuah file baru bernama current dalam direktori log yang sudah kita siapkan. Nantinya file tersebut akan menampung tiap output dari service yang sedang berjalan. Apabila berhasil, seharusnya akan muncul output seperti berikut.

1
2
3
4
5
6
7
8
2020-12-16_17:38:43.31313 Melakukan sesuatu...
2020-12-16_17:38:44.31422 Melakukan sesuatu...
2020-12-16_17:38:45.31513 Melakukan sesuatu...
2020-12-16_17:39:13.34046 Oh tidak, program crash!
2020-12-16_17:39:13.34372 Menjalankan service...
2020-12-16_17:39:13.34375 Melakukan sesuatu...
2020-12-16_17:39:14.34453 Melakukan sesuatu...
2020-12-16_17:39:15.34541 Melakukan sesuatu...

Terlihat seperti diatas, bahwa program foo-script.sh berhasil dijalankan, berhenti setiap 30 detik, kemudian runit akan berusaha menyalakannya lagi. Tidak terbatas seperti tail -f saja, namun svlogd mampu melakukan log rotation otomatis layaknya logrotate, bahkan svlogd mampu melakukannya tanpa perlu mematikan service terlebih dahulu.

Disable service

Untuk menghilangkan sebuah service dari runsvdir kita perlu menghapus symlink yang sebelumnya kita buat.

1
$ sudo unlink /run/runit/service/example

Setelah dihapus, maka service akan berhenti seketika dan tidak akan dimuat ketika sistem operasi booting.


Perbandingan Perintah Runit vs Systemd

Systemd memang memiliki lebih banyak perintah daripada Runit, namun jika dibandingkan maka berikut ini adalah beberapa perintah yang umum digunakan dalam mengelola service dari kedua init system tersebut.

Usage Systemd Runit
Menjalankan service systemctl start <service> sv up <service>
Mematikan service systemctl stop <service> sv down <service>
Menyalakan ulang service systemctl restart <service> sv restart <service>
Enable service at boot systemctl enable <service> ln -s /etc/runit/sv/<template dir> /run/runit/<runsvdir>
Disable service from boot systemctl disable <service> unlink /run/runit/<runsvdir>/<service>

Manakah yang lebih baik?

  • Dalam pekerjaan, systemd tetap digunakan pada server-server customer yang saya jumpai. Tidak ada masalah bagi saya, karena itulah prosedur yang diterapkan di perusahaan-perusaahan tersebut. Tentu sebuah server yang berada dalam skala production membutuhkan stabilitas tinggi, nyaris semua yang saya kelola menggunakan berbagai platform dari Red Hat. Dan RHEL (Red Hat Enterprise Linux) sendiri adalah salah satu distro GNU/Linux yang paling bergantung pada systemd. Saya mengakui bahwa systemd adalah sistem yang modern. Yang menurut saya kurang adalah sistem logging dengan journald, file log yang dihasilkan bukanlah textfile. Sebelumnya, dengan rsyslog kita bebas memakai beragam tool seperti cat, grep, tail, atau head. Tetapi dengan journald kita dibatasi hanya bisa menggunakan satu tool yaitu journalctl.

  • Untuk pemakaian di komputer pribadi, tentu saja saya lebih prefer menggunakan Runit. Bukan tanpa alasan, runit mengkonsumsi resouce (seperti RAM dan CPU) yang relatif lebih sedikit daripada systemd. Dependency yang digunakan oleh runit juga tidak sebanyak systemd, berarti runit juga lebih ramah dalam urusan penggunaan storage. Untuk kecepatan, saya berani mengadu kecepatan antara runit melawan systemd, karena telah memiliki pengalaman pribadi bahwa runit menang telak! Runit membuat sistem operasi saya booting lebih cepat daripada systemd. Terlepas dari semua itu, saya juga belum membutuhkan systemd dengan segala bloated features nya untuk urusan pribadi (itu terlalu berlebihan, saya bahkan tidak pernah menggunakan itu semua secara keseluruhan), yang saya perlukan pada komputer pribadi adalah program dapat berjalan sesuai dengan yang saya kehendaki. Sehingga saya menyimpulkan bahwa runit layak dijadikan sebagai alternatif.


Referensi