我正在将一些服务从 Ubuntu 18.04 迁移到 20.04。在 18.04 中,我以非 root 用户身份运行这些服务。所有这些服务都启动了一个 docker 容器,并且运行良好。在 Ubuntu 20.04 下,这些服务不再启动。
为了说明,这是一个~/.config/systemd/user/hello-world.service
在 Ubuntu 18.04 上运行良好的非常简单的程序:
# -*-systemd-*-
[Unit]
Description=Hello world
After=network.service
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
TimeoutStartSec=0
ExecStartPre=/bin/echo user = $USER
ExecStartPre=/usr/bin/docker pull hello-world
ExecStart=/usr/bin/docker run \
--name hello-world \
--rm -a STDIN -a STDOUT -a STDERR \
hello-world
ExecStop=/usr/bin/docker stop -t 2 %n
[Install]
WantedBy=default.target
我以非 root 用户身份直接在 shell 中运行容器,并且它在 18.04 机器和 20.04 机器上运行良好:
/usr/bin/docker pull hello-world
/usr/bin/docker run \
--name hello-world \
--rm -a STDIN -a STDOUT -a STDERR \
hello-world
对于 systemd 我运行以下命令:
systemctl --user enable hello-world.service
systemctl --user start hello-world.service
在 Ubuntu 18.04 上,当我调查结果时,一切都按预期运行journalctl -xe -f
。
在 Ubuntu 20.04 上,我遇到了可怕的问题:
Sep 15 14:56:26 m4 docker[107614]: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/create?fromImage=hello-world&tag=latest: dial unix /var/run/docker.sock: connect: permission denied
我检查了权限、组,一切似乎都正确。同样,如果我以 身份登录时直接在命令行中运行 docker username
,docker 就可以正常运行。
root@m4:/etc/apt> ll /var/run/docker.sock
srw-rw---- 1 root docker 0 Sep 15 14:08 /var/run/docker.sock=
root@m4:/etc/apt> grep docker /etc/group
docker:x:998:docker,username
唯一不同的是,18.04 上的 systemd 版本是 237,而 20.04 上的 systemd 版本是 245。
两台机器上的 Docker 是相同的:
Docker version 19.03.12, build 48a66213fe
两个版本的 systemd 均显示该用户ExecStartPre
为非 root 用户。
看起来 systemd 245 正在以错误的用户和/或组启动 docker 进程。有什么想法吗?
更新
正如@larsks所建议的,我将其替换$USER
为/usr/bin/id
。这是我收到的输出:
Sep 15 21:36:09 m4 id[122143]: uid=1001(username) gid=1001(username) groups=1001(username)
Sep 15 21:36:09 m4 docker[122144]: Using default tag: latest
Sep 15 21:36:09 m4 docker[122144]: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/create?fromImage=hello-world&tag=latest: dial unix /var/run/docker.sock: connect: permission denied
username
是该组的一部分docker
,如上所示。
答案1
您的 systemd 用户单元未指定Group=
,因此将使用用户的默认组。由于docker
不是默认组,systemd 不会使用此组启动进程。
Group=docker
在[Service]
单位部分进行设置。
答案2
看看docker 容器单元文件示例我认为至少缺少的是:
After=docker.socket
在里面[Unit]
单元文件的部分Delegate=yes
和[Service]
部分,以便
这样 systemd 就不会重置 docker 容器的 cgroups
环境:
KillMode=process
以便
仅终止 docker 进程,而不是 cgroup 中的所有进程
对我来说这似乎也是个好主意。我建议看一下链接的示例并相应地配置单元文件。
答案3
事实证明,老式的重启可以解决问题。:(
在此之前,我曾尝试重新启动 systemd,但问题并未解决。我仍然不知道发生了什么,可能是我遇到了内核和 systemd 配置中的一些错误。
核心:5.4.0-47-generic #51-Ubuntu
系统:
systemd 245 (245.4-4ubuntu3.2)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid