🧱 Linux systemctl 與服務管理全攻略(含常見錯誤與自動重啟設定)
這篇整理 systemctl 的常用與進階操作:從 查詢與控制服務、開機自啟、自動重啟策略、覆寫 drop-in 到 journalctl 排錯、Timer 排程、安全強化,提供可直接複製的指令與範例單元檔。
📑 目錄
- 一、常用 systemctl 指令速查
- 二、開機自動啟動與目標(target)
- 三、自動重啟策略(Restart=)最佳實務
- 四、Service Unit 樣板:穩定、可回復、可觀測
- 五、不改原檔的覆寫:drop-in(systemctl edit)
- 六、常見錯誤與排查清單
- 七、journalctl 與啟動耗時分析
- 八、Timer vs cron:事件式排程與補跑
- 九、服務沙箱與資源限制
- 🔎 常見問答(FAQ)
- 🧭 行動清單
- 🔗 延伸閱讀
一、常用 systemctl 指令速查
# 啟動 / 停止 / 重新啟動 / 重新載入設定
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx
# 查看狀態與即時日誌
systemctl status nginx
journalctl -u nginx -f
# 查看是否開機自啟;設定開機自啟 / 取消
systemctl is-enabled nginx
sudo systemctl enable nginx
sudo systemctl disable nginx
# 列出服務、套用變更
systemctl list-units --type=service --state=running
sudo systemctl daemon-reload
# 查看單元檔與依賴
systemctl cat nginx.service
systemctl list-dependencies multi-user.target
二、開機自動啟動與目標(target)
enable 會建立 WantedBy 目標(通常 multi-user.target),讓服務於開機時載入。
# 目前預設 target 與切換
systemctl get-default
sudo systemctl set-default multi-user.target
sudo systemctl isolate rescue.target # 立即切換到維護模式
三、自動重啟策略(Restart=)最佳實務
Restart=on-failure:非 0 結束碼時重啟,最常用。Restart=always:任何結束都重啟,用於長駐、須高可用的服務。RestartSec=:重啟間隔;StartLimitIntervalSec=+StartLimitBurst=防止瘋狂重啟。- 加上
RuntimeMaxSec=或健康檢查腳本,避免服務卡死無感。
四、Service Unit 樣板:穩定、可回復、可觀測
📄 點我展開範例(建議複製後依實際路徑與使用者調整)
[Unit]
Description=My Web App
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 /opt/myapp/app.py
# --- 重啟策略 ---
Restart=on-failure
RestartSec=3
StartLimitIntervalSec=60
StartLimitBurst=5
# --- 環境與日誌 ---
Environment="ENV=prod" "PORT=8080"
StandardOutput=journal
StandardError=journal
# --- 沙箱化(見下節 Hardening)---
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
五、不改原檔的覆寫:drop-in(systemctl edit)
不要改套件提供的 /usr/lib/systemd/system/*.service;用 drop-in 更安全。
sudo systemctl edit myapp.service
# 會開啟 /etc/systemd/system/myapp.service.d/override.conf
# 只放差異:
[Service]
Restart=always
Environment="DEBUG=false"
# 套用
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl cat myapp.service
六、常見錯誤與排查清單
- 🔌 啟動卡住:缺
Wants=network-online.target或未正確等待網路;檢查NetworkManager-wait-online或systemd-networkd-wait-online。 - 🗝 權限錯誤:服務
User=指定帳號是否擁有目錄與檔案權限;用chown/chmod修正。 - 📁 路徑不存在:在
ExecStartPre=/usr/bin/mkdir -p /var/lib/myapp先建立。 - 👻 Type 設錯:傳統 daemon 應
Type=forking;有通知機制才用notify。 - 🔁 無限重啟:調整
RestartSec、StartLimit*,並用journalctl -xeu找根因。
七、journalctl 與啟動耗時分析
# 當次開機的重要訊息
journalctl -b -p warning
# 追服務日誌(即時)
journalctl -u myapp.service -f
# 啟動耗時總覽與關鍵鏈
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
# 輸出啟動流程圖(SVG)
systemd-analyze plot > /tmp/boot.svg
八、Timer vs cron:事件式排程與補跑
🕒 範例:每天 02:15 執行備份、關機期間補跑
# /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=*-*-* 02:15:00
Persistent=true
RandomizedDelaySec=120
[Install]
WantedBy=timers.target
# 啟用
sudo systemctl enable --now backup.timer
systemctl list-timers --all
九、服務沙箱與資源限制
- 資源限制:
CPUQuota=50%、MemoryMax=1G。 - 沙箱化選項:
NoNewPrivileges=true、PrivateTmp=true、ProtectSystem=full、ProtectHome=true、CapabilityBoundingSet=(最小權限)。 - 臨時限制執行:
systemd-run --scope -p CPUQuota=50% -p MemoryMax=1G <cmd>
# 以 50% CPU、1G 記憶體限制執行
sudo systemd-run --unit=limit-job --scope -p CPUQuota=50% -p MemoryMax=1G /usr/bin/some-task
🔎 常見問答(FAQ)
Q1:我改了 unit 檔,但服務沒有套用?
請先 sudo systemctl daemon-reload 再 restart。變更才會被載入。
Q2:服務已 enable,為何開機沒有跑?
檢查 WantedBy 所屬 target 是否為系統 get-default 的依附鏈;另查 journalctl -b。
Q3:如何讓 oneshot 任務失敗也能重試?
在 [Service] 使用 Restart=on-failure 與 RestartSec=,並將邏輯拆為可重入。
🧭 行動清單
✅ 將既有服務加入 Restart 策略與 StartLimit* 保護 ✅ 以 systemctl edit 建立 drop-in 覆寫(不動原檔) ✅ 用 journalctl 與 systemd-analyze 檢查開機瓶頸 ✅ 關鍵任務改用 Timer,啟用 Persistent 與 RandomizedDelaySec ✅ 套用沙箱化選項與資源上限(CPUQuota / MemoryMax)
🔗 延伸閱讀
- 🐧 Linux systemd 深入解析與啟動流程管理
- Linux sed 使用基礎說明:文字取代、刪除與常用範例
- Linux Log 分析與 GoAccess 網頁報表
- Linux Proxy Server 建置教學(Squid 安裝與設定指南)
— WWFandy・系統管理筆記
沒有留言: