环境:
- a.rpm : 包含apiserver
- apiserver:提供api接口(使用gin), 包括上传升级包的接口
- upgrader: 升级程序
目的:卸载a.rpm再安装新版a.rpm
步骤:
- 通过apiserver上传升级包tar.gz, 解压并执行
nohup ./upgrader >/dev/null 2>&1 &
开始升级 - upgrader里执行
rpm -e a
或systemctl stop a
kill apiserver时upgrader会收到SIGKILL
(由systemd发给它)导致升级异常中止
通过ps查到upgrader的父进程是systemd, 此时upgrader应该和apiserver没有关系才对, apiserver被killed时, 为什么upgrader会收到SIGTERM?
原因:cgroup仍旧保持了apiserver和upgrader的关系.
解决方法:
systemd-run --unit=my_system_upgrade --scope --slice=my_system_upgrade_slice -E setsid nohup upgrader >/dev/null 2>&1 &
这应该与 systemd 利用cgroup进行层级管理有关系,systemd停止一个服务时,默认的KillMode是基于cgroup来识别的,换句话说systemd中管理的服务,下面fork出来的子进程,即使被你丢入后台,父进程脱离了原先进程的关联,它的cgroup层级还是默认被关联在原来的服务下。
具体你可以看看man systemd.kill中的说明,然后调整一下apiserver的systemd配置,改下默认的KillMode配置,改为process试试。