Systemd 使用 reload 升级二进制文件

Systemd 使用 reload 升级二进制文件

我有一个程序,当给出 SIGUSR2 时,它会分叉并正常创建一个新进程(将所有现有的父套接字传递给子进程,并杀死父进程),而不会停机,因此通常在没有 systemd 的情况下它会是这样的:

cp newbinary coredns
kill -s USR2 oldpid

Systemd 只具有ExecReload根据此回答

换句话说,systemd 希望您仅在底层服务支持真正的重新加载功能时才实现“重新加载”……即不会终止并重新启动服务或使服务更改其 PID 的重新加载。换句话说,systemd 只想反映现有的功能。

它可以是类似于这样的 systemd 文件:

PIDFile=/tmp/coredns.pid
Type=forking
ExecStart=./coredns -pidfile /tmp/coredns.pid
ExecStop=kill `/tmp/coredns.pid`
ExecReload=/bin/kill -s USR2 `cat /tmp/coredns.pid`

问题是,在执行时sudo systemctl reload coredns,systemd 是否会:

  1. 知道 pid 改变了吗?
  2. 还能正确处理日志和进程监控吗?

答案1

好的,forking否则oneoff启动时会卡住,类型应该是simple,它会正常工作:

echo '[Unit]
Description=Custom CoreDNS DNS server
After=network.target
[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
LimitNPROC=512
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
WorkingDirectory=/tmp/1
Type=simple
RemainAfterExit=yes
ExecStart=/tmp/1/start.sh
ExecStop=/tmp/1/kill.sh
ExecReload=/tmp/1/reload.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target 
' | sudo tee /usr/lib/systemd/system/coredns.service
sudo systemctl daemon-reload 

创建脚本:

mkdir -p /tmp/1
echo '#!/usr/bin/bash
kill -s USR2 `cat /tmp/1/coredns.pid`
' > /tmp/1/reload.sh
echo '#!/usr/bin/bash
kill -s USR2 `cat /tmp/1/coredns.pid`
' > /tmp/1/kill.sh
echo '#!/usr/bin/bash
/tmp/1/coredns -pidfile /tmp/1/coredns.pid -conf=/tmp/1/Corefile
' > /tmp/1/start.sh
chmod a+x /tmp/1/*.sh
chmod 777 /tmp/1 # just so that no need to set user permission on systemd
cp Corefile coredns /tmp/1/

可以正常启动:

sudo systemctl start coredns

# on journalctl:
Apr 20 18:50:06 pop2204 systemd[1]: Started Custom CoreDNS DNS server.
Apr 20 18:50:06 pop2204 start.sh[1553313]: whoami Name called
Apr 20 18:50:06 pop2204 start.sh[1553313]: whoami Name called
Apr 20 18:50:06 pop2204 start.sh[1553313]: whoami Name called
Apr 20 18:50:06 pop2204 start.sh[1553313]: .:1053
Apr 20 18:50:06 pop2204 start.sh[1553313]: CoreDNS-1.9.4
Apr 20 18:50:06 pop2204 start.sh[1553313]: linux/amd64, go1.20.3, 81159d2f-dirty

删除旧的二进制文件(因为直接复制会导致文本文件繁忙错误),然后复制新的二进制文件

rm /tmp/1/coredns
cp coredns /tmp/1/coredns
sudo systemctl reload coredns

# from journalctl:
Apr 20 18:52:03 pop2204 systemd[1]: Reloading Custom CoreDNS DNS server...
Apr 20 18:52:03 pop2204 start.sh[1553313]: [INFO] SIGUSR2: Upgrading
Apr 20 18:52:03 pop2204 start.sh[1553313]: [INFO] Upgrading
Apr 20 18:52:03 pop2204 systemd[1]: Reloaded Custom CoreDNS DNS server.
Apr 20 18:52:03 pop2204 start.sh[1553726]: whoami Name called 2
Apr 20 18:52:03 pop2204 start.sh[1553726]: whoami Name called 2
Apr 20 18:52:03 pop2204 start.sh[1553726]: whoami Name called 2
Apr 20 18:52:03 pop2204 start.sh[1553726]: .:1053
Apr 20 18:52:03 pop2204 start.sh[1553313]: [INFO] Upgrade finished
Apr 20 18:52:03 pop2204 start.sh[1553726]: CoreDNS-1.9.4
Apr 20 18:52:03 pop2204 start.sh[1553726]: linux/amd64, go1.20.3, 81159d2f-dirty

相关内容