Docker网络配置进阶
Docker啟動會默認創建docker0虛擬網橋,是Linux的一個bridge,可以理解成一個軟件交換機。它會在掛載到它的網口之間進行轉發。
?
之后所有容器都是在172.17.0.x的網段上,并且可以相互通訊,包括和宿主主機通訊。
當創建一個Docker容器的時候,同時會創建一對veth?pair(虛擬設備接口)
(https://www.cnblogs.com/bakari/p/10613710.html)
接口(當數據包發送到一個接口時,另外一個接口也可以收到相同的數據包)。這對接口一端在容器內,即eth0;另一端在本地并被掛載到docker0?網橋,名稱以veth開頭。通過這種方式,主機可以跟容器通信,容器之間也可以相互通信。Docker就創建了在主機和所有容器之間一個虛擬共享網絡。
大概就是書上的這個圖:
?
一些docker網絡相關的命令列表
-b?BRIDGE??或??--bridge=BRIDGE??指定容器掛載的網橋
--bip=CIDR??定制?docker0?的掩碼
-H?SOCKET...??或??--host=SOCKET...??Docker?服務端接收命令的通道
--icc=true|false??是否支持容器之間進行通信
--iptables=true|false??是否允許?Docker?添加?iptables?規則
--mtu=BYTES??容器網絡中的?MTU(最大傳輸單元)
下面2個命令選項既可以在啟動服務時指定,也可以在啟動容器時指定。在?Docker服務啟動的時候指定則會成為默認值,后面執行??docker?run??時可以覆蓋設置的默認值
--dns=IP_ADDRESS...??使用指定的DNS服務器
--dns-search=DOMAIN...??指定DNS搜索域
?
最后這些選項只有在??docker?run??執行時使用,因為它是針對容器的特性內容。
-h?HOSTNAME??或??--hostname=HOSTNAME??配置容器主機名
--link=CONTAINER_NAME:ALIAS??添加到另一個容器的連接
--net=bridge|none|container:NAME_or_ID|host??配置容器的橋接模式
-p?SPEC??或??--publish=SPEC??映射容器端口到宿主主機
-P?or?--publish-all=true|false??映射容器所有端口到宿主主機
?
容器訪問控制
容器訪問控制,主要通過Linux上的iptables防火墻來進行管理和實現。
容器想要訪問外部網絡,需要本地系統的轉發支持。在Linux系統中,檢查轉發是否打開。
sysctl?net.ipv4.ip_forward
結果net.ipv4.ip_forward?=?1中1是打開,如果是0就是沒打開,沒打開則用
sysctl?-w?net.ipv4.ip_forward=1命令設置成打開。
如果在啟動?Docker?服務的時候設定??--ip-forward=true??,?Docker?就會自動設定系統的??ip_forward??參數為?1
?
容器之間的訪問
????容器之間的訪問,需要兩方面的支持。
????1.容器的網絡拓撲是否已經互聯。默認情況下,所有容器都會被連接到docker0網橋上。
????2.本地系統的防火墻軟件--iptables是否允許通過。
?
訪問所有端口
當啟動Docker服務(dockerd)的時候,默認會添加一條轉發策略到本地主機iptables的FORWARD鏈上。策略為通過(ACCEPT)還是禁止(DROP)取決于配置?--icc=true(缺省值)還是--icc=false。如果手動指定--iptables=false則不會添加iptables規則。
所以說在默認情況下,不同容器之間是允許網絡互通的。如果為了安全考慮,可以在
/etc/docker/daemon.json文件中配置{"icc":?false}來禁止。
訪問指定端口
在通過--icc關閉網絡訪問后,可以通過link選項來訪問容器的開放端口。
link=CONTAINER_NAME:ALIAS
例:
????在啟動?Docker?服務時,可以同時使用?icc=false?--iptables=true??參數來關閉允許相互的網絡訪問,并讓?Docker?可以修改系統中的??iptables??規則。
PS:????--link=CONTAINER_NAME:ALIAS??中的??CONTAINER_NAME??目前必須是Docker?分配的名字,或使用??--name??參數指定的名字。主機名則不會被識別。
?
映射容器端口到宿主主機的實現
????默認情況容器可以主動訪問到外部網絡,但是外部網絡無法訪問到容器。
容器訪問外部實現
容器所有到外部網絡的鏈接,源地址都會被NAT成本地系統的IP地址。這是使用iptables的源地址偽裝操作實現的。
查看主機NAT規則sudo?iptables?-t?nat?-nL
上面是所有源地址在172.17.0.0/16網段,目標地址是所有0.0.0.0/0,的流量動態偽裝成從系統網卡發出。MASQUERADE?跟傳統?SNAT的好處是它能動態從網卡獲取地址。
?
外部訪問容器實現
容器允許外部訪問,可以在docker?run?時候通過?-p?或?-P?參數來啟用。原理是在本地iptable的net表中添加相應的規則。
比如-p?80:80可能會這樣
上面是所有地址的80都指向了容器里面的80,如果想鎖定地址可以
-p?IP:host_port:container_port??或??-p?IP::port
也可以直接配置/etc/docker/daemon.json?中?{"ip":?"0.0.0.0"}
配置docker0網橋
Docker服務默認創建docker0?網橋,默認指定了docker0接口的IP地址和子網掩碼,讓主機和容器之間可以通過網橋相互通信,還給出了MTU(接口允許接收的做大傳輸單元),或宿主主機網絡路由上支持的默認值。
--bip=CIDR??IP?地址加掩碼格式,例如?192.168.1.5/24
--mtu=BYTES??覆蓋默認的?Docker?mtu?配置
也可以在配置文件中配置?DOCKER_OPTS,然后重啟服務。
可以通過brctl?show來查看網橋和端口連接信息。
?
每次創建一個新容器的時候,Docker從可用的地址段中選擇一個空閑的IP地址分配給容器的eth0端口。使用本地主機上docker0接口的IP作為所有容器的默認網關。
?
自定義網橋
除了默認的docker0網橋,用戶也可以指定網橋來鏈接各個容器。
啟動docker服務的時候使用??-b?BRIDGE??或?--bridge=BRIDGE??來指定使用的網橋。如果服務已經運行,就停掉服務,刪除就網橋。
sudo?systemctl?stop?docker
sudo?ip?link?set?dev?docker0?down
sudo?brctl?delbr?docker0
然后創建網橋
sudo?brctl?addbr?bridge0
sudo?ip?addr?add?192.168.5.1/24?dev?bridge0
sudo?ip?link?set?dev?bridge0?up
查看確認網橋創建并啟動
ip?addr?show?bridge0
在?Docker?配置文件??/etc/docker/daemon.json??中添加如下內容,即可將Docker?默認橋接到創建的網橋上{"bridge":?"bridge0",}
啟動?Docker?服務systemctl?start?docker
新建一個服務
docker?run?-d?-P?training/webapp?python?app.py
創建一個點到點的連接
默認情況下Docker會將所有容器鏈接到由docker0提供的虛擬子網中。但是有的時候可能需要兩個容器直接通訊,而不是通過主機網橋進行橋接。方法是創建一對peer接口,分別放在兩個容器中,配置成點到點鏈路類型。
?
總結
以上是生活随笔為你收集整理的Docker网络配置进阶的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker网络相关
- 下一篇: Docker Machine-Windo