2 Ağustos 2018 Perşembe

systemd ile linux başlangıçta program çalıştırma

Linux sunucu yönetimine başlayan birçok kişinin zorlandığı konulardan biri sistem başlangıcında komut veya program çalıştırma oluyor. Bunun bir çok sebebi var fakat en bariz olanı farklı linux dağıtımlarının farklı init sistemleri yani windows terimleriyle ifade etmek gerekirse farklı servis, hizmet yöneticileri kullanmasıdır. systemd ise artık hemen hemen her linux dağıtımda standart olan, oldukça kapsamlı bir init sistemi, servis yöneticisidir. Kernel yani işletim sistemimiz çekirdeği yüklendikten sonra systemd devreye girer ver kabuk ortamı yani bash dahil tüm temel başlangıç servislerini, aygıtlarını ve diğer unitleri yükler.


systemd den önce her linux dağıtımı farklı bir init sistemi kullanıyordu. ubuntu14 ve bazı debian sürümlerinde upstart, daha bazı linux sistemlerde init yaygın olarak kullanılan daha basit ve sade sistemlerdi. systemd ise bunlardan çok daha kapsamlı işletim sisteminin her yerine müdehalede bulunan daha büyük bir init sistemi. Sadece başlangıç yönetimi ve servisler ile kalmıyor unit sistemi sayesinde aygıtlardan, dizin bağlantılarına işletim sisteminin bir çok noktasına müdehalede bulunuyor. Bu nedenle ufak programların sadece kendi işlerini yapması üzerine kurulu linux felsefesine uyumlu olmadığı düşünüldüğü için yaygınlaşması zaman aldı. Fakat şu an centos7 den ubuntu16 ya hatta archlinux'e kadar birbirinden oldukça farklı dağıtımlar systemd kullanıyor.


systemd unit mantığı oldukça geniş bunla ilgili uzun uzun yazmaktansa ubuntu'nun sitesine link vermeyi daha faydalı buluyorum. Oldukça güzel çevrilmiş yararlı bir kaynak:

Systemd servislerini ubuntu altında /etc/systemd/system dizinine kaydediyor. Bu dizinde temel 1-2 servis dışında sistem servislerinin yapılandırma dosyaları bulunmuyor. 

nano /etc/system/systemd/denemescript.service

ile gerekli servis dosyamızı oluşturyor ve aşağıdaki gibi yapılandırıyoruz:

[Unit]
Description=denemescript
Requires=local-fs.target network-online.target
After=local-fs.target network-online.target

[Service]
Environment=envdegisken1=deger1
Environment=envdegisken2=deger2
Environment=envdegisken3=deger3
User=root
Group=root
Type=simple
ExecStart=/root/denemescript.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Dosyayı oluşturmak servisin başlangıca yerleşmesi anlamına gelmiyor. Programın başlangıçta çalışması için:

systemctl enable denemescript.service

komutunu kullanıyoruz. Servisi el ile başlatıp durmak içinse

systemctl start denemescript.service
systemctl stop denemescript.service

komutlarını kullanabiliriz.

Dosyanın sonunda .service olması dikkatinizi çekmiştir. Bunun özel bir anlamı var. service tipi systemd unitlerinden sadece biri. Diğer tipler için yukarıdaki ubuntu linkine göz atın derim.  Bu arada .service unit tipi için systemctl de .service ifadesini kullanmadan da işlem yapabiliyoruz. Aşağıdaki komutlar da çalışacaktır.

systemctl enable denemescript
systemctl start denemescript
systemctl stop denemescript

servis hakkında ne kadar süredir çalışıyor, son ekran çıktısı gibi bilgileri almak için:
systemctl status denemescript

Bunun dışında yapılandırma dosyasındaki Requires, After, WantedBy gibi ifadeler servisin diğer systemd unitleri ile olan ilişkilerini belirliyor. Bu haliyle kernelden sonraki çoklu kullanıcı ortamı yüklendikten ve network-online işlemi gerçekleştikten sonra servisimiz çalışacak. Eğer sonlanırsa Restart komutları sayesinde 10 saniye bekleyip tekrardan çalışacak. Bu şekilde bir yapılandırmayı yaygın olarak kullanmamım sebebi birbiriyle ilişkili servislerinin sorunsuzca başlatılabilmesini sağlaması. Örneğin mongodb yi ve mongodb yi kullanan scripti bu şekilde iki ayrı servis olarak eklediğimizi düşünelim. script mongodb den önce çalışırsa bağlantı sağlayamadığından çalışamayacak ve sonlanacak, fakat systemd aynı scripti 10 saniye sonra tekrar çalıştırmayı denediğinde veritabanı uygun olacağından bağlanacaktır.

Systemd logları varsayılan olarak dosyaya kaydetmiyor. Tabi bunu istersek >> operatoru ile execstart'da el ile verebiliriz fakat buna gerek yok. syslog'da tutulan bu loglara journalctl ile erişebiliyoruz. Örneğin

journalctl -u denemescript

ile loglara erişebilir ve:
journalctl -u denemescript -f

ile logları akarken stream olarak izleyebiliriz. Burdaki -u parametresi unit in kısaltmasıdır.

Sistemde şu an çalışan tüm systemd servis unitlerini görnek için şu komutu kullanabilirsiniz:
systemctl list-units --type service --state running

Hiç yorum yok:

Yorum Gönder

hmm