Docker容許經過外部訪問容器或容器互聯的方式來提供網絡服務。docker
當Docker啓動時,會在主機上建立一個 docker0虛擬網橋,其實是Linux的一個bridge,能夠理解爲一個軟件交換機。它會在掛載到它的網口之間進行轉發。安全
同時,Docker隨機分配一個本地未佔用的私有網段中的一個地址給docker0接口。好比典型的172.17.42.1,掩碼爲255.255.0.0 。此後啓動的容器內網口也會自動分配一個統一網段的地址(172.17.0.0/16)的地址。當建立一個Docker容器的時候,同時會建立一對 veth pair接口(當數據包發送到一個接口時,另一個接口也能夠收到相同的數據包)。這對接口一端在容器內,即eth0,另一端在本地並被掛載到docker0網橋,名稱以veth開頭。經過這種方式,主機能夠跟容器通訊,容器之間也能夠相互通訊。docker就建立了在主機和全部容器之間的一個虛擬網絡。網絡
容器之間訪問tcp
容器之間相互訪問,須要兩方面的支持:工具
1.容器的網絡拓撲圖是否互聯。默認狀況下,全部容器都會被鏈接到docker0網橋上。接口
2.本地系統的防火牆軟件-- iptables是否容許經過。ip
訪問全部端口:get
當容器啓動的時候,默認會添加一條轉發策略到iptables的forward鏈上。策略爲經過(accept)仍是禁止(drop)取決於配置--icc=true(缺省值)仍是 -icc=false。io
可見默認狀況下,不一樣容器之間是容許網絡互通的。若是爲了安全考慮,能夠在/etc/default/docker 文件配置中 docker opts=--icc=false來禁止。table
訪問指定端口
在經過-icc=false關閉網絡訪問後,還能夠經過--link=container_name:alias 選項來訪問容器的開放端口。
docker提供了 --link:容器名:別名來指定要和哪一個容器通訊。docker會在iptable中爲兩個容器分別添加一條accept,容許訪問開放的端口(取決於Docfile中的expose指令)。
映射容器端口到宿主機的實現
容器訪問外部網絡
容器要想訪問外部網絡,須要本地系統的轉發支持。容器全部到外部網絡的鏈接,源地址都會被NAT成本地網絡的IP地址。這是使用 iptables的源地址假裝操做來實現的。查看主機的NAT規則: sudo iptables -t nat -nL。能夠看到,規則將全部源的地址在172.17.0.0/16網段,目標地址爲其餘網段(外部網絡)的流量動態假裝爲從系統網卡發出。MASQUERAD跟傳統的SNAT的好處是它能動態從網卡獲取地址。
在Linux系統中,檢查轉發是否打開。
執行: sysctl net.ipv4.ip_forward
輸出: net.ipv4.ip_forward = 1 ,若是爲0,說明沒有開啓轉發,須要手動打開。執行 sysctl -w net.ipv4.ip_forward=1。若是在啓動docker服務的時候設定 --ip-forward=true,Docker就會自動設定系統的ip_forward參數爲1。
在宿主機執行 docker inspect kibana,查看運行容器的ip
而後在宿主機ping容器的IP ping 172.18.0.1,發如今宿主機能夠ping通容器。反之在容器內也能夠ping通宿主機。(容器內安裝ping工具包 apt-get install iputils-ping)。 由此能夠,默認狀況下主機和容器是互通的。 容器的ip在啓動的時候分配,不過在容器從新啓動以後,ip會發生變化。
在相同主機直接的容器也是能夠相互通訊的。
外部訪問容器實現
容器容許外部訪問,能夠在docker run的時候經過 -p 或者-P參數來啓用。無論用那種方式,其實也是在本地的iptables的nat表中添加相應的規則.
使用 -p 6379:6379 時: iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:6379 to:172.18.0.2:6379
這裏規則映射了0.0.0.0,意味着將接受主機來自全部接口的流量。用戶能夠經過 -p IP:host_port:container_port或者 -ip IP::port 來制定容許訪問容器的主機上的IP,接口等。