關(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自動解析)任斋。我們可以來看下:

進入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. 當使用--link時趴俘,docker會自動在接收容器內(nèi)創(chuàng)建基于--link參數(shù)的環(huán)境變量:

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

我們進入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

我們進入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:源容器暴露的端口號中最小的那個端口號监嗜。

我們進入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標簽設(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標簽設(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

我們進入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

我們再進入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更新到目標容器的/etc/hosts中:
我們再進入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也寫進來了汽抚,172.17.0.2是selenium_hub容器的ip,hub是容器在link下的alias伯病,后面是hub容器的容器id造烁。

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

總結(jié)

在--link標簽下惭蟋,接收容器就是通過設(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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市桥胞,隨后出現(xiàn)的幾起案子恳守,更是在濱河造成了極大的恐慌,老刑警劉巖贩虾,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件催烘,死亡現(xiàn)場離奇詭異,居然都是意外死亡缎罢,警方通過查閱死者的電腦和手機伊群,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來策精,“玉大人舰始,你說我怎么就攤上這事⊙释啵” “怎么了丸卷?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長询刹。 經(jīng)常有香客問我谜嫉,道長萎坷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任沐兰,我火速辦了婚禮哆档,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘住闯。我一直安慰自己瓜浸,他們只是感情好,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布比原。 她就那樣靜靜地躺著斟叼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪春寿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天忽孽,我揣著相機與錄音绑改,去河邊找鬼。 笑死兄一,一個胖子當著我的面吹牛厘线,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播出革,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼造壮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了骂束?” 一聲冷哼從身側(cè)響起耳璧,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎展箱,沒想到半個月后旨枯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡混驰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年攀隔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栖榨。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡昆汹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出婴栽,到底是詐尸還是另有隱情满粗,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布居夹,位于F島的核電站败潦,受9級特大地震影響本冲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜劫扒,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一檬洞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沟饥,春花似錦添怔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至幼驶,卻和暖如春艾杏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盅藻。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工购桑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氏淑。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓勃蜘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親假残。 傳聞我的和親對象是個殘疾皇子缭贡,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

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