systemd nedir, nasıl çalışır ve Linux servislerini nasıl yönetirsiniz
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ür | Uzantı | Neyi tanımlar |
| service | .service | servis: bir daemon süreci veya tek seferlik bir görev |
| timer | .timer | başka bir birimi zamanlamak (cron'un yerine) |
| socket | .socket | üzerine bağlantı geldiğinde servisi başlatan soket |
| target | .target | birimlerin grubu, yani «sistem durumu» (örneğin multi-user.target) |
| mount | .mount | bağlama noktası |
| path | .path | bir 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> | |
|---|---|
| Komut | Ne yapar |
systemctl status nginx | servisin durumu, PID, bellek, günlüğün son satırları |
systemctl start nginx | hemen başlatmak |
systemctl stop nginx | durdurmak |
systemctl restart nginx | yeniden başlatmak (stop + start) |
systemctl reload nginx | durdurmadan yapılandırmayı yeniden okumak (servis destekliyorsa) |
systemctl enable nginx | açılışta otomatik başlatmaya eklemek |
systemctl disable nginx | otomatik başlatmadan çıkarmak |
systemctl enable --now nginx | otomatik başlatmayı açmak ve hemen başlatmak |
systemctl is-active nginx | active/inactive çıktısı — betiklerde kullanışlı |
systemctl list-units --type=service | yüklenmiş servislerin listesi |
systemctl --failed | hata veren birimler |
systemctl daemon-reload | unit 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ıkRequires=ile yazılır. - [Service] — nasıl başlatılacağı.
Type=simple,ExecStartiç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-failurehata ile biten servisiRestartSecsaniye sonra yeniden başlatır. - [Install] —
enablekomutunun 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=simpleyazılmışsa, systemd servisin bittiğini sanar. Programı ön planda çalıştırın ya daPIDFile=ileType=forkingkullanın. - Profildeki ortam değişkenleri. Servis
~/.bashrcveya/etc/profiledosyalarını görmez. DeğişkenleriEnvironment=veyaEnvironmentFile=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 konu “Linux: с нуля до уверенного администрирования” kursunda uygulamalı olarak ayrıntılı işleniyor.
- systemd: как на самом деле запускаются сервисы в современном Linux
- Журналы и мониторинг: journald, rsyslog и sysstat