systemctl ile Linux Servis Durumlarını İzleme, Başlatma ve Sorun Giderme

Üretim ortamında bir servis aniden durduğunda, ilk birkaç dakika çok kritik. O anın stresiyle yanlış komut çalıştırmak, log okumayı atlamak ya da durumu yanlış teşhis etmek saatlerce süren sorun giderme süreçlerine yol açabilir. systemctl bu noktada sadece bir araç değil, servis yönetiminin merkezi. Yıllardır Linux yönetiyorum ve şunu söyleyebilirim: systemctl‘i gerçekten anlamadan Linux servis yönetimi yapmak, arabayı göstergeler olmadan kullanmak gibi.

Bu yazıda sizi teoriden çok pratiğe götüreceğim. Servis başlatmaktan sorun gidermeye, unit dosyalarını okumaktan boot sürecini analiz etmeye kadar her konuya elimden geldiğince gerçek senaryolarla bakacağız.

systemd ve systemctl’ı Neden Anlamalısınız

Bir zamanlar SysV init vardı, sonra Upstart geldi, sonunda systemd kazandı. Sevseniz de sevmeseniz de bu tartışma artık kapandı. Debian, Ubuntu, RHEL, CentOS, Fedora, Arch, artık hepsi systemd kullanıyor. Dolayısıyla systemctl bilmek bir tercih değil, zorunluluk.

systemctl, systemd’nin kullanıcıya açılan yüzü. Servis başlatıp durdurabilir, sistem durumunu sorgulayabilir, boot hedeflerini yönetebilir, hatta sistem yeniden başlatma ve kapama işlemlerini bile bu araçla yapabilirsiniz. Tek bir komut, muazzam bir kontrol yüzeyi.

Temel Servis Durumlarını Anlama

Bir servisi kontrol etmenin en temel yolu status alt komutu. Ama çıktıyı doğru okumak önemli.

systemctl status nginx

Bu komutun çıktısında şunlara bakın:

  • Loaded: Unit dosyasının nerede olduğu ve enabled/disabled durumu
  • Active: Servisin şu anki çalışma durumu
  • Main PID: Ana süreç numarası
  • Tasks: Aktif görev sayısı
  • Memory: Bellek kullanımı
  • CGroup: Control group hiyerarşisi

Active satırında görebileceğiniz durumlar:

  • active (running): Servis çalışıyor, her şey yolunda
  • active (exited): Başarıyla tamamlandı ve çıktı (one-shot servisler için normal)
  • active (waiting): Bir olayı bekliyor
  • inactive (dead): Çalışmıyor
  • failed: Hata vererek durdu

Bir servisin son birkaç log satırını da status çıktısının altında görebilirsiniz. Bu ayrıntı, sorun gidermede çok değerli.

Servis Başlatma, Durdurma ve Yeniden Başlatma

Üretim ortamında en sık kullandığınız komutlar bunlar olacak.

# Servisi başlat
sudo systemctl start nginx

# Servisi durdur
sudo systemctl stop nginx

# Servisi yeniden başlat (stop + start)
sudo systemctl restart nginx

# Konfigürasyonu yeniden yükle (servisi durdurmadan)
sudo systemctl reload nginx

# Mümkünse reload, değilse restart yap
sudo systemctl reload-or-restart nginx

Burada reload ile restart arasındaki farkı iyi kavramak gerekiyor. restart, servisi tamamen öldürüp yeniden başlatır. Aktif bağlantılar kesilir. reload ise sinyalle sürece konfigürasyonu yeniden okumasını söyler. Nginx için bu fark kritik: canlı ortamda restart yerine mümkün olduğunca reload kullanın. Tabii servisi destekliyorsa.

Otomatik Başlatma Yönetimi

Sistem yeniden başladığında servisin otomatik başlamasını istiyorsanız:

# Servisi boot'ta otomatik başlat
sudo systemctl enable nginx

# Otomatik başlatmayı devre dışı bırak
sudo systemctl disable nginx

# Hem aktif et hem şu an başlat
sudo systemctl enable --now nginx

# Hem devre dışı bırak hem şu an durdur
sudo systemctl disable --now nginx

# Servisin enabled/disabled durumunu kontrol et
systemctl is-enabled nginx

enable komutu aslında arka planda sembolik link oluşturur. /etc/systemd/system/multi-user.target.wants/ gibi dizinlere servis unit dosyasının linkini ekler. Bu yüzden sistemin hangi hedefte (target) boot ettiğini bilmek önemli.

Tüm Servisleri Listeleme ve Filtreleme

Sistemde ne olduğunu genel olarak görmek istediğinizde:

# Çalışan tüm servisleri listele
systemctl list-units --type=service

# Sadece başarısız servisleri göster
systemctl list-units --type=service --state=failed

# Tüm unit'leri (çalışan ve çalışmayan) göster
systemctl list-units --type=service --all

# Boot'ta etkin olan tüm unit dosyalarını göster
systemctl list-unit-files --type=service

