当使用 systemd 在该用户下运行多个服务时,该用户的所有服务都会被终止

当使用 systemd 在该用户下运行多个服务时,该用户的所有服务都会被终止

我们使用的是 Ubuntu 16.04 LTS,并希望使用多个 Tomcat 安装,这些安装应在启动时启动。其中一个 Tomcat 将托管一个 Jenkins,它将把一个 Web 应用程序部署到另一个 Tomcat 上并重新启动它。

为了启动服务,我们添加了 systemd 服务脚本。我们注意到,当一只雄猫被停止或杀死时,另一只也会被停止。

我们将其简化为两个仅使用 /usr/bin/yes 的简单脚本:

A单元

[Unit]
Description=A
After=syslog.target network.target

[Service]
Type=simple

ExecStart=/usr/bin/yes
ExecStop=/bin/kill -15 $MAINPID

User=tomcat8
Group=tomcat8

[Install]
WantedBy=multi-user.target

B单元

[Unit]
Description=B
After=syslog.target network.target

[Service]
Type=simple

ExecStart=/usr/bin/yes
ExecStop=/bin/kill -15 $MAINPID

User=tomcat8
Group=tomcat8

[Install]
WantedBy=multi-user.target

会发生什么:当一个服务被终止 ( kill -9) 时,两个服务都会随之消失。

  1. 为什么这两个服务都被杀死了?我们怎样才能防止这种情况发生呢?
  2. 是否不鼓励在单个用户下运行多个服务,或者这是一种好的做法?

编辑:为了澄清——我们在启动没有 systemd 的 tomcats 时也尝试做同样的事情。在本例中,行为符合预期:只有被终止的服务被停止,而其他服务则继续运行。

编辑2:该用户根本不是登录/退出的前端用户。纯粹是系统用户限制服务的访问。

答案1

变更日志对于 systemd (v230) 来说:

现在,当用户注销时,systemd-logind 将默认终止属于用户会话范围单元 (session-XX.scope) 一部分的用户进程。此行为由 logind.conf 中的 KillUserProcesses= 设置控制,之前的默认值“no”现在更改为“yes”。这意味着用户会话将在之后被正确清理,但需要额外的步骤才能允许故意长时间运行的进程在注销后继续存在。

所以这是默认行为。它还解释了如何撤消更改:logind.conf、设置KillUserProcesses=no --without-kill-user-processes optionconfigure

但变更日志还包括......

当用户至少登录一次且[email protected]正在运行时,并且在任何单个登录会话结束后应继续存在的任何服务都可以在用户服务或作用域中使用 启动systemd-run。 systemd-run(1) 手册页已扩展为一个示例,该示例展示了如何在下面的范围单元中运行 screen [email protected]。相同的命令适用于 tmux。

用户退出所有会话后,[电子邮件受保护]默认情况下,除非用户启用,否则也会被终止lingering。为了有效地允许用户在注销的情况下运行长期任务,必须为他们启用延迟。详细信息请参见loginctl(1)。修改了默认的 polkit 策略,允许用户无需身份验证即可为自己设置延迟

这个更重要,因为它使用默认值(kill'm all)和一种提供异常的方法:enable lingering

更多信息:

答案2

我认为问题在于systemd依赖性安排。

听起来是这样的关闭逻辑可能正在发生:

当两个具有顺序依赖性的单元被关闭时,将应用启动顺序的逆顺序。即,如果一个单元在另一个单元上配置了 After=,则如果两个单元都关闭,则前者会先于后者停止。

但是,您的示例脚本并未显示您已在两者之间创建了依赖关系。

我尝试运行您的示例“A”脚本,但它没有启动:

 Failed at step USER spawning /usr/bin/yes: No such process

(我在 Ubuntu 16.04 上测试过)。

相关内容