Linux systemd ve Servis Yönetimi Rehberi: systemctl

systemctl komutlarıyla servisleri başlatmayı, journald ile günlük okumayı ve systemd zamanlayıcılarıyla tam otomasyon kurmayı örneklerle anlatan rehber.

Linux
Linux systemd ve Servis Yönetimi Rehberi: systemctl

Bir sunucu açıldığında sistemi ayağa kaldıran ilk süreç, çoğu modern Linux dağıtımında systemd'dir. Diğer tüm servisleri başlatmak, durumlarını izlemek ve gerektiğinde durdurmak bu sistemin görevidir; sunucu yönetimiyle uğraşan herkes er ya da geç systemd ile karşılaşır. Komut sayısı ilk bakışta fazla görünebilir, ama birkaç temel kavram oturduğunda günlük işler ciddi ölçüde kolaylaşır. Bu yazıda systemd'nin temel kavramlarını, servis yönetimini ve günlük kullanımda işe yarayacak systemctl komutlarını sırayla ele alıyorum.

systemd nedir, ünite kavramı ne demek

systemd, Linux çekirdeği yüklendikten hemen sonra çalışan ilk süreçtir ve sistemin "init sistemi" görevini üstlenir. Eski SysV init sistemi servisleri sırayla, birbirini bekleyerek başlatırken, systemd aralarında bağımlılık olmayan servisleri aynı anda açar. Bu paralel başlatma, özellikle çok sayıda servis çalıştıran sunucularda açılış süresini gözle görülür biçimde kısaltır; Ubuntu, Fedora ve Debian gibi büyük dağıtımların çoğu bu yüzden systemd'yi varsayılan olarak kullanıyor.

systemd'de yönetilen her bileşen bir "ünite" (unit) olarak tanımlanır. Servisler, bağlama noktaları, soketler ve zamanlayıcılar farklı ünite türleriyle temsil edilir; en sık karşılaşılanı .service uzantılı servis üniteleridir. Bu ortak yapı, sistemin farklı bileşenlerini aynı komut mantığıyla yönetmenizi sağlar. Teknik ayrıntılar için systemd'nin kendi belgeleri güvenilir bir kaynaktır.

Servisleri başlatma, durdurma, etkinleştirme

Bir servisi yönetmenin ana aracı systemctl komutudur. Temel işlemler şöyle görünür:

systemctl servis başlatma komutlarını gösteren terminal penceresi
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl status nginx

start komutu servisi hemen çalıştırır, ama bu geçici bir çalıştırmadır. Sistem yeniden başlatıldığında servis kendiliğinden açılmaz. Sistemle birlikte otomatik başlamasını istiyorsanız servisi etkinleştirmeniz gerekir:

sudo systemctl enable nginx
sudo systemctl disable nginx

enable ve start farklı işler yapar; sık yapılan bir hata, servisi yalnızca start ile çalıştırıp sistem yeniden başladığında servisin kaybolduğunu fark etmektir. İkisini tek adımda yapmak isterseniz sudo systemctl enable --now nginx komutu hem etkinleştirir hem başlatır. systemctl status çıktısı ise servisin aktif olup olmadığını, ne zaman başladığını ve son birkaç günlük satırını tek ekranda gösterir; sorun giderirken ilk bakılacak yer genelde burasıdır.

Ünite dosyalarını anlamak

Bir ünite dosyası, systemd'ye bir servisin nasıl yönetileceğini anlatan yapılandırma dosyasıdır ve genelde /etc/systemd/system/ altında bulunur. Üç ana bölümden oluşur:

[Unit]
Description=Örnek servis
After=network.target

[Service]
ExecStart=/usr/local/bin/uygulama
Restart=on-failure

[Install]
WantedBy=multi-user.target

[Unit] bölümü servisin açıklamasını ve bağımlılıklarını taşır, [Service] servisin nasıl çalıştırılacağını tanımlar, [Install] ise servisin hangi hedefe bağlı olarak etkinleştirileceğini belirtir. Restart=on-failure satırı servis çökerse systemd'nin onu otomatik olarak yeniden başlatmasını sağlar; üretim ortamındaki servislerde bu satırı eklemek küçük ama değerli bir önlemdir. WantedBy=multi-user.target servisin normal çok kullanıcılı çalışma durumunda etkinleşeceğini belirtir; masaüstü uygulamaları için bunun yerine graphical.target kullanılabilir.

Kendi servisinizi tanımladıktan sonra, systemd'nin bu dosyayı tanıması için önbelleği yenilemeniz gerekir:

sudo systemctl daemon-reload
sudo systemctl enable --now uygulama.service

Bu adımı atlamak sık karşılaşılan bir tuzaktır. Ünite dosyasını düzenledikten sonra daemon-reload çalıştırılmazsa, systemd hâlâ eski yapılandırmayı kullanmaya devam eder ve yapılan değişiklikler sessizce görmezden gelinir.

journald ile günlükleri okumak

systemd, journald adlı entegre bir günlük sistemiyle gelir ve servis günlüklerinden çekirdek mesajlarına kadar her şeyi tek bir yerde toplar. Dağınık log dosyalarında tek tek arama yapmak yerine tüm sistemi tek bir araçla sorgulayabilmek, sorun giderme sürecini ciddi ölçüde hızlandırır. Bir servisin günlüklerini görmek için:

journald günlük sorgulama komutunu gösteren terminal penceresi
journalctl -u nginx
journalctl -u nginx -f
journalctl -u nginx --since "1 hour ago"

-u belirli bir üniteyi filtreler, -f günlüğü canlı takip eder (tıpkı tail -f gibi), --since ise sorguyu belirli bir zaman aralığına daraltır. Bir servisin neden başarısız olduğunu araştırırken bu üç seçeneği birlikte kullanmak, sorunun kaynağını dakikalar içinde bulmanızı sağlar. journalctl -p err gibi bir öncelik filtresi eklemek, binlerce satır arasından yalnızca hata düzeyindeki kayıtları göstererek aramayı daha da hızlandırır.

Zamanlayıcılarla otomasyon kurmak

systemd zamanlayıcıları (timers), cron'a modern bir alternatif sunar ve systemd'nin günlük sistemine doğrudan bağlıdır. Bir zamanlayıcı, bir .timer dosyasıyla bir .service dosyasını birlikte kullanır:

Systemd servis bağımlılıkları ve başlatma sırasını gösteren infografik
# /etc/systemd/system/yedekleme.timer
[Unit]
Description=Günlük yedekleme zamanlayıcı

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

OnCalendar=daily görevi her gün çalıştırır, Persistent=true ise bilgisayar kapalıyken kaçırılan çalıştırmanın açılışta telafi edilmesini sağlar. Zamanlayıcıyı etkinleştirmek klasik bir servisle aynı adımı izler:

sudo systemctl enable --now yedekleme.timer
systemctl list-timers

list-timers komutu sistemde tanımlı tüm zamanlayıcıları ve bir sonraki çalışma zamanlarını listeler; cron'un aksine hangi görevin ne zaman çalışacağını görmek için ayrı bir tabloyu ezberlemeniz gerekmez. Zamanlayıcı tarafından tetiklenen bir görev başarısız olursa bu da doğrudan journald'a düşer, ayrı bir log dosyası aramanız gerekmez.

Bağımlılıklar ve hedefler (targets)

Gerçek sistemlerde servisler birbirine bağımlıdır; bir web uygulaması, veritabanı servisi çalışmadan anlamlı biçimde başlayamaz. systemd bu sırayı ünite dosyalarındaki After= ve Requires= satırlarıyla garanti eder. After= yalnızca başlatma sırasını belirtirken, Requires= bağımlı olunan servis çalışmazsa asıl servisin de başlamamasını zorunlu kılar; bu ince fark karmaşık sistemlerde önem kazanır.

Hedefler (targets), sistemin genel durumunu temsil eden ünite gruplarıdır ve eski init sistemlerindeki "çalışma seviyeleri" kavramının modern karşılığıdır. multi-user.target komut satırı odaklı bir çalışma durumunu, graphical.target ise grafik arayüzlü durumu temsil eder:

systemctl get-default
sudo systemctl set-default multi-user.target

Bir sunucuyu grafik arayüz olmadan, yalnızca gerekli servislerle çalıştırmak istediğinizde multi-user.target ayarlamak kaynak tüketimini azaltır ve saldırı yüzeyini küçültür.

Kaynak sınırlama ile cgroups

systemd her servisi kendi kontrol grubunda (cgroup) çalıştırır; bu sayede bir servisin işlemci veya bellek kullanımını sınırlayabilirsiniz. Örneğin kaynak yoğun bir servisin diğer servisleri etkilemesini önlemek için ünite dosyasına şu satırları ekleyebilirsiniz:

[Service]
MemoryMax=512M
CPUQuota=50%

MemoryMax servisin kullanabileceği azami belleği, CPUQuota ise işlemci payını sınırlar. Bu tür sınırlamalar, çok sayıda servis çalıştıran sunucularda birinin diğerlerini boğmasını engeller; aynı mantık modern konteyner teknolojilerinin de temelini oluşturur. Bellek sınırını aşan bir servis tüm sistemi kilitlemek yerine yalnızca kendisi sonlandırılır, bu da üretim sunucularında beklenmedik çökmelerin önüne geçer.

Bir servis beklenmedik biçimde çöktüğünde ya da başlamadığında, önce durumunu kontrol etmek en hızlı teşhis yöntemidir:

systemctl status uygulama.service
journalctl -u uygulama.service -n 50

Bu iki komut birlikte servisin son durumunu ve son elli satır günlüğünü gösterir; çoğu sorunun kaynağı bu çıktıda görünür hâle gelir. systemctl ve journalctl'ı günlük rutine dahil etmek, komutları ezberden çok pratikle öğrenmenin en doğal yolu; birkaç hafta düzenli kullanımdan sonra ikisi de refleks hâline gelir.

Limitleri belirlerken servisin gerçek kaynak kullanımını önce systemctl status ve journalctl çıktılarıyla birkaç gün gözlemleyin. Rastgele düşük bir değer koymak, servisi gereksiz yere sonlandırabilir.

Celil Uyanikoglu

Yazan Celil Uyanikoglu

Bilgisayar mühendisiyim; 25 yılı aşkın süredir bilgi işlem sektörünün içindeyim. Bu blogu 2020'de, işimde her gün karşılaştığım sorunların çözümlerini bir yere yazmak için açtım: Linux, güvenlik, tarayıcılar, yapay zeka araçları. Yazdığım her rehberi önce kendi bilgisayarımda ya da sunucumda deniyorum; çalıştığını görmediğim adımı yayınlamam. Hatalı ya da eskimiş bir şey görürsen iletişim sayfasından yaz — düzeltirim.

Yorum

Henüz yorum yok.

Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.

Yorum yap

E-posta adresin yayınlanmaz. Yorumlar moderasyondan sonra yayınlanır.

Sırada

İlgili notlar

jekcms 61602b0e6293b42004a1