systemd neden kazandı ve tarihçesi nedir?
SysV init sisteminin eksiklerini, Upstart ve launchd girişimlerini inceleyin. systemd neden dört yılda standart oldu ve yöneltilen haklı eleştiriler nelerdi?
Neden systemd kazandı
systemd tarihçesi, SysV init sisteminin yapamadığı iki temel özellikle başlar. SysV init (Linux'un AT&T Unix'ten devraldığı başlatma sistemi), bir servisin nelere bağımlı olduğunu tanımlayamaz ve çalışmaya başladıktan sonra hangi süreçlerin o servise ait olduğunu takip edemezdi. systemd, bu iki soruna da shell script ile erişilemeyen çekirdek özellikleri kullanarak yanıt verdi: süreç takibi için control groups ve servis sıralaması için önceden açılmış dinleme soketleri. Hikayenin geri kalanı, bu iki çözümün kullanıcı alanının geri kalanına nasıl yayıldığıyla ilgilidir; itirazların başladığı nokta burasıdır ve bu itirazların birçoğu haklıydı.
SysV init aslında ne yapıyordu
Bir SysV sisteminde, PID 1 (çekirdeğin başlattığı ilk süreç olan süreç kimliği), /etc/inittab dosyasını okur, bir çalışma seviyesi (runlevel) seçer ve o çalışma seviyesi için gerekli betikleri çalıştırırdı. Betikler /etc/init.d/ dizininde bulunurdu. /etc/rc3.d/ içindeki sembolik bağlantılar, hangilerinin hangi sırada çalışacağına karar verirdi; bu nedenle /etc/rc3.d/S20nginx, /etc/init.d/nginx dosyasına işaret eder ve start argümanı ile çağrılırdı.
#!/bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO
case "$1" in
start)
start-stop-daemon --start --quiet --pidfile /run/nginx.pid \
--exec /usr/sbin/nginx
;;
stop)
start-stop-daemon --stop --quiet --retry TERM/30/KILL/5 \
--pidfile /run/nginx.pid
;;
esacS20nginx içindeki 20 bir bağımlılık değil, bir konumdur. Bu, betiğin S19 sonrasında ve S21 öncesinde çalıştığını belirtir. Nedenini belirtmediği için hiçbir mekanizma bunu denetleyemez ve bir insan güvenli olduğuna karar vermedikçe, birbiriyle ilişkisiz iki betiği aynı anda güvenli bir şekilde çalıştıramaz.
rc programı, her betiği sırayla çalıştırır ve çıkış yapmalarını beklerdi. Bir ağ adresi beklerken otuz saniye boyunca takılı kalan bir betik, ağ ile hiçbir ilgisi olmayan servisler için bile tüm önyükleme sürecini otuz saniye boyunca engellerdi.
Söz konusu betiğin en üstündeki LSB (Linux Standard Base) başlığı, bu sorunu içeriden çözmeye yönelik bir girişimdi. 2011 yılında Debian 6.0, insserv sistemini varsayılan hale getirdi: bu sistem, her betikten Required-Start verisini okur, bir grafik oluşturur ve sembolik bağlantıları yeniden numaralandırırdı. Debian bu sayede bağımsız betikleri startpar ile aynı anda çalıştırabiliyordu. Bu durum yardımcı oldu ancak daha derin sorunu çözemedi. Bağımlılık hala bir betiğin sonlanmasına bağlıydı. S20nginx değerinin 0 dönmesi, bir kabuk fonksiyonunun başarıyla tamamlandığı anlamına gelir. Bu, nginx'in bağlantı kabul ettiği anlamına gelmez.
Hiçbir init betiğinin düzeltemediği beş sorun
- Paralel başlatma. Dosya adına göre sıralama, makinedeki her servis üzerinde tam bir sıralama zorunluluğu getirir; bu nedenle önyükleme süreci, tüm parçaların toplam süresi kadar yavaş gerçekleşir.
- Hazır olma durumu. Bir başlatma betiği, daemon sürecini oluşturduğunda (fork) değil, daemon bir isteği karşılayabilir hale geldiğinde sonlanmalıdır; ancak init betikleri bunu bilmediğinden, bir sonraki betik genellikle çok erken çalışmaya başlar.
- Denetim (Supervision). Bir daemon iki kez fork işlemi gerçekleştirir ve ebeveyn süreci sonlanır; bu durum daemon'ı terminalden ayırır ve PID 1'e bağlar. init, bir alt sürecin sonlandığını görür ancak hayatta kalan süreçle güvenilir bir bağ kuramaz.
- İsteğe bağlı başlatma (On-demand start). inetd (internet süper sunucusu), bir bağlantı geldiğinde daemon başlatabilirdi ancak bu, kendi yapılandırma dosyasına sahip ayrı bir sistemdi ve önyükleme sırasında diğer her şeyin sıralanması konusunda hiçbir işlev görmüyordu.
- Kaynak kontrolü. Bir init betiğinde, servisin bellek kullanımını veya CPU payını sınırlayacak hiçbir mekanizma yoktu.
ulimityalnızca tek bir sürece uygulanabiliyordu veniceyalnızca zamanlayıcıya (scheduler) etki ediyordu; bu nedenle, bir servisin kontrolden çıkan alt süreci, sistemdeki diğer herhangi bir süreçten farksız görünüyordu.
Denetim boşluğu, günlük operasyonlarda en çok zarar veren sorundu. PID dosyası bu duruma karşı geliştirilen geçici bir çözümdü: daemon, süreç kimliğini /run/nginx.pid içine yazar ve durdurma işlevi bu dosyayı okurdu. Eğer daemon zorla sonlandırılırsa, dosya geride kalırdı. Çekirdek daha sonra bu numarayı başka bir işlem için yeniden kullanır ve start-stop-daemon --stop --pidfile, o an numaraya sahip olan herhangi bir sürece sinyal gönderirdi. Eski bir PID dosyası, bir init betiğinin yanlış süreci sonlandırmasının temel nedenidir.
launchd soket sorununu ilk çözen oldu
Apple, 2005 yılında Mac OS X 10.4 ile birlikte Dave Zarzycki tarafından yazılan launchd yazılımını kullanıma sundu. Tek bir süreç; init, rc, xinetd, crond ve watchdogd süreçlerinin yerini aldı.
Kopyalanmaya değer fikir soket aktivasyonuydu. launchd, tüm dinleme soketlerini önce oluşturur, ardından daemon süreçlerini başlatır. Henüz başlamamış bir daemon sürecine bağlanan bir istemci, "connection refused" hatası almaz; çünkü çekirdek, daemon süreci accept() çağrısını yapana kadar bağlantıyı ilgili soketin backlog kuyruğunda tutar. İki daemon arasındaki başlatma sırası, bir insanın belirlemesi gereken bir konu olmaktan çıkar. Soket bu durumu yönetir.
launchd, Apple'ın XNU çekirdeğine ait olan ve Linux tarafında doğrudan bir karşılığı bulunmayan Mach IPC (süreçler arası iletişim) yapısı üzerine inşa edilmiştir. Kodun taşınması hiçbir zaman gerçekçi bir seçenek olmamıştır. Yine de bu fikir yayılmıştır.
Upstart, iş birimi olarak olayları temel aldı
Scott James Remnant tarafından yazılan Canonical ürünü Upstart, Ekim 2006'da Ubuntu 6.10 ile piyasaya sürüldü. Fedora 9'dan Fedora 14'e kadar olan sürümlerin yanı sıra RHEL 6 ve Chrome OS tarafından da kullanıldı. Çalışma seviyeleri (runlevel) yerine olayları (event) getirdi; bir iş (job), hangi olayların onu başlatıp durduracağını tanımlıyordu.
# /etc/init/example.conf
start on filesystem and net-device-up IFACE!=lo
stop on runlevel [!2345]
respawn
respawn limit 10 5
exec /usr/local/bin/exampledİş sayısı arttıkça iki sorun ortaya çıktı. Birincisi yön sorunuydu. Bir iş "bu olduğunda beni başlat" der; dolayısıyla neyin neye bağımlı olduğu bilgisi yanlış dosyada tutulur: bir servis neye ihtiyaç duyduğunu bilir, ancak gelecek yıl kimin ona ihtiyaç duyacağını bilemez. Yeni bir servis eklemek, genellikle mevcut bir işi düzenleyerek yeni bir olay yayınlamasını sağlamak anlamına geliyordu.
İkincisi ise izleme sorunuydu. Upstart, çatallanan (forking) bir arka plan sürecini, expect fork veya expect daemon olarak yapılandırdığınız fork() çağrılarını ptrace ile sayarak takip ediyordu. Çatallanma sayısını yanlış tahmin ederseniz, Upstart ya zaten çıkış yapmış bir süreci denetler ya da çoktan gerçekleşmiş bir çatallanmayı beklerdi. Bunun belirtisi, initctl start komutunun hata vermeden takılı kalmasıdır; iş dosyası ise bunu açıklamanıza olanak tanıyan bir yol sunmazdı.
Upstart ayrıca katkıda bulunanların Canonical'ın katkı sözleşmesini imzalamasını şart koşuyordu. Bu bir mühendislik hatası değildi, ancak üzerinde kimlerin çalıştığını doğrudan etkiledi.
PID 1'i Yeniden Düşünmek, Nisan 2010
30 Nisan 2010 tarihinde Lennart Poettering, "Rethinking PID 1" başlıklı bir yazı yayımladı. Kay Sievers bu projede kendisiyle birlikte çalıştı. Argüman dört bölümden oluşuyordu.
- Daha az servis başlatın. Birçok servis, kendilerine ihtiyaç duyulana kadar bekleyebilir.
- Bir soketin sıralamayı belirleyebildiği durumlarda sıralama bildirmekten vazgeçin. Tüm soketleri tek seferde açın, ardından her şeyi aynı anda başlatın.
- Süreçleri PID dosyaları yerine control groups ile takip edin.
- Bir servisi bildirimsel (declarative) bir dosyada tanımlayın; böylece tek bir tanım her dağıtımda çalışabilsin.
İlk sürüm aynı yıl içinde yayımlandı. Fedora 14, Kasım 2010'da systemd'yi bir seçenek olarak sundu; Fedora 15 ise Mayıs 2011'de systemd'yi varsayılan hale getirdi.
Cgroups denetimi neden güvenilir kıldı
Cgroup (kontrol grubu), süreçleri gruplandırmak için kullanılan bir çekirdek özelliğidir ve 2008 yılında Linux 2.6.24 sürümüyle çekirdeğe dahil edilmiştir. systemd, her servisi kendi cgroup'u içerisine yerleştirir. Bir alt süreç, ebeveyninin cgroup'unu devralır ve yetkisiz bir süreç kendisini bu gruptan dışarı çıkaramaz. Bu nedenle "double forking" (çift çatallanma) yöntemi hiçbir şeyi gizleyemez: PID 1, her zaman bir birime ait olan süreçlerin tam listesini tutar. Bir servisi durdurmak, o servisin cgroup'u içerisindeki her şeyi sonlandırmak anlamına gelir; varsayılan KillMode=control-group komutunun yaptığı işlem de budur.
systemctl status bu grubu yazdırır:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-08-11 09:14:22 UTC; 3min ago
Main PID: 1042 (nginx)
Tasks: 3 (limit: 4653)
Memory: 6.1M (peak: 7.4M)
CGroup: /system.slice/nginx.service
├─1042 "nginx: master process /usr/sbin/nginx"
├─1043 "nginx: worker process"
└─1044 "nginx: worker process"Bu blok, güncelliğini yitirmiş PID dosyası sorununa verilen tam yanıttır. Liste çekirdek durumu olduğu için güncelliğini yitirebilecek bir dosya bulunmaz.
Aynı ağaç yapısı sınırlamaları da beraberinde getirir; çünkü cgroups, süreç takibi için kullanılmadan önce muhasebe işlemleri için tasarlanmıştır. MemoryMax=, CPUQuota= ve TasksMax= ayarlarının her biri tek satırdır. Bir servise katı bellek ve CPU sınırı koymak günümüzde bir "drop-in" dosyası ile mümkündür; 2009 yılında ise bu, kimsenin yazmadığı bir kabuk betiği yaması gerektirirdi.
Dağıtımların 2011 ile 2015 yılları arasında geçiş yapma nedenleri
- Fedora 15, Mayıs 2011.
- openSUSE 12.1, Kasım 2011.
- Mageia 2, Mayıs 2012.
- Arch Linux, Ekim 2012'den itibaren yeni kurulumlar için varsayılan.
- RHEL 7, Haziran 2014.
- SLES 12, Ekim 2014.
- Debian 8, Nisan 2015.
- Ubuntu 15.04, Nisan 2015.
Geçişin hızlı olmasının nedeni, gerekçelerin büyük ölçüde teknik ve standartlaşmaya yönelik olmasıdır.
- Tek bir unit dosyası her dağıtımda çalıştığı için, yukarı akış projeleri bir
.servicedosyası sunmaya başladı ve dağıtımlar her paket ve her sürüm için ayrı bir kabuk betiği sürdürmeyi bıraktı. - Masaüstü oturum takibi, ConsoleKit'in 2012 civarında bakımının durdurulmasının ardından
systemd-logindbileşenine taşındı. GNOME'un logind'ye ihtiyacı vardı; bu nedenle systemd kullanmayan bir dağıtımın bir alternatif bulması gerekiyordu. Bu alternatif olanelogind, systemd'nin logind bileşeninin ayrıştırılıp ayrı olarak sürdürülen halidir. - Aygıt yöneticisi olan udev, Nisan 2012'de systemd kaynak ağacına dahil edildi. udev sunan dağıtımlar artık systemd deposunu takip ediyordu. Gentoo, buna yanıt olarak
eudevprojesini çatalladı. - Konteyner teknolojileri, güvenilir süreç takibini ve servis bazlı limitleri daha önemli hale getirdi; çünkü her ikisi de cgroup özellikleridir. Bir konteyner sürecinin hangi denetleyiciye ait olduğu sorusu, yeniden başlatma sonrası bir Docker Compose yığınını ayağa kaldırma işlemi yapıldığında hala güncelliğini korumaktadır.
Debian'ın kararı en çok ses getiren gelişmeydi. Teknik Komite Şubat 2014'te oylama yaptı, oylar eşit çıktı ve başkan Bdale Garbee, systemd lehine belirleyici oyu kullandı. Ubuntu, günler sonra Upstart ile devam etmek yerine Debian'ı takip edeceğini duyurdu. Bir grup Debian geliştiricisi, Kasım 2014'te dağıtımı Devuan olarak çatalladı ve Mayıs 2017'de Devuan 1.0 sürümünü yayınladı.
İtirazlar, tarafsız bir bakış açısıyla
Kapsam. Tek bir proje artık PID 1, günlük kaydı daemon'ı, oturum yönetimi, aygıt yöneticisi, ağ yapılandırma daemon'ı, DNS (alan adı sistemi) çözümleyici, NTP (ağ zaman protokolü) istemcisi, container çalıştırıcı ve önyükleyici (boot loader) sunmaktadır. Bunların ayrı ayrı kurulması gerekmeyen bağımsız ikili dosyalar olduğu yönündeki yaygın savunma teknik olarak doğrudur ancak bu durum itirazı yanıtlamaz. Bir masaüstü ortamı logind'ye ihtiyaç duyduğunda ve logind, systemd ağacından ayrıştırılmadığında, seçim özgürlüğü ortadan kalkar. Tartışmada "bağımlılık" (coupling) ile kastedilen budur ve bu durum gerçekleşmiştir.
İkili günlük kaydı. journald, düz metin yerine indekslenmiş bir ikili formatta yazım yapar. Bu sayede düz metnin sunamadığı özelliklere sahip olursunuz: birim (unit) ve öncelik bazlı filtreleme, yapılandırılmış alanlar ve gönderen programın taklit edemeyeceği meta veriler; çünkü journald birim ve cgroup bilgisini kendisi kaydeder. journalctl -u nginx -p err --since "-1h", tarih düzenli ifadeleriyle yapılan grep işlemlerinin yerini alır. Bunun bir bedeli de vardır. Önyükleme yapmayan bir makinede, kurtarma kabuğundan less ile günlükleri okuyamazsınız. Bunun yerine journalctl aracını mount edilmiş diske yönlendirmeniz gerekir:
sudo journalctl --directory /mnt/var/log/journal --boot -1 --priority errBurada insanları bir kez yakalayan ikinci bir tuzak daha vardır. /var/log/journal dizini mevcut değilse, journald günlükleri /run/log/journal yani bellek üzerinde tutar. Bu dizinin bulunmadığı bir sistemde, yeniden başlatma sonrasında journalctl -b -1 komutu hiçbir şey göstermez; oysa günlüklere tam da o anda ihtiyaç duyarsınız. Kontrol edin ve düzeltin:
journalctl --disk-usage
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journaldjournalctl --disk-usage artık /var/log/journal altında arşivlenmiş günlükleri raporlamalıdır. Eğer düz metin günlükleri de istiyorsanız, /etc/systemd/journald.conf dosyasında ForwardToSyslog=yes ayarını yapılandırın ve rsyslog kurulumunu koruyun.
Önyükleme hata ayıklanabilirliği. Bir birim takıldığında, konsol sadece tek bir satır gösterir:
[ *** ] A start job is running for Wait for Network to be Configured (1min 32s / no limit)Daha ileri gitmek için araçlar mevcuttur: takılma anında systemctl list-jobs, sonrasında systemd-analyze blame ve systemd-analyze critical-chain, kernel komut satırında ise systemd.log_level=debug kullanılabilir. Şikayetin haklı tarafı şudur: bir init betiği, sh bilen herkes tarafından baştan sona okunabilirdi; oysa takılan bir birim, bir düzine komuttan hangisinin kullanılması gerektiğini bilmeyi gerektirir. Bu gerçek bir maliyettir. Her yönetici tarafından bir kez ödenir ve bu maliyet, çok sayıda yönetici tarafından aynı anda ödenmiştir.
Herkes için değişen varsayılanlar. 2016 yılındaki systemd 230 sürümü, logind varsayılanlarını değiştirerek oturum kapatıldığında geride kalan kullanıcı süreçlerinin sonlandırılmasına neden oldu. Ayrılmış tmux ve screen oturumları, onları başlatan oturum sona erdiğinde kapandı. Dağıtımlar /etc/systemd/logind.conf içinde KillUserProcesses=no paketini sundu ve desteklenen çözüm loginctl enable-linger <user> oldu. Tek bir projedeki tek bir varsayılan ayar, milyonlarca insanın güvendiği bir alışkanlığı değiştirdi; "kullanıcı alanının (userland) tek bir yerde toplanması" pratikte tam olarak bu anlama gelir.
Varsayılan bağımlılık bir güvenlik yüzeyidir. Mart 2024'te xz-utils içindeki arka kapı, Debian ve Ubuntu üzerindeki sshd'yi hedef aldı. Upstream OpenSSH, libsystemd ile bağlantılı değildir. Söz konusu dağıtımlar, sshd'nin systemd'ye hazır olduğunu bildirebilmesi için bu kütüphaneyi yamaladı ve libsystemd, arka kapının bulunduğu liblzma'yı sisteme dahil etti. Hazırlık protokolünün kendisi, $NOTIFY_SOCKET içinde belirtilen sokete gönderilen tek bir datagramdan ibarettir; dolayısıyla bunun için hiçbir kütüphaneye ihtiyaç yoktur. systemd'nin yanıtı, sıkıştırma kütüphanelerini dlopen ile yüklemek oldu, böylece artık varsayılan olarak sisteme bağlanmıyorlar. Benzer bir hata sınıfı aynı yapıyı gösterir: 2017'de rakamla başlayan bir User= değeri geçersiz kabul edildi ve birim hata vermek yerine root yetkileriyle çalıştı; böylece bir yazım hatası, yetki yükseltme açığına dönüştü. Daha yeni sürümler birimi başlatmayı reddetmektedir.
Kendi systemctl isteminizde tarihçe
Yukarıdaki her sorun, artık okuyabileceğiniz bir dosya içindeki tek bir yönergeye dönüşmüştür.
- Seri önyükleme
After=veWants=haline geldi;systemd-analyze critical-chainise önyüklemenizi gerçekte neyin beklettiğini gösterir. - Hazır olma durumu
Type=notifyhaline geldi; burada servis, hizmet verebilecek duruma geldiğindeREADY=1dosyasını$NOTIFY_SOCKETyoluna yazar. Eski daemon'lar içinPIDFile=ileType=forkinghala mevcuttur ve PID dosyası hiçbir zaman oluşmadığındastart operation timed out. Terminating.hatasıyla başarısız olan tür budur. - Denetim (supervision) cgroup haline geldi; bu nedenle
RestartSec=ileRestart=on-failurebir sarmalayıcı (wrapper) betiğinin yerini alır veStartLimitBurst=, bir çökme döngüsünün sonsuza kadar çalışmasını engeller. - inetd,
.serviceünitesinin yanında duran bir.socketünitesi haline geldi. ulimit;MemoryMax=,CPUQuota=veTasksMax=haline geldi.- Bir init betiğindeki
su - appuser -csatırıUser=,NoNewPrivileges=yesveProtectSystem=stricthaline geldi; bu sayede bir servisi yetkisiz kullanıcı olarak çalıştırmak, ek bir iş olmaktan çıkıp bir ünitenin varsayılan biçimi haline geldi.
[Unit]
Description=Example API
Wants=network-online.target
After=network-online.target postgresql.service
Requires=postgresql.service
[Service]
Type=notify
ExecStart=/usr/local/bin/exampled
Restart=on-failure
RestartSec=2
MemoryMax=512M
CPUQuota=50%
TasksMax=128
User=exampled
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
StateDirectory=exampled
[Install]
WantedBy=multi-user.targetO dosyadaki bir satır, herkesin bir kez yaptığı hatadır. Requires=postgresql.service bir sıralama değil, bir gerekliliktir: Postgres başarısız olursa ünitenizin de başarısız olacağını belirtir, ancak Postgres'i önce başlatın demez. After=postgresql.service olmadan her ikisi de aynı anda başlar ve servisiniz, henüz hiçbir şeyin dinlemediği bir porta bağlanmaya çalışır. İkisi kasıtlı olarak ayrı tutulmuştur çünkü bazen birini diğeri olmadan istersiniz. ProtectSystem=strict, dosya sistemini bu servis için salt okunur bağlar; StateDirectory='in orada bulunma nedeni budur: servise /var/lib altında yazılabilir tek bir yol sağlar.
2005 yılını 2026 model bir sunucuda görmenin en net yeri, Ağustos 2026 itibarıyla systemd 255 sürümünü sunan Ubuntu 24.04 üzerindeki SSH'tır. ssh.service varsayılan olarak soket ile etkinleştirilir: ssh.socket dinleme soketini tutar ve bir bağlantı geldiğinde sshd başlar. Bu nedenle /etc/ssh/sshd_config içindeki Port 2222 hiçbir etkiye sahip değildir, çünkü sshd portu açan süreç değildir. Değişiklik soket ünitesinde yapılmalıdır.
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222Boş ListenStream=, paketlenmiş üniteden devralınan değeri temizler. Bunu çıkarırsanız her iki portu da alırsınız, çünkü systemd değerin yerine yenisini koymak yerine listeye ekleme yapar. Ardından uygulayın ve kontrol edin; bu sırada ikinci bir SSH oturumunu açık tutun:
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -lntp | grep 2222ss, sshd tarafından değil, systemd tarafından sahip olunan 2222 numaralı porttaki tek bir soketi listelemelidir. Bu, yirmi yıl sonra VPS'nizde çalışan launchd tasarımıdır. Eski davranışı tercih ederseniz, sudo systemctl disable --now ssh.socket ve ardından sudo systemctl enable --now ssh.service komutları, Port dosyasını kendi yapılandırmasından tekrar okuyan uzun süreli bir sshd sağlar.
Bu detayların hangileriyle karşılaşacağınız çalıştırdığınız sürüme bağlıdır, bu nedenle bir yükseltme planlamadan önce LTS ve ara Ubuntu sürümü arasındaki farkı bilmek faydalıdır. Birden fazla makinede, bir ünite dosyasının her yerde aynı olması, birden fazla sunucuyu tek bir yerden yönetmenin artık bir shell betiği sorunu değil, bir yapılandırma sorunu olmasının nedenidir. Kendi ünitelerinizi yazdığınızda ise, servis ve zamanlayıcı (timer) ikilisi, 2009 yılında bir init betiği ile bir cron satırı arasında bölüştüreceğiniz işi tek başına yapar.
FAQ
Linux dağıtımları neden SysV init yerine systemd kullanmaya başladı?
İki mühendislik ve bir bakım gerekçesiyle. SysV init, servisleri bağımlılığa göre değil, dosya ismine göre sıralıyordu; bu da bir konumlandırma sorunuydu. Ayrıca ana süreçten ayrılan (fork) daemon'ları takip edemiyordu; bu yüzden eski PID dosyaları yanlış sürecin sonlandırılmasına neden olabiliyordu. systemd, sıralama sorununu socket activation ve bağımlılık yönergeleriyle, takip sorununu ise control groups ile çözdü. Bakım gerekçesi ise hızı belirledi: tek bir unit dosyası her dağıtımda çalışır. Bu sayede upstream projeler bir .service dosyası dağıttı ve dağıtım sorumluları her paket için ayrı bir shell betiği yazmayı bıraktı. Fedora 15, Mayıs 2011'de geçiş yaptı; Ubuntu 15.04 ise Nisan 2015'te bu değişime direnen son büyük dağıtım oldu.
systemd tek bir devasa binary midir?
Hayır. Kaynak kodu birçok ayrı program oluşturur. PID 1, /usr/lib/systemd/systemd'tir; journald, logind ve udevd ise kendi binary dosyalarına sahip ayrı süreçlerdir. Kendi sisteminizde bunları görmek için ls /usr/lib/systemd/ komutunu çalıştırın. Günümüzde yapılan eleştiriler binary boyutundan ziyade sürüm bağımlılığı üzerinedir: bu programlar birlikte yayınlanır ve özel arayüzleri paylaşırlar. Bu nedenle dağıtımlar bunları bir set olarak alma eğilimindedir ve GNOME gibi yazılımlar özellikle logind'yi bekler hale gelmiştir.
Linux'u hala systemd olmadan çalıştırabilir miyim?
Evet. Devuan sysvinit ile gelir, Gentoo varsayılan olarak OpenRC kullanır, Void runit kullanır, Alpine OpenRC ile busybox init kullanır ve Slackware BSD tarzı betikleri korur. Bunun maliyeti uyumluluk çalışmalarıdır. logind bekleyen masaüstü yazılımları, systemd'nin logind'sinin bağımsız bir paket olarak sürdürülen hali olan elogind'ye ihtiyaç duyar. Ayrıca giderek daha fazla sunucu yazılımı yalnızca .service dosyası ile dağıtılmaktadır; bu durumda başlangıç betiğini kendiniz yazıp sürdürmeniz gerekir.
Journal neden düz metin dosyası yerine binary formatındadır?
Çünkü journald, yapılandırılmış alanları bir dizin ile saklar. Bu, birim bazlı filtreleme, öncelik filtreleme ve gönderen programın taklit edemeyeceği meta veriler sağlar: journald, log satırına güvenmek yerine birimi, cgroup'u ve gerçek UID'yi bizzat kaydeder. Bunun bedeli, okumak için journalctl aracına ihtiyaç duymanızdır; buna kurtarma sistemleri de dahildir (burada journalctl --directory /mnt/var/log/journal ile bağlı diski işaret edersiniz). Eğer metin formatında da kayıt istiyorsanız, /etc/systemd/journald.conf içerisinde ForwardToSyslog=yes ayarını yapın.
/etc/init.d betiğimi düzenlemenin yerini ne aldı?
Drop-in dosyaları. /usr/lib/systemd/system/ içindeki unit dosyasını düzenlemeyin, çünkü paket yükseltmeleri bu dosyayı üzerine yazar. sudo systemctl edit nginx.service komutunu çalıştırın; systemd, paketlenmiş unit dosyasıyla birleştirilecek olan /etc/systemd/system/nginx.service.d/override.conf dosyasını oluşturacaktır. systemctl cat nginx.service birleştirilmiş sonucu gösterir, systemd-delta ise makinedeki tüm geçersiz kılmaları (override) listeler. Elle yapılan her düzenlemeden sonra sudo systemctl daemon-reload komutunu çalıştırın, aksi takdirde bir sonraki komut Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. uyarısını verecektir.