關(guān)于對docker run --link的理解

前言

在實踐中,自己會遇到2個容器之間互相訪問通信的問題,這個時候就用到了docker run --link選項。自己也花了一段時間泡官網(wǎng)研究了--link的用法,把自己對--link的理解分享下。注意!docker官方已不推薦使用docker run --link來鏈接2個容器互相通信,隨后的版本中會刪除--link,但了解其原理,對如何使2個容器之間互相通信還是有幫助的。

1. docker run --link的作用

docker run --link可以用來鏈接2個容器,使得源容器(被鏈接的容器)和接收容器(主動去鏈接的容器)之間可以互相通信,并且接收容器可以獲取源容器的一些數(shù)據(jù),如源容器的環(huán)境變量。

--link的格式:

--link <name or id>:alias

其中,name和id是源容器的name和id,alias是源容器在link下的別名。

eg:

源容器

docker run -d --name selenium_hub selenium/hub

創(chuàng)建并啟動名為selenium_hub的容器。

selenium_hub容器

接收容器

docker run -d --name node --link selenium_hub:hub selenium/node-chrome-debug

創(chuàng)建并啟動名為node的容器,并把該容器和名為selenium_hub的容器鏈接起來。其中:

--link selenium_hub:hub

selenium_hub是上面啟動的1cbbf6f07804容器的名字,這里作為源容器,hub是該容器在link下的別名(alias),通俗易懂的講,站在node容器的角度,selenium_hub和hub都是1cbbf6f07804容器的名字,并且作為容器的hostname,node用這2個名字中的哪一個都可以訪問到1cbbf6f07804容器并與之通信(docker通過DNS自動解析)。我們可以來看下:

進(jìn)入node容器:

docker exec -it node /bin/bash

root@c4cc05d832e0:~# ping selenium_hub
PING hub (172.17.0.2) 56(84) bytes of data.
64 bytes from hub (172.17.0.2): icmp_seq=1 ttl=64 time=0.184 ms
64 bytes from hub (172.17.0.2): icmp_seq=2 ttl=64 time=0.133 ms
64 bytes from hub (172.17.0.2): icmp_seq=3 ttl=64 time=0.216 ms

root@c4cc05d832e0:~# ping hub
PING hub (172.17.0.2) 56(84) bytes of data.
64 bytes from hub (172.17.0.2): icmp_seq=1 ttl=64 time=0.194 ms
64 bytes from hub (172.17.0.2): icmp_seq=2 ttl=64 time=0.218 ms
64 bytes from hub (172.17.0.2): icmp_seq=3 ttl=64 time=0.128 ms

可見,selenium_hub和hub都指向172.17.0.2。

2. --link下容器間的通信

按照上例的方法就可以成功的將selenium_hub和node容器鏈接起來,那這2個容器間是怎么通信傳送數(shù)據(jù)的呢?另外,前言中提到的接收容器可以獲取源容器的一些信息,比如環(huán)境變量,又是怎么一回事呢?

源容器和接收容器之間傳遞數(shù)據(jù)是通過以下2種方式:

  • 設(shè)置環(huán)境變量
  • 更新/etc/hosts文件
2.1 設(shè)置環(huán)境變量
  1. 當(dāng)使用--link時,docker會自動在接收容器內(nèi)創(chuàng)建基于--link參數(shù)的環(huán)境變量:

docker會在接收容器中設(shè)置名為<alias>_NAME的環(huán)境變量,該環(huán)境變量的值為:
<alias>_NAME=/接收容器名/源容器alias

我們進(jìn)入node容器,看下此環(huán)境變量:

docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ env | grep -i hub_name
HUB_NAME=/node/hub

可見,確實有名為HUB_NAME=/node/hub的環(huán)境變量存在。

另外,docker還會在接收容器中創(chuàng)建關(guān)于源容器暴露的端口號的環(huán)境變量,這些環(huán)境變量有一個統(tǒng)一的前綴名稱:

<name>PORT<port>_<protocol>

其中:

<name>表示鏈接的源容器alias
<port>是源容器暴露的端口號
<protocol>是通信協(xié)議:TCP or UDP

docker用上面定義的前綴定義3個環(huán)境變量:

<name>PORT<port>_<protocol>ADDR
<name>PORT<port>
<protocol>PORT
<name>PORT<port>
<protocol>_PROTO

注意,若源容器暴露了多個端口號,則每1個端口都有上面的一組環(huán)境變量(包含3個環(huán)境變量),即若源容器暴露了4個端口號,則會有4組12個環(huán)境變量。

查看selenium/hub的Dockerfile,可見只暴露了4444端口號:

EXPOSE 4444

我們進(jìn)入node容器,看這些此環(huán)境變量:

docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ env | grep -i HUB_PORT_4444_TCP_
HUB_PORT_4444_TCP_PROTO=tcp
HUB_PORT_4444_TCP_ADDR=172.17.0.2
HUB_PORT_4444_TCP_PORT=4444

可見,確實有3個以<name>PORT<port><protocol>為前綴的環(huán)境變量存在。

另外,docker還在接收容器中創(chuàng)建1個名為<alias>_PORT的環(huán)境變量,值為源容器的URL:源容器暴露的端口號中最小的那個端口號

