Systemd ile Linux Servislerini Etkin ve Kapsamlı Yönetme Kılavuzu
Linux dünyasında servis yönetimi, bir işletim sisteminin kararlılığı ve verimliliği için hayati öneme sahiptir. Modern Linux dağıtımlarının çoğunda standart hale gelen Systemd, bu görevi üstlenen güçlü bir başlangıç yöneticisi (init system) ve servis yöneticisidir. Geleneksel SysVinit'in yerini alarak, paralel başlangıç, isteğe bağlı aktivasyon, cgroup'lar üzerinden kaynak yönetimi ve kapsamlı günlük kaydı gibi özellikler sunar. Bu kapsamlı rehberde, Systemd'nin temellerinden başlayarak, servisleri nasıl kontrol edeceğimizi, kendi servislerimizi nasıl oluşturacağımızı ve yaygın sorunları nasıl gidereceğimizi adım adım inceleyeceğiz. Amacımız, Systemd'yi kullanarak sistem kaynaklarınızı daha verimli ve güvenli bir şekilde yönetmenizi sağlamaktır.
Systemd Temelleri ve Temel Komutlar
Systemd, her şeyi "birim" (unit) olarak ele alır. Bu birimler, servisleri, montaj noktalarını, soketleri, zamanlayıcıları ve diğer sistem kaynaklarını temsil eder. Servis yönetimi için en çok kullanılan komut, şüphesiz systemctl’dir. İşte sıkça kullanacağınız bazı temel komutlar:
Systemd Birim Dosyaları (Unit Files)
Systemd'nin kalbinde birim dosyaları bulunur. Bunlar, Systemd'ye belirli bir hizmetin nasıl başlatılacağını, durdurulacağını, bağımlılıklarını ve diğer davranışlarını bildiren düz metin dosyalarıdır. Birim dosyaları genellikle `/lib/systemd/system/` (paketlerden gelen varsayılanlar) ve `/etc/systemd/system/` (yöneticinin özel ayarları veya geçersiz kılmaları) dizinlerinde bulunur. `/etc/systemd/system/` içindeki dosyalar, `/lib/systemd/system/` içindeki aynı isimdeki dosyaları geçersiz kılar.
Yaygın birim tipleri şunlardır:
Kendi Systemd Servisimizi Oluşturma
Kendi uygulamanızı veya betiğinizi Systemd ile yönetmek, uygulamanızın sistem başlangıcında otomatik olarak başlamasını, hata durumunda yeniden başlatılmasını ve günlük kaydının merkezi olarak yönetilmesini sağlar. İşte basit bir örnek servis dosyası oluşturalım. Varsayalım ki `/opt/my-app/` dizininde `myscript.py` adında bir Python betiğimiz var ve bu betik sürekli çalışacak.
Önce basit bir Python betiği oluşturalım (`/opt/my-app/myscript.py`):
Bu betiği çalıştırılabilir hale getirin:
Şimdi bir Systemd servis dosyası (`/etc/systemd/system/my-app.service`) oluşturalım:
Birim dosyasının bölümlerini inceleyelim:
Servis dosyasını oluşturduktan sonra, Systemd'ye yeni dosyayı bildirmemiz gerekir:
Şimdi servisi başlatabilir ve etkinleştirebiliriz:
Durumunu kontrol etmek için:
Loglarını izlemek için:
Servis Bağımlılıklarını Yönetme
Systemd, servisler arasındaki bağımlılıkları oldukça esnek bir şekilde yönetir. Bu, belirli bir servisin başlamadan önce başka bir servisin çalışıyor olmasını veya belirli bir hedefe ulaşılmasını sağlamak için kritik öneme sahiptir. `[Unit]` bölümünde kullanılan bazı anahtarlar şunlardır:
Örneğin, veritabanı gerektiren bir web uygulamanız varsa, web uygulamanızın servisine `After=mysql.service` ve `Wants=mysql.service` ekleyebilirsiniz.
Günlük Yönetimi: journalctl
Systemd, tüm sistem ve uygulama günlüklerini tek bir merkezi konumda, Journal adı verilen bir sistemde toplar. Bu, logları izlemeyi ve sorun gidermeyi önemli ölçüde kolaylaştırır. `journalctl` komutu, bu günlükleri sorgulamak ve görüntülemek için kullanılır.
Journal, ikili bir formatta depolar, bu da onu hızlı ve sorgulanabilir kılar. Ancak, metin editörleri ile doğrudan okunamadığı anlamına gelir. `journalctl` komutu, bu ikili veriyi insan tarafından okunabilir formata dönüştürür.
Hedefler (Targets) ve Çalışma Seviyeleri
Systemd, geleneksel SysVinit'in çalışma seviyeleri (runlevels) konseptini hedefler (targets) ile değiştirmiştir. Hedefler, bir dizi birimi gruplayan ve belirli bir sistem durumunu temsil eden özel birimlerdir.
Yaygın hedefler:
Varsayılan hedefi kontrol etmek:
Varsayılan hedefi değiştirmek (örneğin, grafikselden çok kullanıcılıya geçmek):
Mevcut hedefi değiştirmek (sistemi yeniden başlatmadan):
Yaygın Sorun Giderme ve İpuçları
Systemd ile çalışırken karşılaşabileceğiniz bazı yaygın sorunlar ve çözüm ipuçları:
Sonuç
Systemd, modern Linux sistemlerinde servis kontrolünün bel kemiğidir. Sağladığı güçlü `systemctl` komut seti, esnek birim dosyası yapısı ve merkezi günlük kaydı (journal), sistem yöneticilerine ve geliştiricilere hizmetlerini daha verimli, güvenli ve kolay yönetilebilir hale getirme imkanı sunar. Kendi servislerinizi oluşturmaktan, var olanları yönetmeye ve sorun gidermeye kadar Systemd'ye hakim olmak, her Linux kullanıcısı için vazgeçilmez bir beceridir. Unutmayın, pratik yapmak ve Systemd'nin resmi belgelerine göz atmak, bilginizi pekiştirmenin en iyi yoludur. Bu rehberin, Systemd ile servis kontrolü konusunda size sağlam bir temel sağladığını umuyoruz.
Linux dünyasında servis yönetimi, bir işletim sisteminin kararlılığı ve verimliliği için hayati öneme sahiptir. Modern Linux dağıtımlarının çoğunda standart hale gelen Systemd, bu görevi üstlenen güçlü bir başlangıç yöneticisi (init system) ve servis yöneticisidir. Geleneksel SysVinit'in yerini alarak, paralel başlangıç, isteğe bağlı aktivasyon, cgroup'lar üzerinden kaynak yönetimi ve kapsamlı günlük kaydı gibi özellikler sunar. Bu kapsamlı rehberde, Systemd'nin temellerinden başlayarak, servisleri nasıl kontrol edeceğimizi, kendi servislerimizi nasıl oluşturacağımızı ve yaygın sorunları nasıl gidereceğimizi adım adım inceleyeceğiz. Amacımız, Systemd'yi kullanarak sistem kaynaklarınızı daha verimli ve güvenli bir şekilde yönetmenizi sağlamaktır.
Systemd Temelleri ve Temel Komutlar
Systemd, her şeyi "birim" (unit) olarak ele alır. Bu birimler, servisleri, montaj noktalarını, soketleri, zamanlayıcıları ve diğer sistem kaynaklarını temsil eder. Servis yönetimi için en çok kullanılan komut, şüphesiz systemctl’dir. İşte sıkça kullanacağınız bazı temel komutlar:
- Servis Durumunu Kontrol Etme: Bir servisin çalışıp çalışmadığını, etkinleştirilip etkinleştirilmediğini ve genel durumunu öğrenmek için:
Kod:systemctl status sshd
- Servisi Başlatma: Durmuş bir servisi başlatmak için:
Kod:systemctl start apache2
- Servisi Durdurma: Çalışan bir servisi durdurmak için:
Kod:systemctl stop nginx
- Servisi Yeniden Başlatma: Bir servisi durdurup tekrar başlatmak için. Bu, yapılandırma dosyalarında değişiklik yaptıktan sonra sıkça kullanılır:
Kod:systemctl restart php-fpm
- Servisi Yeniden Yükleme (Reload): Bazı servisler, tümüyle yeniden başlatılmadan yapılandırma dosyalarını yeniden yükleyebilir. Bu, kesinti süresini minimize eder:
Kod:systemctl reload dnsmasq
- Servisi Etkinleştirme (Enable): Sistemin başlangıcında otomatik olarak başlamasını sağlamak için:
Kod:systemctl enable firewalld
- Servisi Devre Dışı Bırakma (Disable): Sistemin başlangıcında otomatik başlamasını engellemek için:
Kod:systemctl disable cups
- Servisi Maskeleme (Mask): Bir servisin manuel olarak veya başka bir servis tarafından başlatılmasını tamamen engellemek için kullanılır. Bu, tehlikeli bir servisi tamamen devre dışı bırakmak için güçlü bir yöntemdir:
Kod:systemctl mask bluetooth
- Tüm Servisleri Listeleme: Çalışan ve durmuş tüm birimleri görmek için:
Kod:systemctl list-units --type=service
Systemd Birim Dosyaları (Unit Files)
Systemd'nin kalbinde birim dosyaları bulunur. Bunlar, Systemd'ye belirli bir hizmetin nasıl başlatılacağını, durdurulacağını, bağımlılıklarını ve diğer davranışlarını bildiren düz metin dosyalarıdır. Birim dosyaları genellikle `/lib/systemd/system/` (paketlerden gelen varsayılanlar) ve `/etc/systemd/system/` (yöneticinin özel ayarları veya geçersiz kılmaları) dizinlerinde bulunur. `/etc/systemd/system/` içindeki dosyalar, `/lib/systemd/system/` içindeki aynı isimdeki dosyaları geçersiz kılar.
Yaygın birim tipleri şunlardır:
- .service: Arka planda çalışan bir daemon veya hizmet.
- .socket: Bir ağ veya yerel soket üzerinden erişim bekleyen bir hizmet.
- .device: Çekirdek tarafından algılanan bir cihaz.
- .mount: Bir dosya sistemi bağlama noktası.
- .automount: İsteğe bağlı otomatik bağlama noktası.
- .timer: Cron gibi belirli zamanlarda tetiklenen bir olay.
- .path: Bir dosya veya dizin değişikliği algılandığında tetiklenen bir olay.
- .target: Birden fazla birimi gruplayan ve belirli bir sistem durumunu temsil eden birim (örneğin, `multi-user.target`).
Kendi Systemd Servisimizi Oluşturma
Kendi uygulamanızı veya betiğinizi Systemd ile yönetmek, uygulamanızın sistem başlangıcında otomatik olarak başlamasını, hata durumunda yeniden başlatılmasını ve günlük kaydının merkezi olarak yönetilmesini sağlar. İşte basit bir örnek servis dosyası oluşturalım. Varsayalım ki `/opt/my-app/` dizininde `myscript.py` adında bir Python betiğimiz var ve bu betik sürekli çalışacak.
Önce basit bir Python betiği oluşturalım (`/opt/my-app/myscript.py`):
Kod:
#!/usr/bin/env python3
import time
import os
LOG_FILE = "/var/log/my_app.log"
def main():
with open(LOG_FILE, "a") as f:
f.write(f"[{time.ctime()}] My script started with PID {os.getpid()}\n")
while True:
with open(LOG_FILE, "a") as f:
f.write(f"[{time.ctime()}] My script is running...\n")
time.sleep(5)
if __name__ == "__main__":
main()
Bu betiği çalıştırılabilir hale getirin:
Kod:
chmod +x /opt/my-app/myscript.py
Şimdi bir Systemd servis dosyası (`/etc/systemd/system/my-app.service`) oluşturalım:
Kod:
[Unit]
Description=My Custom Python Application Service
After=network.target
[Service]
ExecStart=/opt/my-app/myscript.py
WorkingDirectory=/opt/my-app/
StandardOutput=journal
StandardError=journal
Restart=always
User=www-data
Group=www-data
[Install]
WantedBy=multi-user.target
Birim dosyasının bölümlerini inceleyelim:
- [Unit]: Servis hakkında genel bilgiler ve bağımlılıklar.
* `Description`: Servisin kısa açıklaması.
* `After`: Bu servisin `network.target` (ağ servisleri) başladıktan sonra başlaması gerektiğini belirtir. Systemd, belirtilen bağımlılıklar karşılandığında servisi başlatmayı dener. - [Service]: Servisin nasıl çalıştırılacağı ve yönetileceği hakkında özel ayarlar.
* `ExecStart`: Servisi başlatmak için çalıştırılacak komut.
* `WorkingDirectory`: Servisin çalışacağı dizin.
* `StandardOutput` ve `StandardError`: Çıktının nereye yönlendirileceğini belirtir. `journal` olarak ayarlamak, tüm çıktıların Systemd günlük kaydı (journal) sistemine yönlendirilmesini sağlar. Bu, `journalctl` ile kolayca izlenebilir.
* `Restart=always`: Servis herhangi bir nedenle durduğunda (örneğin, çöktüğünde), Systemd'nin otomatik olarak yeniden başlatmasını sağlar. Diğer seçenekler: `on-failure`, `on-abort`, `no`.
* `User` ve `Group`: Servisin hangi kullanıcı ve grup altında çalışacağını belirtir. Güvenlik için, servisi mümkün olan en az yetkili kullanıcı altında çalıştırmak önemlidir. - [Install]: Servisin `systemctl enable` komutuyla nasıl etkinleştirileceğini tanımlar.
* `WantedBy`: Bu servisin hangi target (hedef) tarafından istendiğini belirtir. `multi-user.target`, genellikle sunucu sistemlerinin varsayılan çalışma seviyesidir ve Systemd'nin çok kullanıcılı bir ortamı başlattığı anlamına gelir. Bu, servisin sistem açıldığında otomatik olarak başlatılmasını sağlar.
Servis dosyasını oluşturduktan sonra, Systemd'ye yeni dosyayı bildirmemiz gerekir:
Kod:
systemctl daemon-reload
Kod:
systemctl start my-app
systemctl enable my-app
Kod:
systemctl status my-app
Kod:
journalctl -u my-app -f
Servis Bağımlılıklarını Yönetme
Systemd, servisler arasındaki bağımlılıkları oldukça esnek bir şekilde yönetir. Bu, belirli bir servisin başlamadan önce başka bir servisin çalışıyor olmasını veya belirli bir hedefe ulaşılmasını sağlamak için kritik öneme sahiptir. `[Unit]` bölümünde kullanılan bazı anahtarlar şunlardır:
- Requires=: Bu servisin başlaması için bağımlı olduğu servisin mutlaka başarılı bir şekilde başlaması gerektiğini belirtir. Eğer bağımlı servis başarısız olursa, bu servis de başlatılmaz.
- Wants=: `Requires`'a benzer, ancak daha zayıf bir bağımlılıktır. Bağımlı servis başlatılmaya çalışılır, ancak başarısız olsa bile ana servis yine de başlatılır. Bu, genellikle önerilen yöntemdir.
- After=: Bu servisin, belirtilen diğer servisler başladıktan sonra başlaması gerektiğini belirtir. Bu sadece sıralamayı belirler, başarılı başlatma garantisi vermez.
- Before=: Bu servisin, belirtilen diğer servisler başlamadan önce başlaması gerektiğini belirtir.
- Conflicts=: Bu servisin, belirtilen başka bir servisle çeliştiğini ve aynı anda çalışamayacağını belirtir. Biri başladığında diğeri durdurulur.
Örneğin, veritabanı gerektiren bir web uygulamanız varsa, web uygulamanızın servisine `After=mysql.service` ve `Wants=mysql.service` ekleyebilirsiniz.
Systemd'nin gücü, sadece servisleri başlatmakla kalmayıp, aynı zamanda onların tüm yaşam döngüsünü (başlatma, durdurma, yeniden başlatma, durum kontrolü ve hata kurtarma) entegre bir şekilde yönetebilmesinde yatar. Bu, karmaşık sistemlerin tutarlı ve öngörülebilir bir şekilde çalışmasını sağlar.
Günlük Yönetimi: journalctl
Systemd, tüm sistem ve uygulama günlüklerini tek bir merkezi konumda, Journal adı verilen bir sistemde toplar. Bu, logları izlemeyi ve sorun gidermeyi önemli ölçüde kolaylaştırır. `journalctl` komutu, bu günlükleri sorgulamak ve görüntülemek için kullanılır.
- Tüm Günlükleri Görüntüleme:
Kod:journalctl
- Belirli Bir Servisin Günlüklerini Görüntüleme:
Kod:journalctl -u my-app
- Günlükleri Canlı Takip Etme (Tail -f gibi):
Kod:journalctl -f
- Belirli Bir Süreden Sonraki Günlükleri Görüntüleme:
Kod:journalctl --since "2 hours ago"
Kod:journalctl --since "2023-01-15 10:00:00"
- Belirli Bir Süreye Kadarki Günlükleri Görüntüleme:
Kod:journalctl --until "yesterday"
- Sistem Önyüklemesine Göre Günlükleri Görüntüleme: `-b` veya `--boot` ile son önyüklemeden bu yana olan günlükleri görebilirsiniz. `journalctl --list-boots` ile önceki önyüklemeleri listeleyebilir ve indeks numarasını (`-b -1` gibi) kullanarak belirli bir önyüklemenin günlüklerini görüntüleyebilirsiniz.
Kod:journalctl -b 0
Kod:journalctl -b -1
- Disk Kullanımını Yönetme: Journal'ın diskte ne kadar yer kapladığını kontrol etmek ve temizlemek için:
Kod:journalctl --disk-usage
Kod:journalctl --vacuum-size=500M
Journal, ikili bir formatta depolar, bu da onu hızlı ve sorgulanabilir kılar. Ancak, metin editörleri ile doğrudan okunamadığı anlamına gelir. `journalctl` komutu, bu ikili veriyi insan tarafından okunabilir formata dönüştürür.
Hedefler (Targets) ve Çalışma Seviyeleri
Systemd, geleneksel SysVinit'in çalışma seviyeleri (runlevels) konseptini hedefler (targets) ile değiştirmiştir. Hedefler, bir dizi birimi gruplayan ve belirli bir sistem durumunu temsil eden özel birimlerdir.
Yaygın hedefler:
- multi-user.target: Komut satırı arayüzü olan, ağ servisi sağlayan ve çok kullanıcılı ortamlar için uygun varsayılan hedef. Sunucular genellikle bu hedefe önyüklenir.
- graphical.target: `multi-user.target`'ı içerir ve ek olarak grafiksel oturum yöneticilerini ve ilgili hizmetleri başlatır. Masaüstü ortamları için varsayılan hedeftir.
- rescue.target: Sadece minimum sistem hizmetlerini ve bir kök kabuğu başlatan tek kullanıcılı bir mod. Sistem kurtarma durumları için faydalıdır.
- emergency.target: `rescue.target`'tan daha da minimal, sadece temel dosya sistemlerini bağlar ve kök kabuğu başlatır. Ciddi sorun giderme için kullanılır.
- reboot.target: Sistemi yeniden başlatmak için kullanılır.
- poweroff.target: Sistemi kapatmak için kullanılır.
Varsayılan hedefi kontrol etmek:
Kod:
systemctl get-default
Kod:
systemctl set-default multi-user.target
Kod:
systemctl isolate graphical.target
Yaygın Sorun Giderme ve İpuçları
Systemd ile çalışırken karşılaşabileceğiniz bazı yaygın sorunlar ve çözüm ipuçları:
- Servis Başlatılamıyor:
* `systemctl status [servis_adı]` komutuyla servis durumunu ve hata mesajlarını kontrol edin.
* `journalctl -u [servis_adı] -b -f` ile servise ait tüm günlükleri canlı olarak izleyin. Genellikle hatanın kökeni burada belirir.
* Servis dosyanızdaki `ExecStart` yolunun doğru olduğundan ve betiğin çalıştırılabilir izinlere sahip olduğundan emin olun (`chmod +x`).
* `User` ve `Group` ayarlarının doğru ve yetkilendirildiğinden emin olun. Servisin erişmesi gereken dosya ve dizinlere sahip olması gereken izinleri kontrol edin.
* `ExecStart` içindeki komutları Systemd dışında manuel olarak çalıştırmayı deneyin. Çalışmıyorsa, sorun Systemd'den değil, betiğin kendisinden kaynaklanıyordur. - Daemon Yeniden Yüklemesi: Bir servis dosyasında değişiklik yaptıktan sonra her zaman `systemctl daemon-reload` komutunu çalıştırmayı unutmayın. Aksi takdirde Systemd, eski yapılandırmayı kullanmaya devam eder.
- Sıralama Sorunları: Servislerin doğru sırada başlamadığını fark ederseniz, servis dosyasındaki `After=` ve `Requires=` yönergelerini gözden geçirin. Bazen sadece `After=` kullanmak yetmeyebilir, servisin gerçekten başlatılmasını garanti etmek için `Requires=` gerekebilir.
- Kaynak Limitleri: Bazı servisler çok fazla bellek veya CPU kullanabilir. Systemd, cgroup'lar aracılığıyla kaynak limitleri ayarlamanıza olanak tanır. `CPUQuota=`, `MemoryLimit=` gibi yönergeler servis dosyasının `[Service]` bölümüne eklenebilir. Daha fazla bilgi için systemd.resource-control man sayfası'na bakabilirsiniz.
- Maskeleme Etkisi: Bir servisi maskelediyseniz ve neden başlamadığını merak ediyorsanız, `systemctl status` çıktısında "masked" durumunu kontrol edin. `systemctl unmask [servis_adı]` ile maskeyi kaldırın.
Sonuç
Systemd, modern Linux sistemlerinde servis kontrolünün bel kemiğidir. Sağladığı güçlü `systemctl` komut seti, esnek birim dosyası yapısı ve merkezi günlük kaydı (journal), sistem yöneticilerine ve geliştiricilere hizmetlerini daha verimli, güvenli ve kolay yönetilebilir hale getirme imkanı sunar. Kendi servislerinizi oluşturmaktan, var olanları yönetmeye ve sorun gidermeye kadar Systemd'ye hakim olmak, her Linux kullanıcısı için vazgeçilmez bir beceridir. Unutmayın, pratik yapmak ve Systemd'nin resmi belgelerine göz atmak, bilginizi pekiştirmenin en iyi yoludur. Bu rehberin, Systemd ile servis kontrolü konusunda size sağlam bir temel sağladığını umuyoruz.