Ben genellikle bir sunucuya ilk bağlandığımda şunu çalıştırırım:

systemctl list-units --type=service --state=failed

Eğer bu liste boş çıkıyorsa, sunucu genel olarak sağlıklı demektir. Listede bir şeyler varsa, oradan başlarım incelemeye.

Servis Loglarını İnceleme

systemctl status servisin son birkaç satır logunu gösterse de derinlemesine inceleme için journalctl ile çalışmanız gerekiyor. Bu iki araç birbirini tamamlıyor.

# Servisin tüm loglarını göster
journalctl -u nginx

# Son 100 satırı göster
journalctl -u nginx -n 100

# Gerçek zamanlı log izleme
journalctl -u nginx -f

# Belirli bir zaman aralığındaki loglar
journalctl -u nginx --since "2024-01-15 10:00:00" --until "2024-01-15 12:00:00"

# Son boot'taki loglar
journalctl -u nginx -b

# Bir önceki boot'taki loglar (çökme sonrası çok işe yarar)
journalctl -u nginx -b -1

# Sadece hata ve kritik mesajlar
journalctl -u nginx -p err

Gerçek bir senaryo anlatayım. Bir keresinde sabah 3’te bir Django uygulaması çöktü. systemctl status gunicorn çıktısı servisi failed gösteriyordu ama son log satırları yeterliydi durumu anlamak için. journalctl -u gunicorn -b -n 50 çalıştırdım, veritabanı bağlantısının timeout aldığını gördüm. Sorun gunicorn’da değil, PostgreSQL servisinin hafıza baskısından yavaşlamasındaydı. Bu teşhisi koymak 5 dakika aldı, çünkü logları doğru okuyabiliyordum.

Bağımlılıkları Analiz Etme

Bir servis başlamıyorsa, bağımlılıklarından biri başlamıyor olabilir. systemd’nin en güçlü özelliklerinden biri bağımlılık yönetimi, ama bu aynı zamanda sorun kaynağı da olabilir.

# Bir servisin bağımlılıklarını göster
systemctl list-dependencies nginx

# Bağımlılık ağacını tersine çevir (buna bağlı olanları göster)
systemctl list-dependencies nginx --reverse

# Bağımlılıkları düz liste halinde göster
systemctl list-dependencies nginx --plain

Özellikle --reverse parametresi ilginç. Bir servisi durdurmak istediğinizde başka hangi servislerin etkileneceğini önceden görmenizi sağlar.

Unit Dosyalarını Okuma ve Anlama

Bir servisin davranışını anlamak için unit dosyasını okumayı öğrenmelisiniz.

# Unit dosyasının içeriğini göster
systemctl cat nginx

# Unit dosyasının tam yolunu ve parametrelerini göster
systemctl show nginx

# Belirli bir parametreyi göster
systemctl show nginx --property=ExecStart

# Unit dosyasını düzenle (override oluşturur)
sudo systemctl edit nginx

# Unit dosyasını doğrudan düzenle
sudo systemctl edit --full nginx

systemctl cat komutunu çok seviyorum çünkü hem asıl unit dosyasını hem de varsa override dosyalarını bir arada gösteriyor. Bir servisi neden böyle davrandığını anlamak için bu çıktıyı incelemek genellikle yeterli oluyor.

systemctl edit ise güzel bir özellik. Servisin asıl unit dosyasını değiştirmek yerine /etc/systemd/system/nginx.service.d/override.conf gibi bir dosya oluşturur. Paket güncellemelerinde orijinal dosyanın üzerine yazılsa bile override’larınız korunur.

Başarısız Servisleri Sıfırlama

Bir servis failed durumuna girdiğinde, systemd onu tekrar başlatmak için önce bu durumu temizlemenizi isteyebilir.

# Failed durumunu temizle
sudo systemctl reset-failed nginx

# Tüm failed servisleri temizle
sudo systemctl reset-failed

# Sonra yeniden başlat
sudo systemctl start nginx

Bu durumla en çok karşılaştığım senaryo şu: Bir servis art arda çöküp StartLimitIntervalSec sınırını aşıyor ve systemd onu artık otomatik yeniden başlatmıyor. systemctl status bunu açıkça söylüyor: “start request repeated too quickly”. Önce reset-failed, sonra start.

Boot Sürecini Analiz Etme

Sunucu yavaş boot ediyorsa veya boot sırasında bir şeyler ters gidiyorsa:

# Boot sürecinin genel analizi
systemd-analyze

# Her servisin boot'a katkısını göster (yavaştan hızlıya)
systemd-analyze blame

# Boot sürecinin görsel grafiğini oluştur
systemd-analyze plot > boot-analysis.svg

# Kritik zinciri göster
systemd-analyze critical-chain

# Belirli bir servis için kritik zincir
systemd-analyze critical-chain nginx

