systemd用户无法获取用户组的能力

systemd用户无法获取用户组的能力

我在 docker 组中添加了一个非 root 用户,并在该非 root 用户连接到 docker 守护进程时运行另一个服务。但服务无法工作。我为此做了一个测试示例:

root@# systemctl start docker.service 
root@# gpasswd -a tiger docker

在 Tiger 中创建一个 systemd 服务:

[Service]
ExecStart=/home/tiger/connectdocker
Restart=always
StartLimitInterval=0
Delegate=true
KillMode=process
[Install]
WantedBy=default.target

/home/tiger/connectdocker这样:

docker run -itd busybox 2> connectdocker.log

启动这个服务:

tiger@# systemctl --user enable connectdocker.service
tiger@# systemctl --user start connectdocker.service

结果:

Thu Jul 21 00:59:15 CST 2016
Cannot connect to the Docker daemon. Is the docker daemon running on this host?

但我可以用 Tiger 连接到 docker.sock :

tiger@# docker run -itd busybox
997e99f959cfd5500319935ec17677775da9d367d203a11efef8b42161c3ee64

为了证明这一点,我将/var/run/docker.sock组从 docker 更改为 Tiger,并且 connectdocker 服务可以连接到 docker 守护进程。

改变/var/run/docker.sock

ls -l /run/docker.sock
srw-rw---- 1 root docker 0 Jul 21 00:33 /run/docker.sock

到:

ls -l /run/docker.sock
srw-rw---- 1 root tiger 0 Jul 21 00:33 /run/docker.sock

答案1

您应该User=在您的服务中使用该指令systemd

用户=,组=

分别设置执行进程的 UNIX 用户或组。采用单个用户或组名或数字 ID 作为参数。对于系统服务(由系统服务管理器运行的服务,即由PID 1管理的服务)和root用户的用户服务(由root的systemd --user实例管理的服务),默认为“root”,但User=可以用于指定不同的用户。对于任何其他用户的用户服务,不允许切换用户身份,因此唯一有效的设置是运行用户服务管理器的同一用户。如果没有设置组,则使用用户的默认组。此设置不会影响命令行以“+”为前缀的命令。

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#User=

我还建议将您的脚本从主目录移动到标准路径,例如/usr/local/bin或类似的路径。

connectdocker.service您还应该通过提供After=docker.service和来确保您的顺序Requires=docker.service。正如所写,connectdocker.service可能会尝试与 大约同时启动docker.service,并且您需要等待docker.service启动才能连接到它。

需要=

配置对其他单元的需求依赖性。如果该单位被激活,此处列出的单位也将被激活。如果其他单位之一被停用或激活失败,则该单位将被停用。可以多次指定此选项,也可以在一个选项中指定多个空格分隔的单元,在这种情况下,将创建所有列出的名称的需求依赖关系。请注意,需求依赖性不会影响服务启动或停止的顺序。这必须使用 After= 或 Before= 选项独立配置。如果单元 foo.service 需要使用 Requires= 配置的单元 bar.service,并且没有使用 After= 或 Before= 配置排序,那么如果激活 foo.service,两个单元将同时启动,并且它们之间没有任何延迟。通常,使用 Wants= 而不是 Requires= 是更好的选择,以便使系统在处理故障服务时更加健壮。

请注意,此依赖性类型并不意味着当该单元运行时另一个单元必须始终处于活动状态。具体来说:失败的条件检查(例如 ConditionPathExists=、ConditionPathExists=、... — 见下文)不会导致具有 Requires= 依赖性的单元的启动作业失败。此外,某些单元类型可能会自行停用(例如,服务进程可能决定完全退出,或者设备可能被用户拔出),这不会传播到具有 Requires= 依赖性的单元。将 BindsTo= 依赖类型与 After= 一起使用,以确保一个单元永远不会处于活动状态,而没有特定的其他单元也处于活动状态(见下文)。

请注意,这种类型的依赖项也可以通过将符号链接添加到单元文件附带的 .requires/ 目录来在单元配置文件之外进行配置。详细信息请参见上文。

https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires=

https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before=

相关内容