?
本文檔使用 php中文網(wǎng)手冊(cè) 發(fā)布
本節(jié)中的信息解釋了Docker默認(rèn)網(wǎng)橋中的容器通信。這是一個(gè)在安裝Docker時(shí)自動(dòng)創(chuàng)建的bridge
網(wǎng)絡(luò)bridge
。
注意:通過(guò)Docker網(wǎng)絡(luò)功能,您可以創(chuàng)建除默認(rèn)網(wǎng)橋以外的用戶定義網(wǎng)絡(luò)。
一個(gè)容器是否可以與世界交流受兩個(gè)因素控制。第一個(gè)因素是主機(jī)是否轉(zhuǎn)發(fā)其IP數(shù)據(jù)包。其次是主機(jī)是否iptables
允許這種特定的連接。
IP數(shù)據(jù)包轉(zhuǎn)發(fā)由ip_forward
系統(tǒng)參數(shù)管理。如果此參數(shù)是數(shù)據(jù)包,則只能在容器之間傳遞數(shù)據(jù)包1
。通常你會(huì)簡(jiǎn)單地離開(kāi)了碼頭工人服務(wù)器的默認(rèn)設(shè)置--ip-forward=true
和碼頭工人會(huì)去設(shè)置ip_forward
,以1
在服務(wù)器啟動(dòng)時(shí)你。如果您設(shè)置--ip-forward=false
并且您的系統(tǒng)內(nèi)核已啟用該--ip-forward=false
選項(xiàng),則該選項(xiàng)不起作用。要檢查內(nèi)核上的設(shè)置或手動(dòng)打開(kāi)它:
$ sysctl net.ipv4.conf.all.forwarding net.ipv4.conf.all.forwarding = 0 $ sysctl net.ipv4.conf.all.forwarding=1 $ sysctl net.ipv4.conf.all.forwarding net.ipv4.conf.all.forwarding = 1
注意:此設(shè)置不會(huì)影響使用主機(jī)網(wǎng)絡(luò)堆棧(
--network=host
)的容器。
許多使用Docker的人都希望ip_forward
開(kāi)啟,至少可以在容器和更廣泛的世界之間進(jìn)行通信。如果您處于多個(gè)橋接設(shè)置中,也可能需要進(jìn)行集裝箱間通信。
如果您設(shè)置--iptables=false
守護(hù)進(jìn)程啟動(dòng)時(shí),Docker將永遠(yuǎn)不會(huì)更改您的系統(tǒng)規(guī)則iptables
。否則,Docker服務(wù)器會(huì)將轉(zhuǎn)發(fā)規(guī)則附加到DOCKER
過(guò)濾器鏈中。
Docker將刷新任何預(yù)先存在的規(guī)則,從DOCKER
和DOCKER-ISOLATION
過(guò)濾器鏈,如果存在的話。出于這個(gè)原因,需要在Docker啟動(dòng)后添加任何需要進(jìn)一步限制對(duì)容器訪問(wèn)的規(guī)則。
Docker的轉(zhuǎn)發(fā)規(guī)則默認(rèn)允許所有外部源IP。要僅允許特定的IP或網(wǎng)絡(luò)訪問(wèn)容器,請(qǐng)?jiān)?code>DOCKER過(guò)濾器鏈的頂部插入否定規(guī)則。例如,要限制外部訪問(wèn),以便只有源IP 8.8.8.8才能訪問(wèn)容器,可以添加以下規(guī)則:
$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
其中ext_if是提供到主機(jī)的外部連接的接口的名稱(chēng)。
兩個(gè)容器是否可以通信在操作系統(tǒng)級(jí)別由兩個(gè)因素決定。
網(wǎng)絡(luò)拓?fù)涫欠襁B接了容器的網(wǎng)絡(luò)接口?默認(rèn)情況下,Docker會(huì)將所有容器附加到一個(gè)docker0
橋,為數(shù)據(jù)包之間的傳輸提供路徑。有關(guān)其他可能的拓?fù)洌?qǐng)參閱本文檔的后面部分。
你的iptables
是否允許這個(gè)特定的連接?如果您設(shè)置--iptables=false
守護(hù)進(jìn)程啟動(dòng)時(shí),Docker將永遠(yuǎn)不會(huì)更改您的系統(tǒng)規(guī)則iptables
。否則,如果保留缺省值,則Docker服務(wù)器將FORWARD
使用一攬子ACCEPT
策略向該鏈添加默認(rèn)規(guī)則--icc=true
,否則會(huì)將該策略設(shè)置為DROP
如果--icc=false
。
這是一個(gè)戰(zhàn)略性問(wèn)題,是否要保留--icc=true
或改變,--icc=false
以便iptables
保護(hù)其他容器和主要主機(jī)不受任何受到攻擊的容器探測(cè)或訪問(wèn)的端口的限制。
如果您選擇最安全的設(shè)置--icc=false
,那么在您希望他們提供對(duì)方服務(wù)的情況下,容器如何通信?答案就是--link=CONTAINER_NAME_or_ID:ALIAS
選項(xiàng),因?yàn)樗鼘?duì)名稱(chēng)服務(wù)的影響,在前一節(jié)中提到了這個(gè)選項(xiàng)。如果Docker守護(hù)進(jìn)程正在運(yùn)行--icc=false
并且--iptables=true
隨后運(yùn)行,當(dāng)它看到docker run
使用該--link=
選項(xiàng)調(diào)用時(shí),Docker服務(wù)器將插入一對(duì)iptables
ACCEPT
規(guī)則,以便新容器可以連接到其他容器公開(kāi)的端口 - 它提到的端口它的EXPOSE
線Dockerfile
。
注:
CONTAINER_NAME
值的--link=
必須是自動(dòng)分配的Docker的名字一樣stupefied_pare
,或者你用指定的名稱(chēng)--name=
,當(dāng)你跑了docker run
。它不能是主機(jī)名,Docker在該--link=
選項(xiàng)的上下文中不會(huì)識(shí)別。
您可以在Docker主機(jī)上運(yùn)行Fiptables
命令,以查看該ORWARD
鏈?zhǔn)欠窬哂心J(rèn)策略為ACCEPT
或DROP
:
# When --icc=false, you should see a DROP rule:$ sudo iptables -L -n...Chain FORWARD (policy ACCEPT)target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0DROP all -- 0.0.0.0/0 0.0.0.0/0...# When a --link= has been created under --icc=false,# you should see port-specific ACCEPT rules overriding # the subsequent DROP policy for all other packets:$ sudo iptables -L -n...Chain FORWARD (policy ACCEPT)target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0DROP all -- 0.0.0.0/0 0.0.0.0/0Chain DOCKER (1 references)target prot opt source destination ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80
注意:Docker非常小心它的主機(jī)范圍
iptables
規(guī)則完全將容器暴露給彼此的原始IP地址,因此從一個(gè)容器到另一個(gè)容器的連接總是應(yīng)該來(lái)自第一個(gè)容器自己的IP地址。
出于安全原因,Docker配置iptables
規(guī)則以防止容器在Linux主機(jī)上從主機(jī)外部轉(zhuǎn)發(fā)流量。Docker將FORWARD
鏈的默認(rèn)策略設(shè)置為DROP
。
要覆蓋此默認(rèn)行為,您可以手動(dòng)更改默認(rèn)策略:
$ sudo iptables -P FORWARD ACCEPT
在iptables
當(dāng)系統(tǒng)重新啟動(dòng)設(shè)置都將丟失。如果您希望更改是永久的,請(qǐng)參閱您的Linux發(fā)行版的文檔。
注意:在Docker 1.12及更早版本中,默認(rèn)
FORWARD
鏈策略是ACCEPT
。當(dāng)您升級(jí)到Docker 1.13或更高版本時(shí),此默認(rèn)值會(huì)自動(dòng)為您更改。如果您以前的工作配置包含跨多個(gè)主機(jī)的多個(gè)容器,則此更改可能會(huì)導(dǎo)致現(xiàn)有設(shè)置停止工作,如果您不介入。
DROP
為ACCEPT
?假設(shè)你有兩臺(tái)主機(jī),每臺(tái)主機(jī)都有以下配置
host1: eth0/192.168.7.1, docker0/172.17.0.0/16host2: eth0/192.168.8.1, docker0/172.18.0.0/16
如果運(yùn)行在容器host1
需要與容器直接溝通的能力host2
,你需要從路線host1
到host2
。路由存在后,host2
需要能夠接受去往其運(yùn)行容器的數(shù)據(jù)包,并將其轉(zhuǎn)發(fā)。設(shè)置政策來(lái)ACCEPT
完成這一點(diǎn)。