systemd-analyze blame çıktısı bazen şaşırtıcı sonuçlar verebilir. 30 saniyelik bir boot süresinde tek bir servisin 15 saniye aldığını görmek nadir değil. Genellikle bu ya yanlış yapılandırılmış bir ağ bağımlılığı ya da gereksiz yere çalışan bir discovery servisi oluyor.

Gerçek Dünya Sorun Giderme Senaryoları

Senaryo 1: Servis Başlamıyor

# 1. Durumu kontrol et
systemctl status uygulama.service

# 2. Detaylı log bak
journalctl -u uygulama.service -n 50 --no-pager

# 3. Unit dosyasını kontrol et
systemctl cat uygulama.service

# 4. Konfigürasyon dosyası varsa test et
nginx -t  # nginx için
# ya da
uygulama --config-test

# 5. Bağımlılıkları kontrol et
systemctl list-dependencies uygulama.service

Senaryo 2: Servis Periyodik Çöküyor

Bir servisin düzenli aralıklarla çöktüğünü fark ettiğinizde:

# Servisin yeniden başlatma geçmişine bak
journalctl -u uygulama.service --since "24 hours ago" | grep -E "Started|Stopped|Failed"

# Sistem kaynaklarını kontrol et (bellek, disk)
journalctl -b | grep -E "OOM|killed|out of memory"

# Servisin resource limitlerini gör
systemctl show uygulama.service | grep -E "Limit|Memory|CPU"

OOM killer çok sık suçludur bu tip durumlarda. Kernel bir süreci öldürdüğünde systemd bunu servis çöküşü olarak görür ve yeniden başlatır, bellek baskısı devam ederse döngü başlar.

Senaryo 3: Port Çakışması

# Servis başlamıyor, port çakışması şüphesi
journalctl -u nginx -n 20

# Hangi sürecin o portu kullandığını bul
sudo ss -tlnp | grep :80

# Ya da eski yöntem
sudo netstat -tlnp | grep :80

Sistem Geneli İzleme

Tek bir servisten çıkıp sistem geneline baktığınızda:

# Sistemin genel durumu
systemctl status

# Sadece failed olanları göster (hızlı kontrol için)
systemctl --failed

# Aktif olup "degraded" olan sistem durumunu sorgula
systemctl is-system-running

systemctl is-system-running exit code 0 dönüyorsa her şey yolunda demektir. degraded dönüyorsa bir veya daha fazla servis başarısız. Bu komutu monitoring scriptlerinde kullanabilirsiniz.

Masking: Bir Servisi Tamamen Kilitleme

Bazen bir servisi devre dışı bırakmak yetmez, tamamen engellemek istersiniz. Örneğin bir güvenlik politikası gereği.

# Servisi maskele (başlatılamaz hale getir)
sudo systemctl mask bluetooth.service

# Maskelemeyi kaldır
sudo systemctl unmask bluetooth.service

Maskeleme, unit dosyasını /dev/null‘a sembolik link yaparak çalışır. Ne start komutuyla ne de bağımlılık olarak başlatılabilir. disable‘dan çok daha güçlü bir engelleme.

Systemd ile İlgili Sık Yapılan Hatalar

Yıllar içinde hem kendimde hem başkalarında gördüğüm hatalar:

  • reload ile restart karıştırma: Production ortamında servisi gereksiz yere kesmek. Önce servis reload destekliyor mu kontrol edin.
  • daemon-reload unutmak: Unit dosyasını elle düzenlediğinizde systemd’ye bunu bildirmeniz gerekir. sudo systemctl daemon-reload çalıştırmayı atlarsanız değişiklikler uygulanmaz.
  • Log seviyesini daraltmamak: journalctl -u servis yerine direkt journalctl çalıştırıp tonlarca log içinde kaybolmak. -u ile servisi, -p ile seviyeyi filtreleyin.
  • enable ile start‘ı karıştırmak: enable servisi şu an başlatmaz, sadece boot’ta başlayacağını işaretler. enable --now ikisini birden yapar.
  • Bağımlılık sorunlarını atlamak: Bir servis başlamıyorsa sadece o servise bakıp bağımlılıklarını atlamak. list-dependencies her zaman ilk kontrol noktalarından biri olmalı.

Sonuç

systemctl basit görünen ama derinleştikçe gerçek gücünü ortaya koyan bir araç. Temel start/stop/status komutlarını hepimiz biliyoruz, asıl fark yaratan kısım journalctl ile entegrasyonu, bağımlılık yönetimini ve unit dosyası anatomisini kavramak.

Bir sonraki sorun gidermede şu sırayı deneyin: systemctl status ile genel duruma bakın, journalctl -u servis -n 50 ile loglara inin, systemctl cat ile unit dosyasını inceleyin, list-dependencies ile bağımlılıkları gözden geçirin. Bu dört adım vakaların büyük çoğunluğunda sizi doğru yöne götürür.

Linux servis yönetiminde gerçek uzmanlık, bir şeyler bozulduğunda sakin kalıp sistematik ilerlemekten geçiyor. systemctl bu sistematiğin tam merkezinde.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir