ให้ service ใน linux restart อัตโนมัติ
2 June 2021
บางครั้งเราจะพบเหตุการณ์ที่ service ใน linux ปัญหาขึ้นแล้วทำให้ service stop หรือ fail ไป ทำให้เครื่องเราให้บริการไม่ได้อย่างสมบูรณ์
ยกตัวอย่างเช่น service chronyd ที่ทำหน้าที่ในการ sync เวลาของเครื่องเรากับ time server หาก service stop ไป ก็จะทำให้เวลาของเครื่องเราอาจจะไม่ตรง และยิ่งในระบบที่แต่ละเครื่องจำเป็นต้องมีเวลาที่ตรงกันด้วยแล้ว การเกิดปัญหานี้อาจจะทำให้เกิดผลกระทบที่ร้ายแรงได้
วิธีทำให้ service สามารถ restart ตัวเองขึ้นมาได้เองอัตโนมัติสามารถทำได้โดยให้เพิ่ม 2 บรรทัดนี้ใน section “[Service]” ของ config file ของ service ตัวนั้น
Restart=always
RestartSec=3
ยกตัวอย่างเช่นเราอยากจะทำให้ service “chronyd” restart อัตโนมัติ โดยการจะทดสอบโดยการ kill process ของ chronyd แล้วดูว่า service chronyd จะ start ขึ้นมาให้เองได้หรือไม่
เราก็มาหาดู file config ของ service chronyd กันก่อน โดยใช้คำสั่ง
service chronyd status
ก็จะได้ผลออกมาเป็นดังนี้
Loaded: loaded (/lib/systemd/system/chrony.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2021-06-02 04:18:32 UTC; 16min ago
Docs: man:chronyd(8)
man:chronyc(1)
man:chrony.conf(5)
Process: 1704 ExecStart=/usr/lib/systemd/scripts/chronyd-starter.sh $DAEMON_OPTS (code=exited, status=0/SUCCESS)
Process: 1720 ExecStartPost=/usr/lib/chrony/chrony-helper update-daemon (code=exited, status=0/SUCCESS)
Main PID: 1718 (chronyd)
Tasks: 2 (limit: 4713)
Memory: 1.0M
CGroup: /system.slice/chrony.service
├─1718 /usr/sbin/chronyd -F -1
└─1719 /usr/sbin/chronyd -F -1Jun 02 04:18:32 instance-1 systemd[1]: Starting chrony, an NTP client/server...
Jun 02 04:18:32 instance-1 chronyd[1718]: chronyd version 3.5 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 -DEBUG)
Jun 02 04:18:32 instance-1 chronyd[1718]: Frequency -69.003 +/- 0.617 ppm read from /var/lib/chrony/chrony.drift
Jun 02 04:18:32 instance-1 chronyd[1718]: Loaded seccomp filter
Jun 02 04:18:32 instance-1 systemd[1]: Started chrony, an NTP client/server.
Jun 02 04:18:36 instance-1 chronyd[1718]: Selected source 169.254.169.254
ที่บรรทัดแรกเราจะพบว่า config file ของ service chronyd จะอยู่ที่ /lib/systemd/system/chrony.service
เราก็ไปแก้ไข file นี้ แล้วเพิ่ม 2 บรรทัดที่ต้องการเข้าไป
[Unit]
Description=chrony, an NTP client/server
Documentation=man:chronyd(8) man:chronyc(1) man:chrony.conf(5)
Conflicts=openntpd.service ntp.service ntpsec.service
Wants=time-sync.target
Before=time-sync.target
After=network.target[Service]
Type=forking
PIDFile=/run/chronyd.pid
EnvironmentFile=-/etc/default/chrony
# Starter takes care of special cases mostly for containers
ExecStart=/usr/lib/systemd/scripts/chronyd-starter.sh $DAEMON_OPTS
ExecStartPost=-/usr/lib/chrony/chrony-helper update-daemon
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
Restart=always
RestartSec=3[Install]
Alias=chronyd.service
WantedBy=multi-user.target
จากนั้นก็ทำการ save แล้วทำการ reload daemon config เพื่อให้ service systemd รู้จัก file ที่เราเพิ่งแก้ไขเข้าไป โดยใช้คำสั่ง
systemctl daemon-reload
จากนั้นก็ restart ตัว service chronyd ที่เราเพิ่งแก้ไข config ไปเพื่อให้สิ่งที่เราเพิ่งแก้ไขไปมีผล
systemctl restart chronyd
คราวนี้มาลองทดสอบกัน
ตอนนี้ process id ของ service chronyd คือ 1718
เราจะทำให้ process นี้หายไปโดยการ kill process นี้
kill 1718
จากนั้นรอประมาณ 3 วินาที ตัวระบบจะทำการ start process chronyd ขึ้นมาให้เองใหม่
จะพบว่า process ของ chronyd ที่มี process id 1718 หายไปแล้ว และเกิด process ของ chronyd เกิดขึ้นมาใหม่ และได้หมายเลข process id เป็น 1799
เท่านี้เราก็จะมั่นใจได้แล้วว่า service ของเราจะทำงานได้อย่างต่อเนื่องตลอดเวลาครับ 😄
(แต่ก็อย่าลืมเข้าไปตรวจดู log ของระบบด้วยนะครับว่าเกิดปัญหา service stop ขึ้นมาบ้างหรือเปล่า เมื่อไหร่ หาสาเหตุ และแก้ปัญหา เพื่อไม่ให้เกิดปัญหาซ้ำขึ้นอีกครับ)
อ้างอิง https://jonarcher.info/2015/08/ensure-systemd-services-restart-on-failure/