أساسيات

ما هو systemd: طريقة عمله وإدارة خدمات لينكس

آخر تحديث: · Skillaria.Top

systemd هو نظام التهيئة ومدير الخدمات في لينكس. تشغّله النواة أولاً بوصفه العملية الأولى PID 1، فيشغّل بقية الخدمات بالترتيب الصحيح ويراقبها. تُدار كل وظائفه عبر الوحدات (units)، وهي ملفات نصية تصف الخدمات والمؤقتات ونقاط التركيب. يستخدم المستخدم الأمر systemctl لتشغيل الخدمات وإيقافها وإضافتها إلى بدء التشغيل، ويستخدم journalctl لعرض سجلاتها.

systemd هو نظام التهيئة ومدير الخدمات الذي تستخدمه معظم توزيعات لينكس الحديثة: Debian وUbuntu وFedora وRHEL وما يتفرع منها. تشغّل النواة systemd بعد الإقلاع كأول عملية بالمعرّف PID 1، ثم يتولى هو تشغيل الشبكة وتركيب الأقراص وخادم الويب وقاعدة البيانات وكل ما عداها. باختصار، systemd هو «المنسّق» الذي يعرف أي الخدمات يجب أن تعمل، وبأي ترتيب تُشغَّل، وماذا يفعل إذا تعطّلت خدمة.

للتأكد من أن نظامك يستخدم systemd، يكفي هذا الأمر:

$ ps -p 1 -o comm=
systemd

لماذا ظهر systemd

كان لينكس يستخدم في الماضي SysV init: مجموعة من سكريبتات الصدفة في /etc/init.d/ تُشغَّل واحدة تلو الأخرى. كان النظام مفهوماً لكنه بطيء وهش. فكل سكريبت كان يكتب ملف PID بنفسه، ويتحقق بنفسه من بقاء العملية حية، وكان إعادة تشغيل الخدمة المتعطلة تحتاج إلى إعداد منفصل.

يحل systemd هذه المشكلات بطريقة مركزية:

  • التشغيل المتوازي.تبدأ الخدمات التي لا تعتمد على بعضها في وقت واحد، فيصبح الإقلاع أسرع.
  • الاعتماديات والترتيب.يذكر وصف الخدمة صراحةً ما تحتاجه (مثل الشبكة) وما يجب أن تبدأ بعده.
  • المراقبة.يعرف systemd جميع عمليات الخدمة عبر cgroups، ويستطيع إعادة تشغيلها عند الفشل.
  • سجل موحد.يجمع journald مخرجات جميع الخدمات، ويمكن عرضها بأمر واحد.
  • واجهة موحدة.تُدار كل خدمة بالطريقة نفسها: systemctl start|stop|restart|status.

إلى جانب مدير الخدمات، يضم مشروع systemd مجموعة من المكونات: journald (السجل)، وlogind (جلسات المستخدمين)، وtimesyncd (مزامنة الوقت)، وresolved (DNS)، وnetworkd (الشبكة). لا تستخدم كل التوزيعات جميع هذه المكونات، لكن systemd بوصفه PID 1 وjournald موجودان تقريباً في كل مكان.

الوحدات: مكونات systemd

كل ما يديره systemd يُوصف بـوحدات (units). والوحدة ملف نصي بصيغة INI، ويحدد امتداد الملف نوع الوحدة.

النوعالامتدادما تصفه
service.serviceخدمة: عملية خلفية (daemon) أو مهمة لمرة واحدة
timer.timerتشغيل وحدة أخرى وفق جدول زمني (بديل cron)
socket.socketمقبس تُشغَّل عند وصول اتصال إليه الخدمة المرتبطة به
target.targetمجموعة من الوحدات، أي «حالة النظام» (مثل multi-user.target)
mount.mountنقطة تركيب
path.pathمراقبة ملف أو مجلد

أماكن ملفات الوحدات

توجد ملفات الوحدات في عدة مجلدات، ولها أولويات:

  • /usr/lib/systemd/system/ (وفي Debian وUbuntu أيضاً /lib/systemd/system/): وحدات تثبتها الحزم. لا تعدّلها يدوياً، فتحديث الحزمة يستبدل تعديلاتك.
  • /etc/systemd/system/: وحدات المدير وإعدادات التجاوز، وهي الأعلى أولوية.
  • /run/systemd/system/: وحدات مؤقتة تُنشأ أثناء التشغيل.

لعرض المحتوى النهائي للوحدة مع كل إعدادات التجاوز استخدم systemctl cat nginx.service.

الأهداف (targets) بدلاً من مستويات التشغيل

حلّت الأهداف محل مستويات التشغيل القديمة (runlevel). فالهدف multi-user.target هو الوضع المعتاد للخادم دون واجهة رسومية، وgraphical.target يضم الواجهة الرسومية، وrescue.target وضع الاستعادة لمستخدم واحد. يُعرض الهدف الافتراضي بالأمر systemctl get-default، ويُغيَّر بالأمر systemctl set-default multi-user.target.

systemctl: إدارة الخدمات

