使用 SystemD 和 "daemon.json" 启用 Docker 远程 HTTP API

3

免责声明:

在一台使用Upstart作为初始化系统的Ubuntu 14.04旧机器上,我通过在/etc/default/docker中定义DOCKER_OPTS来启用了HTTP API。它可以正常运行。

$ docker version
Client:
 Version:      1.11.2
 (...)

Server:
 Version:      1.11.2
 (...)

问题:

这个解决方案在使用SystemD的Ubuntu 16.04最新机器上无法使用。

如最近安装的文件/etc/default/docker顶部所述:

# Docker Upstart and SysVinit configuration file

#
# THIS FILE DOES NOT APPLY TO SYSTEMD
#
#   Please see the documentation for "systemd drop-ins":
#   https://docs.docker.com/engine/articles/systemd/
#
(...)

根据我在 SystemD 的 Docker 文档页面 上检查到的信息,我需要填写一个 daemon.json 文件,但在参考文献中指出有些属性是自解释的,而其他一些则可能解释不足。

话虽如此,我正在寻求帮助将这个转换为 daemon.json 对象:

DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -G myuser --debug"


注释

PS1: 我知道 daemon.json 有一个默认的 debug: true

PS2: 可能 group:"myuser" 会像这样工作,或者带有字符串数组。

PS3: 我的主要关注点是同时使用 SOCK 和 HTTP。


编辑(8/08/2017) 阅读接受的答案后,请参考 @white_gecko 答案以获得更多信息。


请注意,如果您按照这里的任何步骤操作,将会创建一个未加密的远程根登录到服务器,没有任何密码或凭据。任何拥有网络访问权限的人都可以轻松地在主机上运行一个以root身份运行的容器,并挂载主机文件系统。强烈建议保护此套接字:https://docs.docker.com/engine/security/https/ - BMitch
4个回答

10

由于文档零散,解决问题变得困难。

我的第一个解决方案是创建具有daemon.json的文件。

{
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://127.0.0.1:2376"
  ]
}

出现了错误,错误信息为:docker[5586]: unable to configure the Docker daemon with file /etc/docker/daemon.json,尝试使用service docker restart重启守护进程后仍未解决。

此错误的意思是,在启动守护程序时,与daemon.json上的标识和配置发生了冲突。

通过使用service docker status检查,发现父进程是:ExecStart=/usr/bin/docker daemon -H fd://

这很奇怪,因为它与/etc/init.d/docker上的配置不同,我认为那里面应该是服务的配置。更奇怪的是,init.d文件中没有任何关于daemon参数或-H fd://的引用。

经过一些研究以及在docker github issue #22339讨论中获得的帮助后,我找到了以下目录。

解决方案

编辑/lib/systemd/system/docker.service中的ExecStart,将其替换为:/usr/bin/docker daemon

然后创建/etc/docker/daemon.json文件,其内容为:

{
  "hosts": [
    "fd://",
    "tcp://127.0.0.1:2376"
  ]
}

最后使用service docker start重新启动了服务,现在service docker status状态显示为“绿色”。

使用以下命令测试了新的配置:

$ docker run hello-world

Hello from Docker!
(...)

而且,

$ curl http://127.0.0.1:2376/v1.23/info
[JSON]

我希望这能对像我一样有类似问题的人有所帮助! :)


也许你忘记复制的错误信息是:无法使用文件/etc/docker/daemon.json配置Docker守护程序:以下指令既在标志中指定,又在配置文件中指定:hosts:(来自标志:[fd://],来自文件:[tcp://127.0.0.1:2375 fd://]) - white_gecko
2
您不需要更改原始的 docker.service,可以使用 systemd 的 drop-in 文件,例如:/etc/systemd/system/docker.service.d/no_fd.conf,其中包含 [Service] ExecStart= ExecStart=/usr/bin/dockerd - Tomasz Sętkowski

5

我使用 https://docs.docker.com/engine/admin/#troubleshoot-conflicts-between-the-daemonjson-and-startup-scripts 中描述的解决方案成功解决了我的问题:

One notable example of a configuration conflict that is difficult to troubleshoot is when you want to specify a different daemon address from the default. Docker listens on a socket by default. On Debian and Ubuntu systems using systemd), this means that a -H flag is always used when starting dockerd. If you specify a hosts entry in the daemon.json, this causes a configuration conflict (as in the above message) and Docker fails to start.

To work around this problem, create a new file /etc/systemd/system/docker.service.d/docker.conf with the following contents, to remove the -H argument that is used when starting the daemon by default.

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
请注意,带有ExecStart=的行实际上是必需的,否则它将失败并显示以下错误信息:

docker.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.

创建文件后,您必须运行:
sudo systemctl daemon-reload
sudo systemctl restart docker

5
我遇到了同样的问题,实际上在我看来最简单的解决方案是使用systemd drop-in:只需创建一个文件/etc/systemd/system/docker.service,覆盖/lib/systemd/system/docker.service中服务的特定部分,这样就不会影响由系统更新过程管理的任何现有文件。在这种情况下,/etc/systemd/system/docker.service的内容应该是:
[Service]
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H=tcp://127.0.0.1:2375 -H=fd://

您甚至可以创建一个目录docker.service.d,其中包含多个文件以覆盖不同的参数。

在添加文件后,只需运行:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

你的建议很好!我会编辑问题,让新的观众也能看到你的答案。 - Paulo Oliveira
在Debian stretch上对我不起作用;我得到了docker.service:Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing. - Serrano
1
请注意,如果您想从外部访问,则IP应为0.0.0.0,否则仅通过本地主机可用。此外,Docker文档建议使用2376端口进行TLS连接,而不是2375 - Dmytro Titov

2

对于我来说,这在Ubuntu 18.04.1 LTS和Docker 18.06.0-ce上有效。创建/etc/systemd/system/docker.service.d/remote-api.conf文件,并添加以下内容:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock

然后运行sudo systemctl daemon-reloadsudo systemctl restart docker。 查看结果调用:

curl http://localhost:2376/info

如果您的docker在代理后面,您可能需要配置代理。 要实现这个,请在/etc/default/docker文件中粘贴以下内容:

http_proxy="http://85.22.53.71:8080/"
https_proxy="http://85.22.53.71:8080/"
HTTP_PROXY="http://85.22.53.71:8080/"
HTTPS_PROXY="http://85.22.53.71:8080/"
# below you can list some *.enterprise_domain.com as well
NO_PROXY="localhost,127.0.0.1,::1" 

或者创建/etc/systemd/system/docker.service.d/remote-api.conf文件,并写入以下内容:

[Service]
Environment="HTTP_PROXY=http://<you_proxy_ip>:<port>"
Environment="HTTPS_PROXY=https://<you_proxy_ip>:<port>/"
Environment="NO_PROXY=localhost,127.0.0.1,::1"

我希望这能帮助到有需要的人...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接