Linux servisleri nasıl yönetir?
Bu flood’da Linux işletim sisteminde çalıştırılan servislerin yönetilmesinde kullanılan systemd
'den bahsedeceğim.
Linux üzerinde koşturduğumuz servislerin, durduğunda ve işletim sistemi kapatılıp açıldığında otomatik olarak yeniden başlatılması, loglarının toplanması vb işlemleri yürütecek bir mekanizmaya ihtiyaç vardır. systemd
birçok Linux dağıtımı için bu mekanizmayı sağlamaktadır.
Linux’ta çalıştırdığımız web ve uygulama sunucuları, SSH, DNS, telnet, vb servisler systemd
veya benzeri (örneğin upstart
) bir init system
tarafından yönetilirler. Bu sistemlere init system
denmesinin sebebi, Linux'un bu sistemleri açılış sırasında (boot) diğer process'leri başlatan ve PID
(Process ID) 1
ile ifade edilen init
process'i olarak kullanmasıdır. Aşağıdaki ekran çıktısında görüldüğü gibi Ubuntu 16.04.1
Linux dağıtımında init
process'i olarak systemd
kullanılmıştır.
systemd
komut satırından systemctl
CLI
'ı ile yönetilir. Sistemde systemd
tarafından yönetilen bütün servisler systemctl list-units --type service --state running
komutu ile görüntülenebilir. Aşağıda bu komutun benim test sistemimde verdiği çıktı görülmektedir.
Halihazırda çalışan bir servisin durumu systemctl status <service_name>
komutu listelenir. Örnek olarak test sisteminde çalışmakta olan docker
servisinin durumu sudo systemctl status docker.service
komutu ile görülebilir.
Çalışmakta olan bir servis systemctl stop <service_name>
komutu ile durdurulur, durdurulmuş bir servis ise systemctl start <service_name>
komutu ile başlatılır. Bir servisi yeniden başlatmak için ise systemctl restart <service_name>
komutu kullanılır.
Sistemde bulunan bir servisin deaktive edilmesi istendiğinde systemctl disable <service_name>
, aktive edilirken ise systemctl enable <service_name>
komutları kullanılır. Deaktive edilen bir servis, systemd
tarafından sistemin yeniden başlatılması sırasında başlatılmaz.
systemd
tarafından yönetilen servislerin ürettiği loglar journalctl
komutu ile görülebilir. Aşağıda sudo journalctl -u docker.service
ile docker
servisinin logları döktürülmüştür. systemd
'nin yönettiği kaynaklar (servis, soket, vb) unit / -u
olarak adlandırılır.
Her ne kadar bu flood’da systemd
'nin Linux servisleri yönetmesi üzerinde durulduysa da systemd
unit
olarak nitelendirdiği sisteme ait bütün kaynakları yönetebilir. Bazı unit
tipleri service
, socket
, device
, mount
vb olarak verilebilir.
Şimdi Linux’ta servis olarak çalışmak üzere basit bir Python programı hazırlayarak bunu systemd
servisi olarak tanımlayalım ve systemd
'nin sağladığı özellikleri daha yakından tanıyalım. Örnek Python programı aşağıda verilmiştir.
Görüldüğü üzere örnek Python programı birer saniye aralıklarla ekrana bir mesaj yazmaktadır. Örnek program terminalden çalıştırıldığında aşağıdakine benzer bir görüntü oluşturmaktadır.
Örnek Python programı için hazırlanan systemd
unit dosyası aşağıda verilmiştir. Şimdi bu dosyada bulunan satırları teker teker açıklayalım. Restart=on-failure
satırı ile systemd
ilgili prosesi başarısız çıkış yaptığında yeniden başlatacaktır.
RestartSec=10
, systemd
'ye proses çıkış yaptıktan sonra yeniden başlatmak için 10 saniye beklemesini söylemektedir. WorkingDirectory=
başlatılan prosesin çalışma klasörünü, ExecStart=/usr/bin/python3 ...
ise servis başlatılırken çalıştırılacak komutu belirtmektedir. ExecStop=/bin/kill -INT $MAINPID
satırı ile servis durdurulduğunda systemctl stop sample.service
çalıştırılacak komuta yer verilmiştir. Görüldüğü üzere kill
programı ile systemd
tarafından başlatılan prosese SIGINT
sinyali gönderilmesi planlanmıştır.
Şimdi servisi sample.service
adlı dosyayı /etc/systemd/system/
klasörü altına taşıyarak sudo systemctl enable sample.service
komutu ile aktive ederek sudo systemctl start sample.service
ile servisi başlatabiliriz.
Başlattığımız servisin loglarını journalctl -u sample.service -f
komutu ile ekrana döktürebilir ve -f / follow
ile takip edebiliriz.
Başka bir servise bağımlılığı olan bir servisin bağımlı olduğu servis unit
dosyasında belirtilirse systemd
öncelikle bağımlı olunan servisi ayağa kaldırıp daha sonra bağımlı servisi başlatabilir ve böylece servisler doğru sırada başlatılabilir.
systemd
ile boot sırasında belirlenen sırada başlatılan prosesler sistemin kapanışında da systemd
tarafından sonlandırılırlar. systemd
başlattığı proseslere SIGTERM
sinyali göndererek sistemin kapatılacağını proselere haber verir ve graceful
çıkış yapmalarını sağlar. Sistem kapatılması veya durdurulma sırasında systemd
'den SIGTERM
dışında bir sinyal almak isteyen prosesler unit
dosyalarına KillSignal=SIGINT
gibi bir tanımlama yaparak SIGTERM
yerine SIGINT
sinyalini alabilirler.