Temeller

systemd nedir, nasıl çalışır ve Linux servislerini nasıl yönetirsiniz

Güncellendi: · Skillaria.Top

systemd, Linux'un başlatma sistemi ve servis yöneticisidir: çekirdek onu ilk süreç (PID 1) olarak başlatır, diğer servisleri doğru sırayla açar ve izler. systemd'nin tüm işleri birimlerle (unit) tanımlanır; bunlar servislerin, zamanlayıcıların ve bağlama noktalarının metin açıklamalarıdır. systemctl ile bunlar başlatılır, durdurulur ve açılışa eklenir; journalctl ise günlüklerini gösterir.

systemd, çoğu modern Linux dağıtımında kullanılan bir başlatma sistemi ve servis yöneticisidir: Debian, Ubuntu, Fedora, RHEL ve türevleri. Açılıştan sonra çekirdek systemd'yi PID 1 numaralı ilk süreç olarak çalıştırır; ardından ağı açar, diskleri bağlar, web sunucusunu, veritabanını ve diğer her şeyi başlatır. Kısaca systemd, hangi servislerin çalışması gerektiğini, hangi sırayla başlatılacağını ve bir servis çöktüğünde ne yapılacağını bilen bir «yönetici»dir.

Gerçekten systemd kullanıp kullanmadığınızı kontrol etmek kolaydır:

$ ps -p 1 -o comm=
systemd

systemd neden ortaya çıktı

Linux'ta eskiden SysV init kullanılıyordu: /etc/init.d/ içindeki kabuk betikleri sırayla çalıştırılırdı. Anlaşılması kolaydı ama yavaş ve kırılgandı. Her betik kendi PID dosyasını yazmak, sürecin hayatta olup olmadığını kendisi anlamak zorundaydı ve çöken bir servisi yeniden başlatmak için ayrı bir düzenek gerekiyordu.

systemd bu işleri merkezi olarak çözer:

  • Paralel başlatma. Aralarında bağımlılık olmayan servisler aynı anda başlar, bu yüzden açılış hızlanır.
  • Bağımlılıklar ve sıra. Servis tanımında neye ihtiyaç duyduğu (örneğin ağ) ve ne zaman başlatılacağı açıkça yazılır.
  • Gözetim. systemd, cgroups aracılığıyla bir servisin tüm süreçlerini bilir ve çöktüğünde yeniden başlatabilir.
  • Tek günlük. Tüm servislerin çıktısını journald toplar; günlükler tek bir komutla okunur.
  • Tek arayüz. Her servis aynı şekilde yönetilir: systemctl start|stop|restart|status.

Yalnızca servis yöneticisi değil, systemd projesinin bir parçası olan başka bileşenler de vardır: journald (günlük), logind (kullanıcı oturumları), timesyncd (zaman eşitleme), resolved (DNS), networkd (ağ). Her dağıtım hepsini kullanmaz, ama PID 1 olarak systemd ve journald neredeyse her yerde bulunur.

Birimler: systemd neyden oluşur

systemd'nin yönettiği her şey birimlerle (unit) tanımlanır. Birim, INI biçiminde bir metin dosyasıdır ve türü uzantısından anlaşılır.