الأمر systemctl هو الأداة الرئيسية للتعامل مع systemd. ومعظم الأوامر التي تغيّر حالة النظام تحتاج إلى sudo.

الأمرالوظيفة
systemctl status nginxحالة الخدمة، ومعرّف PID، والذاكرة، وآخر أسطر السجل
systemctl start nginxالتشغيل الآن
systemctl stop nginxالإيقاف
systemctl restart nginxإعادة التشغيل (stop ثم start)
systemctl reload nginxإعادة قراءة الإعدادات دون إيقاف الخدمة (إذا كانت الخدمة تدعم ذلك)
systemctl enable nginxإضافة الخدمة إلى بدء التشغيل
systemctl disable nginxإزالة الخدمة من بدء التشغيل
systemctl enable --now nginxتفعيل بدء التشغيل وتشغيل الخدمة فوراً
systemctl is-active nginxعرض active أو inactive، وهذا مفيد في السكريبتات
systemctl list-units --type=serviceالخدمات المحمّلة
systemctl --failedالوحدات المتعطلة
systemctl daemon-reloadإعادة قراءة ملفات الوحدات بعد تعديلها

كيف تقرأ systemctl status

$ 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 مصدر ملف الوحدة، وهل بدء التشغيل التلقائي مفعّل (enabled). ويوضح السطر Active الحالة الحالية: active (running) أو inactive (dead) أو failed. أما الجزء CGroup فيعرض جميع عمليات الخدمة، وبهذه الطريقة يعرف systemd أي العمليات تنتمي إلى الخدمة.

الفرق بين enable وstart

هذا خلط شائع. يشغّل start الخدمة الآن، لكنها لا تعمل تلقائياً بعد إعادة التشغيل. أما enable فينشئ رابطاً رمزياً في مجلد الهدف (مثل /etc/systemd/system/multi-user.target.wants/)، فتبدأ الخدمة عند الإقلاع، لكنها لا تعمل الآن. وغالباً تحتاج إلى الأمرين معاً، لذلك نستخدم enable --now.

وهناك حالة ثالثة هي mask. فالأمر systemctl mask service يربط الوحدة بـ /dev/null، فلا يمكن تشغيلها يدوياً ولا كاعتمادية. وهذا مفيد عندما تريد تعطيل الخدمة نهائياً.

journalctl: سجلات الخدمات

يلتقط systemd-journald كل ما تكتبه الخدمة في stdout وstderr، ويحفظه في سجل ثنائي مع البيانات الوصفية: اسم الوحدة، ومعرّف PID، والأولوية، والوقت. ويُقرأ السجل بالأمر journalctl.

journalctl -u nginx              # سجل خدمة واحدة
journalctl -u nginx -f           # متابعة لحظية، مثل tail -f
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -n 50        # آخر 50 سطراً
journalctl -b                    # منذ الإقلاع الحالي
journalctl -b -1                 # الإقلاع السابق
journalctl -p err -b             # الأخطاء وما هو أخطر
journalctl -k                    # رسائل النواة
journalctl --disk-usage          # المساحة التي يشغلها السجل

يصفّي الخيار -p حسب أولوية syslog: emerg، وalert، وcrit، وerr، وwarning، وnotice، وinfo، وdebug. ويشمل المستوى المحدد كل ما هو أخطر منه.

بقاء السجل بعد إعادة التشغيل

إذا لم يكن المجلد /var/log/journal موجوداً، وكان الإعداد Storage=auto في /etc/systemd/journald.conf، فإن السجل يُحفظ في الذاكرة فقط (/run/log/journal)، ويضيع عند إعادة التشغيل. ولجعله دائماً اضبط Storage=persistent أو أنشئ المجلد وأعد تشغيل journald. ويحدد الحجم الإعداد SystemMaxUse=، ويمكن تنظيف السجلات القديمة بالأمر journalctl --vacuum-time=2weeks أو --vacuum-size=500M.

وكثيراً ما يعمل journald مع rsyslog: يمرر journald الرسائل إلى rsyslog، فيكتبها الأخير في ملفات السجل النصية التقليدية داخل /var/log/، ويستطيع إرسال السجلات إلى خادم مركزي.

تشغيل خدمتك الخاصة تلقائياً: مثال على ملف وحدة

لنفترض أن لديك تطبيقاً (سكريبتاً أو ملفاً تنفيذياً) تريد إبقاءه قيد التشغيل، وتشغيله عند الإقلاع، وإعادة تشغيله إذا توقف. أنشئ الملف /etc/systemd/system/myapp.service:

