Linux systemd incident runbook là bộ thao tác chuẩn để sysadmin điều tra khi service trên production chết bất thường, restart liên tục, boot chậm hoặc không tự phục hồi sau lỗi. systemd không chỉ là công cụ start/stop service; nó còn là lớp quản lý dependency, logging, cgroup, resource limit, timer và chính sách recovery cho hầu hết bản phân phối Linux hiện đại.
Bài này đi theo bối cảnh thực chiến: một máy Linux chạy Nginx, PHP-FPM, worker nền hoặc database replica trong production. Mục tiêu là khôi phục dịch vụ nhanh, thu thập bằng chứng đủ tốt, tìm nguyên nhân gốc và thêm guardrail để sự cố tương tự không lặp lại.
1. Nguyên tắc xử lý incident với systemd
- Đừng restart mù quáng trước khi lấy trạng thái và log tối thiểu.
- Phân biệt lỗi service, lỗi dependency, lỗi cấu hình, thiếu tài nguyên và lỗi boot order.
- Ưu tiên khôi phục dịch vụ nhưng phải lưu lại bằng chứng: status, journal, exit code, resource usage.
- Mọi thay đổi unit trên production nên dùng override trong /etc/systemd/system thay vì sửa file vendor trực tiếp.
- Sau khi phục hồi cần có checklist nghiệm thu và hành động phòng ngừa.
2. Thu thập trạng thái trong 60 giây đầu
SERVICE=nginx
hostnamectl
uptime
systemctl status "$SERVICE" --no-pager -l
systemctl show "$SERVICE" -p ActiveState -p SubState -p Result -p ExecMainStatus -p NRestarts -p FragmentPath -p DropInPaths
journalctl -u "$SERVICE" -b --no-pager -n 120
Các trường quan trọng: Result cho biết service chết do exit-code, signal, timeout hay watchdog; ExecMainStatus là mã thoát; NRestarts giúp nhận ra restart loop; DropInPaths cho biết có override nào đang ảnh hưởng unit không.
3. Đọc journalctl đúng cách
Lọc theo boot, mức độ lỗi và khoảng thời gian
journalctl -u nginx -b -p warning..alert --no-pager
journalctl -u nginx --since "30 minutes ago" --until "now" --no-pager
journalctl -k -b -p warning..alert --no-pager
journalctl --disk-usage
Nếu service bị kernel OOM kill, log của unit có thể không nói hết. Hãy kiểm tra kernel journal với journalctl -k. Nếu journal quá ít, kiểm tra cấu hình persistent log trong /var/log/journal và rotation.
4. Phân tích dependency và boot chậm
systemctl list-dependencies nginx.service
systemctl list-units --failed
systemd-analyze time
systemd-analyze blame | head -30
systemd-analyze critical-chain nginx.service
Boot chậm thường do mount chờ timeout, DNS/network-online target, service ExecStartPre treo hoặc dependency không cần thiết. Với service web, hãy xác định nó thật sự cần network-online.target hay chỉ cần network.target; cấu hình sai có thể làm boot chậm hàng phút.
5. Kiểm tra cấu hình unit và override
systemctl cat nginx.service
systemctl edit nginx.service
systemctl daemon-reload
systemctl restart nginx.service
systemctl status nginx.service --no-pager -l
Không nên sửa trực tiếp file unit trong /usr/lib/systemd/system hoặc /lib/systemd/system vì update package có thể ghi đè. Dùng systemctl edit để tạo drop-in override tại /etc/systemd/system/nginx.service.d/override.conf.
6. Thêm restart policy an toàn
[Service]
Restart=on-failure
RestartSec=5s
StartLimitIntervalSec=300
StartLimitBurst=5
TimeoutStartSec=60
TimeoutStopSec=60
Restart policy giúp tự phục hồi lỗi tạm thời, nhưng không được che giấu lỗi lặp lại. StartLimitBurst và StartLimitIntervalSec ngăn restart storm làm CPU/log đầy. Với database hoặc queue worker, cần cân nhắc dữ liệu đang xử lý trước khi bật restart tự động.
7. Debug lỗi permission, environment và working directory
systemctl show myapp -p User -p Group -p WorkingDirectory -p Environment -p EnvironmentFiles
sudo -u appuser -H /bin/bash -lc 'cd /opt/myapp && ./start.sh'
namei -l /opt/myapp/config.yml
systemd-run --pty --same-dir --uid=appuser /bin/bash
Rất nhiều service chạy được khi gõ tay nhưng chết dưới systemd vì khác user, thiếu biến môi trường, sai working directory, file secret không đọc được hoặc PATH khác shell tương tác.
8. Resource limit và cgroup
systemctl status myapp --no-pager
systemctl show myapp -p MemoryCurrent -p MemoryMax -p CPUQuota -p TasksCurrent -p TasksMax
systemd-cgtop
cat /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io
Nếu service bị kill do memory, hãy kiểm tra cả giới hạn systemd và kernel OOM. Nếu TasksMax thấp, ứng dụng nhiều thread/process có thể chết khó hiểu. Trên server bận, PSI trong /proc/pressure/* giúp nhận diện nghẽn CPU, memory hoặc I/O.
9. Timer thay cron: khi nào nên dùng
systemctl list-timers --all
cat > /etc/systemd/system/backup-db.timer <<'EOF'
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
EOF
systemctl enable --now backup-db.timer
systemd timer có log tập trung, trạng thái rõ ràng và Persistent=true để chạy bù nếu máy tắt vào thời điểm lịch. Nó phù hợp cho backup, cleanup, report và job vận hành cần quan sát tốt hơn cron truyền thống.
10. Troubleshooting các lỗi thường gặp
- Unit not found: sai tên unit, chưa daemon-reload hoặc package chưa cài.
- Start request repeated too quickly: service restart loop, xem log gốc rồi reset bằng systemctl reset-failed.
- Permission denied: kiểm tra User/Group, SELinux/AppArmor, quyền file và capability.
- TimeoutStartSec: ExecStartPre treo, dependency chưa sẵn sàng hoặc app khởi động quá lâu.
- Failed at step EXEC: binary/script không tồn tại, thiếu shebang hoặc không có quyền execute.
- EnvironmentFile missing: đường dẫn secret/env sai hoặc file không đọc được bởi systemd.
11. Checklist nghiệm thu sau khi xử lý
- Service active và không tăng NRestarts trong ít nhất 10-15 phút.
- Endpoint/port nghiệp vụ trả về đúng từ ngoài máy chủ.
- journalctl không còn lỗi mới ở mức warning..alert.
- systemctl list-units –failed sạch hoặc lỗi còn lại đã được ghi nhận.
- Dashboard CPU/RAM/disk/I/O/network ổn định.
- Override được lưu rõ ràng, có comment nếu thay đổi quan trọng.
- Runbook incident ghi lại timeline, nguyên nhân, lệnh đã chạy và hành động phòng ngừa.
12. Lab thực hành an toàn
Trên máy lab, tạo một service giả cố tình exit code 1, bật Restart=on-failure, quan sát NRestarts, sau đó thêm StartLimitBurst. Tiếp theo tạo timer chạy mỗi phút và kiểm tra log bằng journalctl -u ten-service. Bài tập nhỏ này giúp bạn hiểu cơ chế trước khi áp dụng vào production.
Kết luận
Linux systemd incident runbook giúp sysadmin phản ứng có phương pháp thay vì chỉ restart service. Khi nắm được status, journalctl, dependency, override, restart policy, cgroup và timer, bạn có thể khôi phục nhanh hơn, giảm downtime và biến mỗi sự cố thành cải tiến vận hành có kiểm chứng.