ead>
TürUzantıNeyi tanımlar
service.serviceservis: bir daemon süreci veya tek seferlik bir görev
timer.timerbaşka bir birimi zamanlamak (cron'un yerine)
socket.socketüzerine bağlantı geldiğinde servisi başlatan soket
target.targetbirimlerin grubu, yani «sistem durumu» (örneğin multi-user.target)
mount.mountbağlama noktası
path.pathbir dosyayı veya dizini izlemek

Unit dosyaları nerede durur

Birim dosyaları birkaç dizinde tutulur ve bunların bir öncelik sırası vardır:

  • /usr/lib/systemd/system/ (Debian ve Ubuntu'da ayrıca /lib/systemd/system/) — paketlerle kurulan birimler. Bunları elle değiştirmeyin: paket güncellendiğinde değişiklikleriniz üzerine yazılır.
  • /etc/systemd/system/ — yöneticinin birimleri ve geçersiz kılmaları. En yüksek önceliğe sahiptir.
  • /run/systemd/system/ — çalışma sırasında oluşturulan geçici birimler.

Bir birimin tüm geçersiz kılmalarla birlikte son içeriğini görmek için systemctl cat nginx.service kullanın.

Çalışma seviyeleri yerine target'lar

Eski runlevel'ların yerini target'lar aldı. multi-user.target grafik olmayan normal sunucu modudur, graphical.target grafik arayüzlüdür, rescue.target ise tek kullanıcılı kurtarma modudur. Varsayılan hedef systemctl get-default ile görülür, systemctl set-default multi-user.target ile değiştirilir.

systemctl: servisleri yönetmek

systemctl, systemd ile çalışmanın ana aracıdır. Komutların çoğu sistem durumunu değiştirir ve sudo gerektirir.

ead>
KomutNe yapar
systemctl status nginxservisin durumu, PID, bellek, günlüğün son satırları
systemctl start nginxhemen başlatmak
systemctl stop nginxdurdurmak
systemctl restart nginxyeniden başlatmak (stop + start)
systemctl reload nginxdurdurmadan yapılandırmayı yeniden okumak (servis destekliyorsa)
systemctl enable nginxaçılışta otomatik başlatmaya eklemek
systemctl disable nginxotomatik başlatmadan çıkarmak
systemctl enable --now nginxotomatik başlatmayı açmak ve hemen başlatmak
systemctl is-active nginxactive/inactive çıktısı — betiklerde kullanışlı
systemctl list-units --type=serviceyüklenmiş servislerin listesi
systemctl --failedhata veren birimler
systemctl daemon-reloadunit dosyasını değiştirdikten sonra yeniden yüklemek

systemctl status nasıl okunur

$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-10-12 09:14:03 UTC; 2h 5min ago
       Docs: man:nginx(8)
   Main PID: 812 (nginx)
      Tasks: 3 (limit: 2307)
     Memory: 6.1M
        CPU: 154ms
     CGroup: /system.slice/nginx.service
             ├─812 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             ├─813 "nginx: worker process"
             └─814 "nginx: worker process"

Loaded satırı unit dosyasının nereden alındığını ve açılış otomatik başlatmasının açık olup olmadığını (enabled) gösterir. Active satırı mevcut durumu verir: active (running), inactive (dead) veya failed. CGroup bloğu servisin tüm süreçlerini gösterir; systemd bir sürecin hangi servise ait olduğunu bu şekilde bilir.

enable ile start arasındaki fark

Bu sık karıştırılır. start servisi hemen çalıştırır, ama yeniden başlatmadan sonra kendiliğinden açılmaz. enable hedefin dizininde bir sembolik bağlantı oluşturur (örneğin /etc/systemd/system/multi-user.target.wants/); böylece açılışta servis başlar, ama o an çalıştırılmaz. İkisini birden istiyorsanız enable --now kullanın.

Üçüncü bir durum mask'tır. systemctl mask servis birimi /dev/null'a bağlar; artık ne elle ne de bağımlılık olarak başlatılabilir. Bir servisi kesin olarak kapalı tutmak gerektiğinde kullanılır.

journalctl: servislerin günlükleri

Bir servisin stdout ve stderr'ine yazdığı her şeyi systemd-journald yakalar ve birim adı, PID, öncelik ve zaman bilgileriyle birlikte ikili bir günlükte saklar. Günlüğü okumak için journalctl kullanılır.

journalctl -u nginx              # tek bir servisin günlüğü
journalctl -u nginx -f           # canlı izleme, tail -f gibi
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -n 50        # son 50 satır
journalctl -b                    # bu açılıştan beri
journalctl -b -1                 # önceki açılış
journalctl -p err -b             # yalnızca hatalar ve daha ciddileri
journalctl -k                    # çekirdek mesajları
journalctl --disk-usage          # günlüğün kapladığı alan

-p bayrağı syslog önceliğine göre süzer: emerg, alert, crit, err, warning, notice, info, debug. Verilen seviye ve ondan daha ciddi olan her şeyi gösterir.

Yeniden başlatmadan sonra günlük

Eğer /var/log/journal dizini yoksa ve /etc/systemd/journald.conf içinde Storage=auto varsa, günlük yalnızca bellekte (/run/log/journal) tutulur ve yeniden başlatmada kaybolur. Kalıcı yapmak için Storage=persistent ayarlayın ya da dizini oluşturup journald'ı yeniden başlatın. Boyut sınırı SystemMaxUse= ile belirlenir; eski kayıtlar journalctl --vacuum-time=2weeks veya --vacuum-size=500M ile temizlenir.

journald çoğu zaman rsyslog ile birlikte çalışır: günlük mesajlarını rsyslog'a verir, o da klasik metin dosyalarını /var/log/ içine yazar ve günlükleri merkezi bir sunucuya gönderebilir.

Servisinizi açılışta başlatmak: unit dosyası örneği

Diyelim ki ayakta tutulması, açılışta kalkması ve çöktüğünde yeniden başlaması gereken bir uygulamanız var: bir betik veya ikili dosya. /etc/systemd/system/myapp.service dosyasını oluşturun:

[Unit]
Description=My web application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=/etc/myapp/env
ExecStart=/opt/myapp/bin/server --port 8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Bölümleri tek tek inceleyelim:

  • [Unit] — açıklama ve bağımlılıklar. After= yalnızca sırayı belirler, Wants= yumuşak bir bağımlılıktır (birimi çek, ama o kalkmazsa çökme). Sert bağımlılık Requires= ile yazılır.
  • [Service] — nasıl başlatılacağı. Type=simple, ExecStart içindeki sürecin servisin kendisi olduğu ve arka plana geçmediği anlamına gelir. User= servisi ayrıcalıksız bir kullanıcıyla çalıştırır. Restart=on-failure hata ile biten servisi RestartSec saniye sonra yeniden başlatır.
  • [Install] — enable komutunun ne yaptığı. WantedBy=multi-user.target «normal açılışta çalıştır» demektir.

Uygulamak için:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp
journalctl -u myapp -f

Unit dosyalarında sık yapılan hatalar

  • ExecStart içinde göreli yol. Programın yolu mutlak olmalıdır. systemd, kabuğun yaptığı gibi kullanıcının PATH'inde komut aramaz.
  • daemon-reload unutulması. Dosyayı değiştirdikten sonra systemd eski sürümü kullanmaya devam eder ve bunu status çıktısında uyarır.
  • Daemon arka plana geçer. Program kendi kendine fork yapıyorsa ve Type=simple yazılmışsa, systemd servisin bittiğini sanar. Programı ön planda çalıştırın ya da PIDFile= ile Type=forking kullanın.
  • Profildeki ortam değişkenleri. Servis ~/.bashrc veya /etc/profile dosyalarını görmez. Değişkenleri Environment= veya EnvironmentFile= ile verin.

Paket birimini değiştirmeden geçersiz kılma

Bir paketin servisindeki ayarları, dosyasına dokunmadan değiştirmek için drop-in kullanılır:

sudo systemctl edit nginx

Bir editör açılır ve değişiklikler /etc/systemd/system/nginx.service.d/override.conf dosyasına kaydedilir. Örneğin oraya [Service] altında Restart=always yazabilirsiniz. Editörden çıkınca systemd yapılandırmayı kendisi yeniden okur.

cron yerine systemd zamanlayıcıları

Zamanlayıcı (timer), aynı adlı servisi zamanlayan bir birimdir. cron'a göre avantajları: görevin günlükleri journal'da tutulur, bağımlılıklar tanımlanabilir ve kaçırılan çalışmalar telafi edilebilir (Persistent=true). Günlük yedeklemeye örnek:

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers

OnCalendar ifadesini kontrol etmek için systemd-analyze calendar "*-*-* 03:00:00" çalıştırın: bir sonraki çalışma zamanını gösterir.

Açılış tanılama

systemd her birimin başlama zamanını tutar, bu yüzden yavaş açılışın nedenini kolayca bulabilirsiniz:

systemd-analyze                  # toplam açılış süresi
systemd-analyze blame            # birimler, başlama süresine göre
systemd-analyze critical-chain   # açılışı geciktiren zincir
systemd-analyze verify /etc/systemd/system/myapp.service   # unit dosyasını denetle

Sonuç

systemd, modern Linux'un PID 1'i ve servis yöneticisidir. Her şeyi birimlerle tanımlar, systemctl ile yönetilir, günlükleri journalctl ile okunan bir journal'da toplar ve cron yerine zamanlayıcılarla görev çalıştırabilir. Ona rahatça hâkim olmak için status, enable --now, journalctl -u komutlarını bilmek ve Restart=on-failure içeren basit bir unit dosyası yazabilmek yeterlidir. systemd, journald ve günlükleme, kurs içinde uygulamalı olarak işlenmektedir.

Sık sorulan sorular

Sistemimde systemd olup olmadığını nasıl anlarım?

<code>ps -p 1 -o comm=</code> komutunu çalıştırın. Çıktı systemd ise sistem systemd ile çalışıyor demektir. Ayrıca <code>/run/systemd/system</code> dizini yalnızca systemd ile açılışta bulunur.

systemctl restart ile reload arasındaki fark nedir?

restart servisi tamamen durdurup yeniden başlatır ve mevcut bağlantılar kopar. reload servisten yapılandırmayı durdurmadan yeniden okumasını ister; ancak bu yalnızca birimde <code>ExecReload</code> tanımlıysa çalışır.

systemd servislerini sudo olmadan, normal kullanıcı olarak çalıştırabilir miyim?

Evet, systemd'nin kullanıcı örneği vardır: birimleri <code>~/.config/systemd/user/</code> içine koyun ve <code>systemctl --user</code> ile yönetin. Aktif oturum olmadan da çalışmaları için <code>loginctl enable-linger</code> etkinleştirilmelidir.

Bir servis <code>failed</code> durumunda; bu durum nasıl sıfırlanır?

Nedeni <code>journalctl -u isim -b</code> ve <code>status</code> çıktısındaki <code>Active</code> satırında arayın. Düzelttikten sonra servisi yeniden başlatın; <code>failed</code> işareti yeniden başlatmadan <code>systemctl reset-failed</code> ile silinir.

systemd günlükleri diskte nerede tutulur?

Kalıcı ayarda <code>/var/log/journal/</code> içinde ikili biçimde, aksi halde <code>/run/log/journal/</code> içinde bellekte. Bunları metin araçlarıyla değil, <code>journalctl</code> ile okuyun.

Bu konuyu videoyla öğrenin

Bu konu “Linux: с нуля до уверенного администрирования” kursunda uygulamalı olarak ayrıntılı işleniyor.

Kursa git