2017-04-09 56 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。該ExecStartdocker.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