2017-04-09 552 views
8

Docker daemon documentation提出了大部份的设定如下hosts选项:什么呢FD://意味着什么在dockerd -H FD://

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 -H tcp://0.0.0.0:2375 ps 

但是,如果我使用-H fd://开始泊坞窗守护进程,下面的调用给出了错误:

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

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

回答

1

在systemd中运行docker时使用-H fd://语法。 Systemd本身将在docker.socket单元文件中创建一个套接字并侦听它,并且该套接字通过docker.service单元文件中的fd://语法连接到docker守护进程。

12

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

  • Systemd是为了取代传统的SysV初始化系统的新init系统。其主要特点之一是更快的初始化过程。
  • Socket activation是Systemd加速服务初始化中使用的技术之一
  • 要接收请求,服务需要一个套接字来侦听。以Docker为例,它需要unix domain socket,如/var/run/docker.sock或TCP套接字。当然,这些套接字需要一些东西来创建它们,大多数情况下它是服务本身的开始时间。
  • 通过套接字激活,SystemD将创建这些套接字并监听它们的服务,并在服务启动时将这些套接字传递给exec服务。一个好处是,即使在相关服务启动之前,一旦套接字成功创建,客户端请求就可以在套接字缓冲区中排队。
  • 由Systemd使用某个服务的插座信息是socket单位文件,多克尔它[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 
    

让我们看到了整个事情是如何工作的。我有文件docker.socketdocker.service根据/etc/systemd/system。该ExecStart线docker.service是:

ExecStart=/usr/bin/dockerd -H fd:// 
  1. 停止码头工人服务:systemctl stop docker

    $> ps aux | grep 'docker' # the `grep` itself in the output is ignored 
    $> lsof -Ua | grep '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进程,但是已经创建了套接字/var/run/docker.sock,它属于进程systemd。 (即使docker还没有运行,systemd将在第一个请求到来的时刻开始docker.service,将已经创建的套接字传递给Docker),这是如此-called点播自动产卵)

  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:// 
    <....> 
    

    正如你可以告诉码头工人正在运行。让我们退一步,并尝试从终端手动执行/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,如果你有兴趣,你可以看看。

在另一方面为搬运工客户端,搬运工CLI将从-H指定host解析协议/ addr和作出http请求搬运工守护进程。默认主机是unix:///var/run/docker.sock。支持的协议包括tcp,unix,npipefd。据我从源代码探索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 
+0

很好的描述@shizhz – Alkaline

+0

谢谢@Alkaline改善答案,英语不是我的主要语言: - – shizhz