docker容器网络配置之容器间的链接(默认桥接网络下的links)
一、 遺留的容器連接方式? --link
? --link是docker 的一個(gè)遺留的特征,最終可能被刪除。除非絕對(duì)需要使用,不然,建議使用 user-defined network 建立容器間的連接。不同的是,使用--link,容器間可共享變量,而使用 user-defined 網(wǎng)絡(luò)不行,但是也通過一種更可控方式實(shí)現(xiàn)容器間變量共享,例如數(shù)據(jù)卷。
? ? ?本文章主要默認(rèn)橋接網(wǎng)絡(luò)下 容器間采用遺留連接特征(--link)通訊細(xì)節(jié),并且討論容器間的安全交互問題。隨著docker 網(wǎng)絡(luò)特征(network features)的引入,仍然可以使用 創(chuàng)建連接方式促進(jìn)容器間交互,但是它與 默認(rèn)橋接網(wǎng)絡(luò)和自定義的橋接網(wǎng)絡(luò)又存在不同。
? ? ?本文章首先討論容器間端口連接問題,然后深入 討論容器在 默認(rèn)橋接網(wǎng)絡(luò)下的連接問題。
1.1 使用網(wǎng)絡(luò)端口映射方式連接
首先,運(yùn)行一個(gè)簡(jiǎn)單的python flask 程序
[root@localhost docker]# docker run -P -d training/webapp python app.py? ? ?容器創(chuàng)建后,由于采用 -P(大寫)參數(shù),docker自動(dòng)將容器內(nèi)部需要開放的端口自動(dòng)映射到主機(jī)上一個(gè)隨機(jī)較高的短暫端口范圍內(nèi)的端口。我們可使用docker ps? 或 docker container ls 查看
[root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a9e336610a0a training/webapp "python app.py" 7 seconds ago Up 6 seconds 0.0.0.0:32768->5000/tcp elated_hugle可發(fā)現(xiàn),將容器的5000 tcp端口映射到主機(jī)端口32768.
? ?也可以通過指定具體端口映射關(guān)系,例如將主機(jī)端口80映射到容器端口5000? 標(biāo)記? -p(小寫)
[root@localhost docker]# docker run -p 80:5000 -d training/webapp python app.py b9401a847804210e665e540ff8bc3e9b80863731eeb96f4aa5e0b82465834095 [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b9401a847804 training/webapp "python app.py" 4 seconds ago Up 2 seconds 0.0.0.0:80->5000/tcp affectionate_mahavira [root@localhost docker]#? ? 如此方式,智能一個(gè)容器的5000端口映射到主機(jī),但是如此存在多個(gè)容器間該端口需要通訊,則不適用。解決方式,采用主機(jī)的一個(gè)較高臨時(shí)端口范圍來綁定不同容器的臨時(shí)端口。
[root@localhost docker]# docker run -d -p 8000-9000:5000 --name node1 --hostname test1 training/webapp python app.py c92a9244159a569031882bc9429dbdad9b5993d99cac61128eb529103f1ff543 [root@localhost docker]# docker run -d -p 8000-9000:5000 --name node2 --hostname test2 training/webapp python app.py a7387aae557b039e26a13b7c0bad41b2f366283f778654efa60fdcc67697b672 [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a7387aae557b training/webapp "python app.py" 2 seconds ago Up 1 second 0.0.0.0:8001->5000/tcp node2 c92a9244159a training/webapp "python app.py" 13 seconds ago Up 12 seconds 0.0.0.0:8000->5000/tcp node1 [root@localhost docker]#? ?如此,每個(gè)容器的5000端口,將自動(dòng)映射到主機(jī)的端口范圍內(nèi)。
? ?默認(rèn)情況下,使用 -p標(biāo)記,是將指定端口綁定到主機(jī)所有接口(0.0.0.0)上,使用 -p另一種方式可把端口映射到本地 local host上,或者指定某個(gè)網(wǎng)卡上。
[root@localhost docker]# docker run -d -p 127.0.0.1:80:5000 training/webapp python app.py 37ebfc97fbf60d7cdc2b939e34fb555847395499fe00aa183a16810a118d450e [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 37ebfc97fbf6 training/webapp "python app.py" 10 seconds ago Up 8 seconds 127.0.0.1:80->5000/tcp brave_albattani如此方式將主機(jī) localhost 的端口80 綁定到容器端口 5000。但是和上述說的確定一樣,只能存在一個(gè)容器能夠綁定,可以使用動(dòng)態(tài)綁定方式
[root@localhost docker]# docker run -d -p 127.0.0.1::5000 training/webapp python app.py d654f947c0f7ab2bfb2a70e20e9266dc598276641cc544986b4e71c899bd8753 [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d654f947c0f7 training/webapp "python app.py" 5 seconds ago Up 3 seconds 127.0.0.1:32768->5000/tcp trusting_noether此時(shí),動(dòng)態(tài)端口為32768.再動(dòng)態(tài)啟動(dòng)一個(gè), 32769
[root@localhost docker]# docker run -d -p 127.0.0.1::5000 training/webapp python app.py c5e7b5dfc039652d3d5545c622b38bc01637a056d8bad4fbf47e3578c3a9d612 [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5e7b5dfc039 training/webapp "python app.py" 4 seconds ago Up 3 seconds 127.0.0.1:32769->5000/tcp sharp_easley d654f947c0f7 training/webapp "python app.py" About a minute ago Up About a minute 127.0.0.1:32768->5000/tcp trusting_noether? 默認(rèn)情緒下,綁定端口一般都為tcp協(xié)議,可在 -p的參數(shù)下帶 /udp /tcp /sctp等方式,指定協(xié)議類型
[root@localhost docker]# docker run -d -p 127.0.0.1:82:5000/udp training/webapp python app.py 1304cc996745431dea2460a1d9c87b4549c5f29521b8aec4d9a7e001a9d0e3eb [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1304cc996745 training/webapp "python app.py" 2 seconds ago Up 1 second 5000/tcp, 127.0.0.1:82->5000/udp clever_murdock同樣,可使用 docker port 指令,查看容器具體端口的映射情況 可通過容器ID 或者容器名
[root@localhost docker]# docker port node1 5000 0.0.0.0:8000? 注意:? -p 標(biāo)記可重復(fù)使用,用于指定不同端口映射關(guān)系。
1.2 連接容器到鏈接系統(tǒng)
? ? ? ?這一章節(jié),主要介紹,默認(rèn)橋接網(wǎng)絡(luò)模式下容器連接。網(wǎng)絡(luò)端口映射不是容器間通訊的唯一方式,docker 還擁有一個(gè)鏈接系統(tǒng),允許容器相互連接,并共享連接信息,當(dāng)一個(gè)容器被連接,則源容器的信息將可被發(fā)送給被連接的容器。因此,被連接的容器可查看源容器的被選定數(shù)據(jù)源的各方面信息,例如變量等。
?1.2.1 命名的重要性
為建立鏈接系統(tǒng),docker依賴容器的命名,容器在創(chuàng)建時(shí),如果未指定命名,則自動(dòng)給一個(gè)名字,使用 --name 標(biāo)記,在啟動(dòng)容器時(shí),可自定義指定容器名字。使用名字具有如下兩個(gè)好處:
? ? ?(1) 便于記憶,例如一個(gè)web程序的容器,可命名為 web
? ? ? ?(2)? ? 為docker 提供了一個(gè)方便的引用點(diǎn),例如將容器 web 連接到 容器db
? ? 例如啟動(dòng)一個(gè)名為web的容器,然后調(diào)用 docker ps , 或者docker container inspect web 查看容器具體信息
[root@localhost hadoop]# docker run -d -P --name web training/webapp python app.py 93e7d4982c5436783ad2f57270aeb73feaaa57e7273e932c5524542c0aeb967f [root@localhost hadoop]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 93e7d4982c54 training/webapp "python app.py" 6 seconds ago Up 5 seconds 0.0.0.0:32769->5000/tcp web注意 :容器名稱必須唯一,意味著一臺(tái)主機(jī)的daemon 下,只能存在一個(gè)名為web的容器,如果需要重新建立一個(gè)名為web的容器,需要先刪除舊的容器,這里有個(gè)建議,在啟動(dòng)容器時(shí) docker? create / run? 帶上標(biāo)記 --rm? ,? 一旦容器停止,則自動(dòng)刪除該容器。
1.2.2 容器間溝通? --link
? ? ? ? 鏈接 允許容器發(fā)現(xiàn)各自對(duì)方,同時(shí)構(gòu)建安全的信息交互鏈路,當(dāng)創(chuàng)建一個(gè)鏈接時(shí),則在源容器和接收容器間創(chuàng)建了一條溝通渠道,接收容器可瀏覽源容器的部分?jǐn)?shù)據(jù)信息。我們使用標(biāo)記 --link ,這次我們創(chuàng)建一個(gè)包含數(shù)據(jù)庫(kù)的容器,。
?
[root@localhost hadoop]# docker run -d --name db training/postgres 8ebe0029de23186cfd729b48c4e227be6392ad6d56f1cb53b96e9e789883ee7a [root@localhost hadoop]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8ebe0029de23 training/postgres "su postgres -c '/us…" 49 seconds ago Up 47 seconds 5432/tcp db 93e7d4982c54 training/webapp "python app.py" 13 minutes ago Up 13 minutes 0.0.0.0:32769->5000/tcp web我們?cè)谠侔阎暗娜萜鱳eb 刪除, 然會(huì)在新建一個(gè)容器 連接db
[root@localhost hadoop]# docker container rm -f web web [root@localhost hadoop]# docker run -d -P --link db:db --name web training/webapp python app.py ae71a962f945a14a1f879258e326318d374d91fe99628120d3f69d369f4ba4d5 [root@localhost hadoop]#? ? 使用 --link 標(biāo)記的個(gè)數(shù)? ?--link? <name or id>:alias? ? ?冒號(hào)左邊為容器的名稱或者ID? 右邊為? 源容器的別名。
? ?然后我們可調(diào)用 docker inspect -f? 格式查看web 容器的鏈接信息
[root@localhost hadoop]# docker inspect -f {{.HostConfig.Links}} web [/db:/web/db] [root@localhost hadoop]#可發(fā)現(xiàn),web容器已經(jīng)鏈接到 db容器,/web/db, 允許web容器訪問db容器的部分信息,進(jìn)入容器 web? 打開 /etc/hosts 就可以看到db容器的信息,同時(shí)可直接ping db
[root@localhost hadoop]# docker exec -ti web /bin/bash root@ae71a962f945:/opt/webapp# pwd /opt/webapp root@ae71a962f945:/opt/webapp# 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 192.168.0.3 db 8ebe0029de23 192.168.0.2 ae71a962f945 root@ae71a962f945:/opt/webapp# ping db PING db (192.168.0.3) 56(84) bytes of data. 64 bytes from db (192.168.0.3): icmp_seq=1 ttl=64 time=0.130 ms 64 bytes from db (192.168.0.3): icmp_seq=2 ttl=64 time=0.038 ms? ? ? ? ?那么當(dāng)我們使用 --link 建立容器間的鏈接時(shí),實(shí)際進(jìn)行什么操作? 我們知道,一個(gè)鏈接運(yùn)行 源容器將自身部分信息傳遞給接收容器,這里接收容器是 web, 源容器是db, web可方式db的某些信息, 實(shí)際上,docker 在web容器和db容器新建一個(gè)安全通道,該通道并不需要容器對(duì)外開放任何端口。而且也不用在啟動(dòng)容器時(shí),采用參數(shù) -p? 或者 -P指定容器開發(fā)端口,這就是 link的最大好處之一,不需要向容器公開通道,這里就是?PostgreSQL數(shù)據(jù)庫(kù)不需要向 web公開端口。
? ? ? docker傳遞源容器的信息給接收容器,一般采用如下兩種方式:
? ? ? ? ? ? ?(1)? ? 環(huán)境變量
? ? ? ? ? (2) 更新/etc/hosts? 文件? 。? 前面通過查看該文件可觀察到? 添加了db容器的IP地址和容器ID
1.3 環(huán)境變量
? ? ? ? 在創(chuàng)建容器間的鏈接時(shí),docker會(huì)創(chuàng)建根據(jù) --link 的參數(shù),創(chuàng)建一些環(huán)境變量,同時(shí)docker可能暴露源 容器的環(huán)境變量,那些可能被暴露源容器的環(huán)境變量來自于如下:
? ? ?(1)源容器的Dockerfile 中使用ENV 指定的環(huán)境變量
? ? ?(2)源容器在啟動(dòng)時(shí),-e? 或? --env 或者? --env-file? 指定的環(huán)境變量
? ? ? ? 那些帶有源容器信息的環(huán)境變量,被允許在接收容器程序化發(fā)現(xiàn)(特定規(guī)則,下文講到)。因此,注意,環(huán)境變量中避免存儲(chǔ)一些敏感信息,避免被那些連接容器發(fā)現(xiàn)。
? ? ? ?docker在創(chuàng)建鏈接時(shí),根據(jù)--link參數(shù)?為接收端容器生成一個(gè) <alias>_NAME 的環(huán)境變量,這里指web容器,我們可進(jìn)入容器內(nèi)部查詢。
[root@localhost hadoop]# docker exec -ti web /bin/bash root@0af1176d2df9:/opt/webapp# echo $BACKDB_NAME /web/backdb root@0af1176d2df9:/opt/webapp#? ?我們使用 --link? ?db:backdb 將web容器鏈接到db容器,則在web容器新建一個(gè)環(huán)境變量 BACKDB_NAME=/web/backdb
? ?同樣 docker 還為源容器的公開的端口新建了一些列的環(huán)境變量。以如下的規(guī)則;
? ? <name>_PORT_<port>_<protocol>
? 每個(gè)段部分的命名與介紹:
? ? <name>? ?即為? --link 指定的別名,? 例如? ? ?這里的backdb
? ? <port>? ?開放的端口
? ? <protocol>? TCP? 或者UDP
?docker 使用這些前綴定義,定義了三個(gè)不同的環(huán)境變量:
? ?固定前綴 ADDR 返回源容器地址信息? 例如? ?BACKDB_PORT_5432_TCP_ADDR =192.168.0.2
? ?固定前綴PORT返回源容器的開放端口信息 例如:?BACKDB_PORT_5432_TCP_PORT = 5432
? ?固定前綴PROTO 返回源容器開放端口通訊協(xié)議: 例如:?BACKDB_PORT_5432_TCP_PROTO=tcp
當(dāng)有多個(gè)開放端口時(shí),針對(duì)每個(gè)端口定義該三個(gè)變量,如果有4個(gè)開放端口,則存在12個(gè)如此規(guī)則的環(huán)境變量。
[root@localhost hadoop]# docker exec -ti web /bin/bash root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT_5432_TCP_ADDR 192.168.0.2 root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT_5432_TCP_PORT 5432 root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT_5432_TCP_PROTO tcp root@0af1176d2df9:/opt/webapp#另外,docker 還創(chuàng)建一個(gè)環(huán)境變量 <alias>_PORT 返回第一個(gè)開放端口的具體信息 (包含了ip、port 、protocol)
root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT tcp://192.168.0.2:5432 root@0af1176d2df9:/opt/webapp#? ? ? ?最后,針對(duì)源容器的環(huán)境變量,在接收容器,將每個(gè)變量采用<alias>_ENV_<name>方式保存,并在接收容器啟動(dòng)時(shí)創(chuàng)建該些變量,例如前面,如果我們啟動(dòng)db容器時(shí) 帶入?yún)?shù) -e DBNAME="testName".? ?則我們?cè)诮邮杖萜鱳eb內(nèi)可查看該變量,注意alias別名前綴使用大寫。
root@0af1176d2df9:/opt/webapp# echo $BACKDB_ENV_DBNAME testName?注意:與/etc/hosts文件中的主機(jī)條目不同,如果源容器重新啟動(dòng),存儲(chǔ)在環(huán)境變量中的IP地址不會(huì)自動(dòng)更新。因此,一般使用/etc/hosts 解析源容器的IP地址信息。
? ? ? ?那些變量,僅為容器第一個(gè)進(jìn)程設(shè)置,當(dāng)一些守護(hù)經(jīng)常構(gòu)建時(shí),例如sshd, 那些變量將被清除。
1.4 更新 /etc/hosts文件
? ? ?容器間創(chuàng)建鏈接后,docker自動(dòng)更新接收容器的/etc/hosts文件,添加源容器的ip地址等相關(guān)信息到條目中,源容器的/etc/hosts未保存接收容器的信息。
root@0af1176d2df9:/opt/webapp# 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 192.168.0.2 backdb 92aca4dce8fc db 192.168.0.3 0af1176d2df9 root@0af1176d2df9:/opt/webapp# exit [root@localhost hadoop]# [root@localhost hadoop]# docker exec -ti db /bin/bash root@92aca4dce8fc:/# 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 192.168.0.2 92aca4dce8fc root@92aca4dce8fc:/#如web容器內(nèi)保存 db容器的 名稱,ID和別名,web容器分別利用名稱? ID和別名 均可訪問到db容器
root@0af1176d2df9:/opt/webapp# 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 192.168.0.2 backdb 92aca4dce8fc db 192.168.0.3 0af1176d2df9 root@0af1176d2df9:/opt/webapp# ping db PING backdb (192.168.0.2) 56(84) bytes of data. 64 bytes from backdb (192.168.0.2): icmp_seq=1 ttl=64 time=0.145 ms 64 bytes from backdb (192.168.0.2): icmp_seq=2 ttl=64 time=0.038 ms 64 bytes from backdb (192.168.0.2): icmp_seq=3 ttl=64 time=0.044 ms ^C --- backdb ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.038/0.075/0.145/0.050 ms root@0af1176d2df9:/opt/webapp# ping backdb PING backdb (192.168.0.2) 56(84) bytes of data. 64 bytes from backdb (192.168.0.2): icmp_seq=1 ttl=64 time=0.112 ms 64 bytes from backdb (192.168.0.2): icmp_seq=2 ttl=64 time=0.037 ms ^C --- backdb ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.037/0.074/0.112/0.038 ms root@0af1176d2df9:/opt/webapp# ping 92aca4dce8fc PING backdb (192.168.0.2) 56(84) bytes of data. 64 bytes from backdb (192.168.0.2): icmp_seq=1 ttl=64 time=0.053 ms 64 bytes from backdb (192.168.0.2): icmp_seq=2 ttl=64 time=0.045 ms ^C --- backdb ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.045/0.049/0.053/0.004 ms root@0af1176d2df9:/opt/webapp# ping 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.098 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.041 ms ^C --- 192.168.0.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.041/0.069/0.098/0.029 ms root@0af1176d2df9:/opt/webapp#一個(gè)容器可允許被多個(gè)容器同時(shí)連接,但是注意不能啟動(dòng)相同容器名
?
總結(jié)
以上是生活随笔為你收集整理的docker容器网络配置之容器间的链接(默认桥接网络下的links)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是DDOS攻击?怎么抵抗DDOS攻击
- 下一篇: android 修改充电图标,更换图标、