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