[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

شرح الأقسام:

  • [Unit]: الوصف والاعتماديات. يحدد After= الترتيب فقط، أما Wants= فهو اعتماد ضعيف (يحاول تشغيل الوحدة، لكنه لا يُفشل الوحدة إذا لم تعمل). والاعتماد القوي يُكتب بـ Requires=.
  • [Service]: طريقة التشغيل. يعني Type=simple أن العملية في ExecStart هي الخدمة نفسها، ولا تنتقل إلى الخلفية. يشغّل User= الخدمة بمستخدم غير مميز. يعيد Restart=on-failure تشغيل الخدمة إذا انتهت بخطأ، بعد RestartSec ثانية.
  • [Install]: ما يفعله الأمر enable. تعني WantedBy=multi-user.target «شغّل الخدمة عند الإقلاع العادي».

طبّق الإعداد:

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

أخطاء شائعة في ملفات الوحدات

  • مسار نسبي في ExecStart.يجب أن يكون مسار البرنامج مطلقاً. فـ systemd لا يبحث عن الأوامر في PATH الخاص بالمستخدم كما تفعل الواجهة.
  • نسيان daemon-reload.بعد تعديل الملف يستمر systemd في استخدام النسخة القديمة، ويحذّر من ذلك في status.
  • العملية تنتقل إلى الخلفية.إذا كان البرنامج يُنشئ عملية فرعية بنفسه بينما الإعداد Type=simple، سيعتقد systemd أن الخدمة انتهت. شغّل البرنامج في المقدمة (foreground)، أو استخدم Type=forking مع PIDFile=.
  • متغيرات البيئة من الملف الشخصي.لا ترى الخدمة الملفين ~/.bashrc و/etc/profile. تُحدَّد المتغيرات عبر Environment= أو EnvironmentFile=.

تعديل الوحدة دون تغيير ملف الحزمة

لتغيير إعدادات خدمة قادمة من حزمة دون لمس ملفها، استخدم الإعداد التكميلي (drop-in):

sudo systemctl edit nginx

يُفتح المحرر، وتُحفظ التغييرات في /etc/systemd/system/nginx.service.d/override.conf. فمثلاً يمكنك إضافة [Service] وRestart=always هناك. وعند إغلاق المحرر يعيد systemd قراءة الإعدادات تلقائياً.

مؤقتات systemd بدلاً من cron

المؤقت (timer) وحدة تشغّل خدمة لها الاسم نفسه وفق جدول زمني. ومزاياه مقارنةً بـ cron: سجل المهمة في journal، وإمكانية تحديد الاعتماديات، وتعويض التشغيلات الفائتة (Persistent=true). مثال على نسخ احتياطي يومي:

# /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 استخدم systemd-analyze calendar "*-*-* 03:00:00"، فسيعرض موعد التشغيل التالي.

تشخيص زمن الإقلاع

يسجل systemd وقت بدء كل وحدة، لذلك يسهل تحليل بطء الإقلاع:

systemd-analyze                  # الزمن الإجمالي للإقلاع
systemd-analyze blame            # الوحدات مرتبةً حسب زمن التشغيل
systemd-analyze critical-chain   # السلسلة التي أخّرت الإقلاع
systemd-analyze verify /etc/systemd/system/myapp.service   # فحص ملف الوحدة

الخلاصة

systemd هو PID 1 ومدير الخدمات في لينكس الحديث. يصف كل شيء بالوحدات، ويُدار بـ systemctl، ويجمع السجلات في journal يقرؤه journalctl، ويمكنه تشغيل المهام بمؤقتات بدلاً من cron. وللعمل به بثقة يكفي أن تتقن status وenable --now وjournalctl -u، وأن تكتب ملف وحدة بسيطاً فيه Restart=on-failure. يُشرح systemd وjournald وإدارة السجلات عملياً في دورة لينكس.

الأسئلة الشائعة

كيف أعرف هل يستخدم نظامي systemd؟

نفّذ الأمر ps -p 1 -o comm=. إذا كان الناتج systemd فالنظام يعمل بـ systemd. كذلك يوجد المجلد /run/systemd/system فقط عند الإقلاع عبر systemd.

ما الفرق بين systemctl restart وreload؟

يوقف restart الخدمة تماماً ثم يعيد تشغيلها، فتنقطع الاتصالات. أما reload فيطلب من الخدمة إعادة قراءة الإعدادات دون توقف، ولا يعمل إلا إذا عرّفت الوحدة ExecReload.

هل يمكن تشغيل خدمات systemd بمستخدم عادي دون sudo؟

نعم، لدى systemd نسخة للمستخدم: تُوضع ملفات الوحدات في ~/.config/systemd/user/ وتُدار بـ systemctl --user. ولكي تعمل بدون جلسة نشطة يجب تفعيل loginctl enable-linger لهذا المستخدم.

لماذا تكون الخدمة في حالة failed، وكيف أعيد الحالة إلى الوضع الطبيعي؟

ابحث عن السبب في journalctl -u الاسم -b وفي سطر Active في أمر status. بعد الإصلاح أعد تشغيل الخدمة، ولإزالة علامة failed دون إعادة تشغيل استخدم systemctl reset-failed.

أين تُحفظ سجلات systemd على القرص؟

عند الحفظ الدائم تكون في /var/log/journal/ بصيغة ثنائية، وإلا فهي في الذاكرة داخل /run/log/journal/. اقرأها عبر journalctl، لا بأدوات النصوص.

تعلّم هذا الموضوع بالفيديو

يُشرح هذا الموضوع بالتفصيل مع التطبيق العملي في دورة «Linux: с нуля до уверенного администрирования».

الانتقال إلى الدورة