Systemd Unit Dosyası Oluşturma ve Servis Yönetimi: Derinlemesine Bir Rehber

 · 

Systemd Unit Dosyası Oluşturma ve Servis Yönetimi: Derinlemesine Bir Rehber

Systemd Unit Dosyası Oluşturma ve Servis Yönetimi: Derinlemesine Bir Rehber

Linux sistemlerinde servislerin yaşam döngüsünü yönetmek, modern altyapıların kararlılığı ve verimliliği için kritik öneme sahiptir. Systemd, bu yönetimi standartlaştıran ve otomatikleştiren güçlü bir sistem ve servis yöneticisidir. Bu rehber, özel servisleriniz için systemd unit dosyalarını nasıl oluşturacağınızı, yapılandıracağınızı ve yöneteceğinizi adım adım açıklayacaktır.

Systemd Unit Dosyalarının Temel Yapısı

Bir systemd unit dosyası, genellikle .service uzantısına sahip metin dosyalarıdır ve servislerin nasıl başlatılacağını, durdurulacağını, yeniden başlatılacağını ve hangi bağımlılıklara sahip olacağını tanımlar. Bu dosyalar, /etc/systemd/system/ veya /usr/lib/systemd/system/ gibi dizinlerde bulunur. Temel bir .service dosyası üç ana bölümden oluşur:

[Unit] Bölümü

Bu bölüm, unit'in meta verilerini ve diğer unit'lerle olan ilişkilerini tanımlar. En sık kullanılan direktifler şunlardır:

  • Description=: Servis için açıklayıcı bir metin.
  • After=: Bu unit'in başlatılmasından sonra başlatılacak diğer unit'ler. Örneğin, network.target veya mysql.service.
  • Requires=: Bu unit'in başarılı bir şekilde çalışması için kesinlikle başlatılması gereken diğer unit'ler.
  • Wants=: Bu unit başlatıldığında isteğe bağlı olarak başlatılacak diğer unit'ler.

[Service] Bölümü

Bu bölüm, servisin kendisini nasıl çalıştıracağını ve yönetileceğini belirler. Önemli direktifler şunlardır:

  • Type=: Servisin başlatılma türünü belirtir (simple, forking, oneshot, notify, dbus). Çoğu modern servis için simple veya notify tercih edilir.
  • ExecStart=: Servisi başlatmak için çalıştırılacak komut.
  • ExecStop=: Servisi durdurmak için çalıştırılacak komut.
  • Restart=: Servis beklenmedik bir şekilde sonlandığında yeniden başlatma politikasını belirler (on-success, on-failure, always).
  • User= ve Group=: Servisin hangi kullanıcı ve grupla çalıştırılacağını belirtir. Güvenlik açısından önemlidir.

[Install] Bölümü

Bu bölüm, unit'in systemctl enable komutuyla nasıl etkinleştirileceğini tanımlar. En sık kullanılan direktif şudur:

  • WantedBy=: Unit'in hangi hedef (target) ile ilişkilendirileceğini belirtir. Örneğin, multi-user.target sistemin normal çalışma modunu temsil eder.

Örnek: Özel Bir Web Servisi İçin Unit Dosyası

Diyelim ki, Python ile yazdığınız ve /opt/mywebapp/app.py adresinde bulunan özel bir web uygulamasını çalıştıracaksınız. Bu uygulamanın 8080 portunda dinlemesini ve belirli bir kullanıcı altında çalışmasını istiyorsunuz. İşte bu servis için örnek bir systemd unit dosyası:

# /etc/systemd/system/mywebapp.service

[Unit]
Description=My Custom Web Application
After=network.target

[Service]
Type=simple
User=webappuser
Group=webappgroup
WorkingDirectory=/opt/mywebapp
ExecStart=/usr/bin/python3 /opt/mywebapp/app.py --port 8080
Restart=on-failure

[Install]
WantedBy=multi-user.target

