使用 snap 安装 docker 后无法启动 dockerd

Xin*_* Ma 5 docker 16.04 snap

我正在运行 16.04(distro=Ubuntu 16.04.1 LTS和 kernel= 4.4.0-45-generic)并通过 docker snap 安装了 docker。

snap install docker
Run Code Online (Sandbox Code Playgroud)

这是我的快照列表。

# snap list
Name               Version   Rev  Developer  Notes
docker             1.11.2-9  56   canonical  -
snapstore-example  0.3       4    noise      -
ubuntu-core        16.04.1   423  canonical  -
Run Code Online (Sandbox Code Playgroud)

但我无法启动 docker 守护进程。我做了什么

systemctl start snap.docker.dockerd.service
Run Code Online (Sandbox Code Playgroud)

错误日志似乎已获得许可。

Nov 30 00:54:20 ubuntu-xenial systemd[1]: Started Service for snap application docker.dockerd.
Nov 30 00:54:20 ubuntu-xenial snap[19148]: grep: /proc/self/mountinfo: Permission denied
Nov 30 00:54:20 ubuntu-xenial snap[19148]: time="2016-11-30T00:54:20.708894420Z" level=fatal msg="can't create unix socket /var/run/docker.sock: permission denied"
Nov 30 00:54:20 ubuntu-xenial systemd[1]: snap.docker.dockerd.service: Main process exited, code=exited, status=1/FAILURE
Nov 30 00:54:20 ubuntu-xenial systemd[1]: snap.docker.dockerd.service: Unit entered failed state.
Nov 30 00:54:20 ubuntu-xenial systemd[1]: snap.docker.dockerd.service: Failed with result 'exit-code'.
Nov 30 00:54:20 ubuntu-xenial systemd[1]: snap.docker.dockerd.service: Service hold-off time over, scheduling restart.
Nov 30 00:54:20 ubuntu-xenial systemd[1]: Stopped Service for snap application docker.dockerd.
Nov 30 00:54:20 ubuntu-xenial systemd[1]: snap.docker.dockerd.service: Start request repeated too quickly.
Nov 30 00:54:20 ubuntu-xenial systemd[1]: Failed to start Service for snap application docker.dockerd.
Run Code Online (Sandbox Code Playgroud)

这个错误更具体。

Nov 30 00:54:20 ubuntu-xenial snap[19148]: time="2016-11-30T00:54:20.708894420Z" level=fatal msg="can't create unix socket /var/run/docker.sock: permission denied"

而如果我这样做apt-get install docker.io并尝试使用systemctl start docker.service. 它运作良好。

docker snap 有什么已知问题?还是我错过了任何一步。谢谢!

Xin*_* Ma 2

经过一些初步的故障排除后。我自己找到了 RC。看来 apparmor 阻止了两者grep: /proc/self/mountinfo并在中创建套接字/var/run/docker.sock

syslog.1:Nov 30 02:18:27 ubuntu-xenial kernel: [ 5359.923039] audit: type=1400 audit(1480472307.476:349): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/proc/19448/mountinfo" pid=19448 comm="umount" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
syslog.1:Nov 30 02:18:27 ubuntu-xenial kernel: [ 5359.923053] audit: type=1400 audit(1480472307.476:350): apparmor="DENIED" operation="open" profile="snap.docker.dockerd" name="/proc/19448/mounts" pid=19448 comm="umount" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
syslog.1:Nov 30 02:38:28 ubuntu-xenial kernel: [ 6560.900141] audit: type=1400 audit(1480473508.452:362): apparmor="DENIED" operation="connect" profile="snap.docker.docker" name="/run/docker.sock" pid=20591 comm="docker" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=0
Run Code Online (Sandbox Code Playgroud)

但这是为什么呢。为什么 16.04 提供了默认的 apparmor 配置文件(在 中/var/lib/snapd/apparmor/profiles/snap.docker.docker),它会阻止 dockerd 守护进程启动。


小智 1

我怀疑您正在运行 snapd 2.16ubuntu3,这是 16.04 中当前可用的版本。您可以通过以下方式验证:

$ apt-cache policy snapd
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,问题是安装时未连接 docker 接口。默认情况下,docker 的一些 snappy 接口不会自动连接,但可以使用存储中的 snap 声明来自动连接它们。我们有让 docker 自动连接接口的 snap 声明,但 2.16ubuntu3 还不知道如何使用它们。你有两个选择:

  1. 从 xenial 建议安装 snapd: https://launchpad.net/ubuntu/+source/snapd/2.17.1ubuntu1

  2. 手动连接接口。例如:

$ snap interfaces |grep docker # show the disconnected interfaces
docker:docker-daemon     -
:docker-support          -
:home                    docker
:network                 docker
:network-bind            docker
-                        docker:docker-cli
-                        docker:firewall-control
-                        docker:privileged
-                        docker:support

# connect the interfaces
$ sudo snap connect docker:support ubuntu-core:docker-support
$ sudo snap connect docker:firewall-control ubuntu-core:firewall-control
$ sudo snap connect docker:docker-cli docker:docker-daemon

$ snap interfaces | grep docker # show the connected interfaces
docker:docker-daemon     docker:docker-cli
:docker-support          docker:support
:firewall-control        docker
:home                    docker
:network                 docker
:network-bind            docker
-                        docker:privileged

# restart the daemon
$ sudo service snap.docker.dockerd stop
$ sudo service snap.docker.dockerd start

# verify it worked
$ sudo docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
...
Run Code Online (Sandbox Code Playgroud)

如果您想使用 docker 特权容器,请使用以下命令连接该接口:

$ sudo snap connect docker:privileged ubuntu-core:docker-support
Run Code Online (Sandbox Code Playgroud)

如果您不想使用“sudo”,请创建 docker 组并将自己添加到其中:

$ sudo addgroup docker
$ sudo adduser `id -un` docker
$ newgrp docker

# restart docker so it will make the socket group writable by 'docker'
$ sudo service snap.docker.dockerd stop
$ sudo service snap.docker.dockerd start

$ docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
...
Run Code Online (Sandbox Code Playgroud)

您可以在此处获取有关 snappy 界面的更多信息: https ://github.com/snapcore/snapd/wiki/Interfaces

如前所述,一旦安装了 snapd 2.17 或更高版本,就不再需要“snap connect”命令。它也在本机支持系统组的路线图上,因此您不必自己将组添加到系统中。