我們進(jìn)入node容器,看下此環(huán)境變量:

docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ env | grep -i HUB_PORT=
HUB_PORT=tcp://172.17.0.2:4444

可見,此環(huán)境變量的確存在。

  1. 接收容器還會獲取源容器暴露的環(huán)境變量,這些變量包括:
  • 源容器Dockerfile中ENV標(biāo)簽設(shè)置的環(huán)境變量
  • 源容器用docker run命令創(chuàng)建,命令中包含的 -e或--env或--env-file設(shè)置的環(huán)境變量

docker會在接收容器中創(chuàng)建一些環(huán)境變量,這些環(huán)境變量是的值是關(guān)于源容器本身的環(huán)境變量的值。這些環(huán)境變量的定義格式為:

<alias>ENV<name>

查看selenium/hub的Dockerfile,可見Dockerfile中ENV標(biāo)簽設(shè)置的環(huán)境變量有:

# As integer, maps to "maxSession"
ENV GRID_MAX_SESSION 5
# In milliseconds, maps to "newSessionWaitTimeout"
ENV GRID_NEW_SESSION_WAIT_TIMEOUT -1
# As a boolean, maps to "throwOnCapabilityNotPresent"
ENV GRID_THROW_ON_CAPABILITY_NOT_PRESENT true
# As an integer
ENV GRID_JETTY_MAX_THREADS -1
# In milliseconds, maps to "cleanUpCycle"
ENV GRID_CLEAN_UP_CYCLE 5000
# In seconds, maps to "browserTimeout"
ENV GRID_BROWSER_TIMEOUT 0
# In seconds, maps to "timeout"
ENV GRID_TIMEOUT 30
# Debug
ENV GRID_DEBUG false

我們進(jìn)入selenium_hub容器,看下這些環(huán)境變量:

root@ubuntu:~# docker exec -it selenium_hub /bin/bash
seluser@1cbbf6f07804:/$ env | grep -i grid_
GRID_DEBUG=false
GRID_TIMEOUT=30
GRID_CLEAN_UP_CYCLE=5000
GRID_MAX_SESSION=5
GRID_JETTY_MAX_THREADS=-1
GRID_BROWSER_TIMEOUT=0
GRID_THROW_ON_CAPABILITY_NOT_PRESENT=true
GRID_NEW_SESSION_WAIT_TIMEOUT=-1

我們再進(jìn)入node容器,看下node容器中關(guān)于selenium_hub的<alias>ENV<name>環(huán)境變量:

docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ env | grep -i hub_env
HUB_ENV_GRID_DEBUG=false
HUB_ENV_GRID_TIMEOUT=30
HUB_ENV_DEBCONF_NONINTERACTIVE_SEEN=true
HUB_ENV_GRID_CLEAN_UP_CYCLE=5000
HUB_ENV_GRID_MAX_SESSION=5
HUB_ENV_TZ=UTC
HUB_ENV_GRID_JETTY_MAX_THREADS=-1
HUB_ENV_DEBIAN_FRONTEND=noninteractive
HUB_ENV_GRID_BROWSER_TIMEOUT=0
HUB_ENV_GRID_THROW_ON_CAPABILITY_NOT_PRESENT=true
HUB_ENV_GRID_NEW_SESSION_WAIT_TIMEOUT=-1

可見,selenium_hub容器中的GRID_* 環(huán)境變量均在node容器中被創(chuàng)建,只不過名稱變?yōu)镠UB_ENV_GRID_* 而已。

環(huán)境變量的注意事項
注意,接收容器環(huán)境變量中存儲的源容器的IP,不會自動更新,即,若源容器重啟,則接收容器環(huán)境變量中存儲的源容器的IP很可能就失效了。所以,docker官方建議使用/etc/hosts來解決上述的IP失效問題。

2.2 更新/etc/hosts文件

docker會將源容器的host更新到目標(biāo)容器的/etc/hosts中:
我們再進(jìn)入node容器,查看node容器中的/etc/hosts文件的內(nèi)容:

docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  hub 1cbbf6f07804 selenium_hub
172.17.0.3  c4cc05d832e0

其中172.17.0.3是node容器的ip,并使用node容器的容器id作為host name。另外,源容器的ip和hostname也寫進(jìn)來了,172.17.0.2是selenium_hub容器的ip,hub是容器在link下的alias,后面是hub容器的容器id。

如果重啟了源容器,接收容器的/etc/hosts會自動更新源容器的新ip。

總結(jié)

在--link標(biāo)簽下,接收容器就是通過設(shè)置環(huán)境變量和更新/etc/hosts文件來獲取源容器的信息,并與之建立通信和傳遞數(shù)據(jù)的。

在docker的后續(xù)版本中,會取消docker run中的--link選項,但了解其如何在2個容器之間建立通信的原理是非常有用的,因為這有助于理解如何用官方推薦的所有容器在同一個network下來通信的方法,以及用docker-compose來鏈接2個容器來通信的方法。

9月初就用--link方法連接了seleniumhub和seleniumnode容器,但是不明白--link的作用,最近花了幾天時間讀官方文檔,終于算搞清楚了,也把自己的理解在這里分享下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內(nèi)容