如何實現 Linux 服務 Crash 後自動重啓?
概述
近期碰到了一個 Linux Systemd 服務 Crash, Crash 後需要人工介入重啓. 那麼, 有沒有辦法如何實現 Linux 服務 Crash 後自動重啓?
Systemd
Systemd Restart
Systemd 允許你對服務進行配置,以便在服務崩潰時自動重啓。
一個典型的單元文件是這樣的:
[Unit]
Description=Tailscale node agent
After=network-online.target
Wants=tailscale-weekly-update.timer
[Service]
Type=oneshot
ExecStart=/usr/bin/tailscale update -yes
[Install]
WantedBy=multi-user.target
在上面的例子中,如果守護進程崩潰或被殺死,systemd 不會去管它。
不過,你可以讓 systemd 自動重啓守護進程,以防它崩潰或意外被殺掉。爲此,你可以在 [Service]
中添加 Restart
選項。典型的示例如下:
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target
StartLimitIntervalSec=600
StartLimitBurst=5
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=-/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
上述操作會對任何導致守護進程停止的情況做出反應... 只要守護進程停止,systemd 就會在 5 秒內重啓它。
Restart
有 2 個可選參數:
•always
•on-failure
: 即故障時重啓. 涵蓋了最廣泛的故障情形,如信號不清和退出代碼不清:
在本例中,[Unit]
部分還有 StartLimitIntervalSec
和 StartLimitBurst
指令。這可以防止故障服務每 5 秒鐘重啓一次。如果仍然失敗,systemd 將停止嘗試啓動服務。
如果服務在 600 秒內 5 次嘗試重啓均未成功,則應進入失敗狀態,不再嘗試重啓。這樣就能確保如果服務真的壞了,systemd 不會繼續嘗試重啓它。應該人工上去處理了。
如果在守護進程被殺死後詢問其狀態,systemd 會顯示正在activating (auto-restart)
。
Systemd OnFailure
重啓一項服務固然很好,但在某個單元出現故障時採取特定行動就更好了。也許你使用的軟件有一個已知的錯誤,要求在崩潰時刪除緩存文件,也許你想啓動一個腳本來收集日誌和系統信息,以便診斷問題。Systemd 允許你指定在服務失敗時運行的單元。
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target
StartLimitIntervalSec=600
StartLimitBurst=5
OnFailure=k3s-recovery.service
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=-/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=on-failure
RestartSec=5s
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
此示例指定 OnFailure=k3s-recovery.service
來告訴 systemd,如果我的服務失敗,它就應該啓動 k3s-recovery
單元.
k3s-recovery
單元只是一個運行此腳本的一次性服務單元:
[Unit]
Description=K3s recovery
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/k3s-recovery.sh
這個腳本可以做任何事情:執行一些手動變通方法讓服務重新運行,向監控系統發出警報,或者壓縮一些臨時日誌和應用程序狀態以排除故障。示例如下:
#!/bin/bash
echo 'Attempting to recover!' > /tmp/recovery_info
systemctl stop k3s.service
/usr/local/sbin/k3s-killall.sh
systemctl start k3s.service
Systemd FailureAction reboot
還有一種可能, 重啓治百病! 所以 systemd 內置了在單元故障時觸發系統重啓的功能。在本例中,當單元發生故障時,系統將優雅地重新啓動:
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target
StartLimitIntervalSec=600
StartLimitBurst=5
FailureAction=reboot
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=-/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=on-failure
RestartSec=5s
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
FailureAction
有多種有效值: none
, reboot
, reboot-force
, reboot-immediate
, poweroff
, poweroff-force
, poweroff-immediate
, exit
, exit-force
, soft-reboot
, soft-reboot-force
, kexec
, kexec-force
, halt
, halt-force
和 halt-immediate
.
總結
本文介紹了服務異常時, 自動處理故障的一些方式。Systemd 包含強大的功能,可自動響應以保持服務運行。
References
[1]
Auto-restart a crashed service in systemd (ttias.be): https://ma.ttias.be/auto-restart-crashed-service-systemd/
[2]
Set up self-healing services with systemd | Enable Sysadmin (redhat.com): https://www.redhat.com/sysadmin/systemd-automate-recovery
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/5foPUpX26ddWnS3-Fpg-tA