Kod Açıklaması:

  • Description: Servisimiz için kısa bir açıklama.
  • After=network.target: Web uygulamamızın ağ bağlantısı kurulduktan sonra başlamasını sağlar.
  • Type=simple: Uygulamanın ana işlemi başlatıldıktan sonra servisin çalıştığı anlamına gelir.
  • User=webappuser ve Group=webappgroup: Uygulamanın ayrıcalıkları kısıtlanmış bir kullanıcı altında çalıştırılmasını sağlar. Bu, güvenlik için standart bir uygulamadır.
  • WorkingDirectory: Python betiğimizin çalışacağı dizini belirtir.
  • ExecStart: Servisi başlatacak tam komutu belirtir. Python 3 yorumlayıcısı ve uygulama betiğinin yolu verilmiştir.
  • Restart=on-failure: Uygulama bir hata nedeniyle çökerse, systemd servisi otomatik olarak yeniden başlatmaya çalışacaktır.
  • WantedBy=multi-user.target: Sistem açıldığında bu servisin otomatik olarak başlatılmasını sağlar (eğer etkinleştirilirse).

Servis Yönetimi Komutları

systemd unit dosyalarınızı oluşturduktan ve kaydettikten sonra, servisleri yönetmek için systemctl komutunu kullanırsınız:

  • sudo systemctl daemon-reload: Yeni veya değiştirilmiş unit dosyalarını systemd'nin tanıması için bu komutu çalıştırmanız gerekir.
  • sudo systemctl start mywebapp.service: Servisi manuel olarak başlatır.
  • sudo systemctl stop mywebapp.service: Servisi manuel olarak durdurur.
  • sudo systemctl restart mywebapp.service: Servisi yeniden başlatır.
  • sudo systemctl status mywebapp.service: Servisin mevcut durumunu (çalışıyor, durduruldu, hata vb.) ve son loglarını gösterir. Bu, hata ayıklama için en önemli komutlardan biridir.
  • sudo systemctl enable mywebapp.service: Sistem açıldığında servisin otomatik olarak başlamasını sağlar.
  • sudo systemctl disable mywebapp.service: Sistem açıldığında servisin otomatik olarak başlamasını engeller.
  • sudo systemctl is-enabled mywebapp.service: Servisin etkin olup olmadığını kontrol eder.

Gerçek Production Senaryoları ve İpuçları

Senaryo 1: Bağımlılık Yönetimi

Bir veritabanı servisi (örn. PostgreSQL) başlamadan önce ağın hazır olmasını sağlamak için After=network.target kullanmak standarttır. Ancak, veritabanının kendisi hazır olmadan başka bir servisin başlamasını önlemek için Requires=postgresql.service veya After=postgresql.service gibi direktifler kullanılır. Production ortamında, servisler arasındaki doğru bağımlılık sıralaması, sistemin tutarlı ve kararlı çalışmasını garantiler.

Senaryo 2: Kaynak Kısıtlamaları

Özellikle yoğun kaynak kullanan servisler için systemd, cgroups entegrasyonu sayesinde kaynakları kısıtlama yeteneği sunar. [Service] bölümüne CPUQuota=, MemoryLimit= gibi direktifler ekleyerek belirli bir servisin kullanabileceği CPU ve bellek miktarını sınırlayabilirsiniz. Bu, bir servisin sistemin tamamını tüketmesini engelleyerek diğer kritik servislerin çalışmasını güvence altına alır.

Senaryo 3: Loglama ve Hata Ayıklama

systemctl status komutu, servisin çıktısını ve hatalarını journald üzerinden toplar. Daha detaylı loglama için, servisinizin kendi içindeki loglama mekanizmalarını yapılandırmak ve journald'nin bunları doğru bir şekilde işlemesini sağlamak önemlidir. Örneğin, servisinizin loglarını belirli bir dosyaya yazmasını sağlayabilir ve systemd unit dosyasında StandardOutput=file:/var/log/mywebapp.log ve StandardError=file:/var/log/mywebapp.error.log gibi direktiflerle bu dosyaları journald'ye yönlendirebilirsiniz.

Senaryo 4: Forking Servisler

Geleneksel daemon'lar genellikle fork işlemiyle arka plana geçer. Bu tür servisler için Type=forking kullanılır ve PIDFile= direktifi ile ana işlemin PID'sinin tutulduğu dosyanın belirtilmesi gerekir. Ancak, modern uygulamalar genellikle Type=simple veya Type=notify ile doğrudan çalışır ve bu daha kolay yönetim sağlar.

Ek İpucu: Güvenlik

Servislerinizi mümkün olan en düşük ayrıcalıklı kullanıcı altında çalıştırın. PrivateTmp=yes, ProtectSystem=full, NoNewPrivileges=yes gibi direktifler, servisin erişebileceği dosya sistemlerini, ağ portlarını ve yetkilerini kısıtlayarak güvenlik duruşunu önemli ölçüde iyileştirir.

← Blog Listesine Dön