الفصل 8.2 - الخدمات المخصصة
أهداف التعلم
في نهاية هذا الفصل، ستكون قادرًا على:
- إنشاء ملف unit لـ systemd
- تكوين خدمة مخصصة
- فهم أقسام ملف unit
- إدارة التبعيات
- إنشاء خدمات للسكربتات
هيكل ملف Unit
الموقع
# النظام
/etc/systemd/system/
# المستخدم
~/.config/systemd/user/
الأولوية:
/etc/systemd/system/(النظام) >/usr/lib/systemd/system/(الحزم)
التنسيق الأساسي
[Unit]
Description=وصف الخدمة
After=network.target
[Service]
Type=simple
ExecStart=/chemin/vers/commande
Restart=always
[Install]
WantedBy=multi-user.target
الأقسام الرئيسية
[Unit]
[Unit]
Description=خدمتي المخصصة
Documentation=man:mon-service(1)
After=network.target sshd.service
Before=some-service.service
Requires=network.target
Wants=sshd.service
Conflicts=old-service.service
التوجيهات:
- Description: وصف الخدمة
- After: يبدأ بعد هذه الوحدات
- Before: يبدأ قبل هذه الوحدات
- Requires: تبعية قوية (يفشل إذا فشلت التبعية)
- Wants: تبعية ضعيفة (يستمر إذا فشلت التبعية)
- Conflicts: لا يمكن أن يعمل في نفس الوقت
[Service]
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-script.sh
ExecStartPre=/bin/echo "بدء"
ExecStartPost=/bin/echo "بدأ"
ExecStop=/bin/echo "إيقاف"
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
User=monuser
Group=mongroup
WorkingDirectory=/var/lib/monservice
Environment="VAR1=valeur1"
EnvironmentFile=/etc/monservice/env
StandardOutput=journal
StandardError=journal
الأنواع:
- simple: الأمر الرئيسي (الافتراضي)
- forking: يتفرع في الخلفية
- oneshot: تنفيذ لمرة واحدة
- notify: يُخطر systemd عندما يكون جاهزًا
إعادة التشغيل:
- no: لا يعيد التشغيل
- always: يعيد التشغيل دائمًا
- on-failure: يعيد التشغيل إذا فشل
- on-success: يعيد التشغيل إذا نجح
[Install]
[Install]
WantedBy=multi-user.target
Alias=monservice.service
الأهداف الشائعة:
- multi-user.target: وضع متعدد المستخدمين
- graphical.target: وضع رسومي
- default.target: الهدف الافتراضي
أمثلة عملية
خدمة بسيطة
# /etc/systemd/system/mon-service.service
[Unit]
Description=خدمتي البسيطة
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-script.sh
Restart=always
RestartSec=10
User=www-data
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
التفعيل:
sudo systemctl daemon-reload
sudo systemctl enable mon-service
sudo systemctl start mon-service
خدمة مع سكربت
#!/bin/bash
# /usr/local/bin/mon-script.sh
# سكربت الخدمة
# وظيفة التنظيف
cleanup() {
echo "إيقاف الخدمة"
# تنظيف...
exit 0
}
# Trap signals
trap cleanup SIGTERM SIGINT
# الحلقة الرئيسية
while true; do
# العمل...
echo "الخدمة نشطة: $(date)"
sleep 60
done
ملف الوحدة:
[Unit]
Description=خدمة مع سكربت
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-script.sh
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
خدمة Forking
[Unit]
Description=خدمة Forking
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/daemon --daemonize
PIDFile=/var/run/daemon.pid
Restart=always
[Install]
WantedBy=multi-user.target
خدمة Oneshot
[Unit]
Description=سكربت Oneshot
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/init-script.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
متغيرات البيئة
في ملف الوحدة
[Service]
Environment="VAR1=valeur1"
Environment="VAR2=valeur2"
EnvironmentFile=/etc/monservice/env
ملف البيئة
# /etc/monservice/env
VAR1=valeur1
VAR2=valeur2
VAR3="valeur مع مسافات"
إدارة السجلات
سجل systemd
# عرض سجلات الخدمة
sudo journalctl -u mon-service
# متابعة السجلات
sudo journalctl -u mon-service -f
# السجلات الحديثة
sudo journalctl -u mon-service -n 50
# منذ تاريخ
sudo journalctl -u mon-service --since "2024-01-01"
إعادة التوجيه
[Service]
# إلى السجل (الافتراضي)
StandardOutput=journal
StandardError=journal
# إلى ملف
StandardOutput=file:/var/log/monservice.log
StandardError=file:/var/log/monservice-error.log
# تجاهل
StandardOutput=null
StandardError=null
الممارسات الجيدة
الهيكل
[Unit]
# وصف واضح
# تبعيات مناسبة
[Service]
# النوع الصحيح
# User/Group غير root إذا أمكن
# إعادة تشغيل مناسبة
# تكوين السجلات
[Install]
# الهدف المناسب
الأمان
[Service]
# عدم استخدام root إذا أمكن
User=serviceuser
Group=servicegroup
# تقييد القدرات
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
# Chroot إذا أمكن
RootDirectory=/var/lib/monservice
الملخص
في هذا الفصل، تعلمت:
ملفات الوحدة: هيكل [Unit], [Service], [Install]
الأنواع: simple, forking, oneshot, notify
التبعيات: After, Before, Requires, Wants
إعادة التشغيل: always, on-failure, never
البيئة: Environment, EnvironmentFile
السجلات: journalctl, إعادة توجيه الملفات
الممارسة: إنشاء خدمات للسكربتات والتطبيقات
الخطوات التالية
الفصل 8.3: Cron المتقدم وsystemd Timers
الوحدة 9: أمان النظام
تم إنشاء الفصل في: ديسمبر 2024