【问题标题】:what does fd:// mean exactly in dockerd -H fd://fd:// 在 dockerd -H fd:// 中究竟是什么意思
【发布时间】:2021-01-09 01:37:31
【问题描述】:

Docker daemon documentation 建议大多数设置使用以下hosts 选项:

dockerd -H fd://

我猜fd 代表文件描述符。我不明白fd 是如何用于套接字通信的。

我了解以下选项:

-H unix:///var/run/docker.sock -H tcp://192.168.59.106 -H tcp://10.10.10.2

这些是 unix 域套接字和 tcp 套接字。我知道如何使用这些套接字调用 docker daemon:

docker -H tcp://0.0.0.0:2375 ps

但如果我使用 -H fd:// 启动 docker 守护程序,则以下调用会出错:

$ docker -H fd:// ps
error during connect: Get http:///v1.26/containers/json: http: no Host in request URL

那么fd://是什么意思呢?有什么用吗?

【问题讨论】:

    标签: sockets docker


    【解决方案1】:

    当您启动 Docker 守护程序时,-H fd:// 将告诉 Docker 该服务正在由 Systemd 启动,并将使用套接字激活。 systemd 然后将创建目标套接字并将其传递给 Docker 守护程序以使用。这在introduction to Systemdintroduction to socket activation 中有描述。博客很长,但确实值得一读,这里是理解这个问题的关键点的简短摘要:

    • Systemd 是一个新的init 系统,旨在取代传统的 SysV 初始化系统。它的主要功能之一是更快的初始化过程。

    • Socket activation是Systemd中用来加速服务初始化的技术之一

    • 要接收请求,服务需要一个套接字来监听。以 Docker 为例,它需要一个 unix domain socket/var/run/docker.sock 或一个 TCP 套接字。当然,这些套接字需要一些东西来创建它们,而且大多数时候它是服务本身在启动时。

    • 通过套接字激活,SystemD 将创建这些套接字并侦听它们以获取服务,并在服务启动时将这些套接字以exec 传递给服务。一个好处是,一旦成功创建套接字,甚至在相关服务启动之前,客户端请求就可以在套接字缓冲区中排队。

    • Systemd 使用的某个服务的套接字信息在 socket 单元文件中,对于 Docker 它是 [docker.socket][3] 内容:

        [Unit]
        Description=Docker Socket for the API
        PartOf=docker.service
      
        [Socket]
        ListenStream=/var/run/docker.sock
        SocketMode=0660
        SocketUser=root
        SocketGroup=docker
      
        [Install]
        WantedBy=sockets.target
      

    让我们看看整个事情是如何运作的。我在/etc/systemd/system 下有文件docker.socketdocker.servicedocker.serviceExecStart 行是:

    ExecStart=/usr/bin/dockerd -H fd://
    
    1. 停止 Docker 服务:systemctl stop docker

      $> ps aux | grep 'docker' # the `grep` itself in the output is ignored
      $> lsof -Ua | grep 'docker'
      $> 
      

      没有 docker 进程在运行,也没有docker.sock

    2. 执行systemctl start docker.socket:

      $> systemctl start docker.socket
      $> ps aux | grep 'docker' 
      $> lsof -Ua | grep 'docker'
      systemd       1    root   27u  unix 0xffff880036da6000      0t0 140748188 /var/run/docker.sock
      

      启动docker.socket之后,我们可以看到仍然没有docker进程在运行,但是socket/var/run/docker.sock已经创建好了,属于systemd的进程。

      (题外话:实际上套接字现在已经准备好接收请求了,即使docker 还没有运行。systemd 将在第一个请求到来的那一刻启动docker.service,将已经创建的套接字传递给 Docker。这就是所谓的按需自动生成)

    3. 开始docker.service

      $> systemctl start docker.service
      $> ps aux | grep 'docker'
      root     26302  0.0  1.8 431036 38712 ?        Ssl  14:57   0:00 /usr/bin/dockerd -H fd://
      <....>
      

      正如您所见,Docker 现在正在运行。让我们退后一步,尝试从终端手动执行/usr/bin/dockerd -H fd://

      $> /usr/bin/dockerd -H fd://
      FATA[0000] no sockets found via socket activation: make sure the service was started by systemd 
      

      现在你看到了区别;当您使用-H fd:// 时,docker 会期望套接字由其父进程传递,而不是自己创建。当它由 Systemd 启动时,Systemd 将完成这项工作,但是当您在终端上手动启动它时,您不会执行这项工作,因此 docker 守护进程失败并中止。这是code of how docker process fd:// when docker daemon starts,有兴趣的可以看看。

    另一方面,对于 docker 客户端,docker cli 将从-H 中指定的host 解析协议/地址,并向 docker 守护进程发出http 请求。默认主机为unix:///var/run/docker.sock。支持的协议包括tcpunixnpipefd。据我从源代码中探索,fd 的传输配置与tcp 相同,所以如果你有 tcp 套接字监听,你可以玩它:

    $> docker -H fd://localhost:4322 ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    

    等同于:

    docker -H tcp://localhost:4322 ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    

    【讨论】:

    • 很棒的描述@shizhz
    • 感谢@Alkaline 改进答案,英语不是我的主要语言:-
    • 很好的解释!这应该在 dockerd 手册页中,即使它是特定于 systemd 的。我唯一能找到的是docs.docker.com/engine/reference/commandline/dockerd/…
    • 感谢非常详细的回答。
    • @shizhz 仅供参考,“docker process fd:// ...的代码”的链接现在已损坏。
    【解决方案2】:

    在 systemd 中运行 docker 时使用 -H fd:// 语法。 Systemd 自己会在 docker.socket 单元文件中创建一个 socket 并监听它,这个 socket 会通过 docker.service 单元文件中的fd:// 语法连接到 docker daemon。

    【讨论】:

      猜你喜欢
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 2015-04-11
      • 2014-10-29
      • 2016-01-27
      • 2014-12-05
      • 1970-01-01
      相关资源
      最近更新 更多