systemd 以哪个用户身份启动服务?

systemd 以哪个用户身份启动服务?

我想了解如何systemd启动服务,特别是以哪个用户身份启动服务,并且我想使用在我的 Linux PC 上运行的 Jenkins 作为示例。

我知道它initpid 1Linux 中所有进程的母亲,在我的例子中pid 1属于systemd,我可以从运行中看到top

$ top
Tasks: 646 total,   1 running, 645 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.0 us,  0.6 sy,  0.0 ni, 97.0 id,  1.3 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem : 257826.8 total, 198695.4 free,  28529.6 used,  30601.7 buff/cache
MiB Swap: 262012.0 total, 262012.0 free,      0.0 used. 227579.3 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0  171284  11196   7904 S   0.3   0.0  31:49.54 systemd

我天真地认为,因为systemd以 root 身份运行root,所以它运行的所有服务都将以 root 身份运行。
但我认为 Jenkins 正在admin我的 PC 上运行。
我尝试用来systemctl确定 Jenkins 正在以哪个用户身份运行,但我在标准输出中没有看到任何用户信息:

user@linux_box:~$ systemctl status jenkins
● jenkins.service - LSB: Start Jenkins at boot time
   Loaded: loaded (/etc/init.d/jenkins; generated)
   Active: active (exited) since Fri 2023-05-05 11:50:06 PDT; 3 days ago
     Docs: man:systemd-sysv-generator(8)
    Tasks: 0 (limit: 4915)
   Memory: 0B
   CGroup: /system.slice/jenkins.service

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
user@linux_box:~$

...所以我尝试ps aux

user@linux_box:~$ ps aux | grep jenkins
admin  2042  0.0  0.0  14164   196 ?        S    May05   0:00 /usr/bin/daemon --name=admin --inherit --env=JENKINS_HOME=/home/admin/jenkins --output=/var/log/jenkins/jenkins.log --pidfile=/var/run/admin/admin.pid -- /usr/bin/java -Djava.awt.headless=true -jar /home/admin/jenkins/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8080
admin  2043  1.7  5.3 48146100 14118144 ?   Sl   May05  83:41 /usr/bin/java -Djava.awt.headless=true -jar /home/admin/jenkins/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8080
admin 29932  0.0  0.0   6204   892 pts/1    S+   20:37   0:00 grep jenkins

...我认为最左边的专栏说詹金斯正在运行admin,不是吗?

有人可以解释一下之间的关系吗systemd有人可以解释一下, 用户运行身份与服务运行的用户身份?如果答案能够将其与 Jenkins 在这台 Linux PC 上的具体情况联系起来,那就太好了。

答案1

systemd 用于运行系统服务的默认用户确实是root,但当然可以使用该User选项进行自定义。从man 5 systemd.exec:

User=,Group=

分别设置执行进程的 UNIX 用户或组。采用单个用户名、组名或数字 ID 作为参数。对于系统服务(由系统服务管理器运行的服务,即由 PID 1 管理的服务)和 root 用户的用户服务(由 root 的实例管理的服务 systemd --user),默认为“ root”,但User=可以用于指定不同的用户。 [...]

在您的 Jenkins 案例中,systemd 使用基于 sysv init script 的生成单元/etc/init.d/jenkins,因此它不使用User选项(生成的单元非常基本:systemd 如何使用 /etc/init.d 脚本?)。 init 脚本似乎正在调用/usr/bin/daemon启动 Jenkins,并且从man 1 daemon:

The preparatory tasks that daemon performs for other processes are:
[...]

•   Change the process uid and gid if the --user option was supplied. Only root can use
    this option. Note that the uid of daemon itself is changed, rather than just changing
    the uid of the client process.

但是,输出中不存在此选项ps,因此它可能使用其他方式来更改 UID。检查/etc/init.d/jenkins脚本即可找到答案。

答案2

穆鲁的回答在大多数情况下是正确的,但我想添加有关--user巴士的信息。

systemd有两辆巴士: --system--user。巴士--system是默认的,穆鲁的答案适用于此。但您也可以在--user公交车上启动服务。

单元文件位于/lib/systemd/user/或中~/.config/systemd/user/,这些文件将以调用该服务的用户身份启动。该WantedBy=default.target服务将在用户登录时启动,或者WantedBy=graphical.target该服务将在用户获得图形会话时启动。

用户总线不仅仅是User=系统总线设置的替代方案。它提供了一种为每个用户创建服务实例的方法。例如,如果您想使用该用户的凭据将 sshfs 目录安装到主目录中的某个位置,则可以在用户总线上轻松完成此操作。

另一个特点是用户总线继承了用户的环境。这包括诸如DISPLAY和 之类的东西XAUTHORITY。这将帮助您在用户登录其桌面环境时启动 GUI 应用程序。相比之下,User=系统总线上的设置将无法找到正确的显示(除非明确指定),并且通常会在 DE 启动之前尝试启动 GUI 应用程序。

相关内容