1. 程式人生 > >006.Docker網路管理

006.Docker網路管理

docker網路模式

Docker使用Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離程序,Mount Namespace隔離檔案系統,Network Namespace隔離網路等。 一個Network Namespace提供了一份獨立的網路環境,包括網絡卡、路由、Iptable規則等都與其他的Network Namespace隔離,Docker容器一般會分配一個獨立的Network Namespace。

1.1 四種模式

  • host模式
指定方式:--net=host
  • container模式
指定方式:--net=container:NAME_or_ID
  • none模式
指定方式:--net=none
  • bridge模式
指定方式:--net=bridge
  1 [email protected]:~# docker network ls		#預設已經建立好三種模式,且無法刪除
  2 NETWORK ID          NAME                DRIVER              SCOPE
  3 4237839afd99        bridge              bridge              local
  4
c7a14aafc3b5 host host local 5 3cc2eba3eb5f none null local
 

1.2 host模式

容器網路指定為host模式,則容器將不會獲得獨立的Network Namespace,該模式下宿主機共用一個Network Namespace。容器將不會虛擬出自己的網絡卡,不會配置獨有的IP等,而是使用宿主機的IP和埠。 其具有以下特點:
  • host模式下的容器沒有隔離的 network namespace;
  • 容器的 IP 地址同 Docker host 的 IP 地址;
  • 需要注意容器中服務的埠號不能與 Docker host 上已經使用的埠號相沖突;
  • host 模式能夠和其它模式共存。
49_thumb1
  1 [email protected]:~# docker run -d --name docker_host1 --network host training/webapp python app.py
  2 [email protected]:~# docker exec -it docker_host1 /bin/bash
  3 [email protected]:/opt/webapp# ifconfig -a
  50_thumb1 宿主機172.24.8.90/24上使用host模式啟動一個容器,則檢視的網絡卡資訊為宿主機資訊,容器中的應用對外直接採用宿主機IP地址提供服務,無任何NAT轉換。 注意:除網路外,容器的其他方面,如檔案系統、程序列表等還是和宿主機隔離的,同時採用host模式,埠無法做對映,無需指定,否則會出現warning告警。

1.3 container模式

Container 網路模式是 Docker 中一種較為特別的網路的模式,處於container模式下的 Docker 容器會共享其他容器的網路環境,因此,兩個或以上的容器之間不存在網路隔離,而配置container模式的容器又與宿主機以及除此之外其他的容器存在網路隔離。  51_thumb1
  1 [email protected]:~# docker run -dit --name docker_host2 centos7-xhy /bin/bash
  2 [email protected]:~# docker run -dit --name docker_host3 --network container:docker_host2 centos7-xhy /bin/bash
  3 [email protected]:~# docker exec -it docker_host2 /bin/bash
  4 [[email protected] /]# ifconfig -a
  52_thumb1
  1 [email protected]:~# docker exec -it docker_host3 /bin/bash
  2 [[email protected] /]# ifconfig -a
  53_thumb1 注意:因為此時兩個容器要共享一個 network namespace,因此需要注意埠衝突情況,否則第二個容器將無法被啟動,以上docker_host3因為埠原因,無法正常啟動。

1.4 none模式

none模式下,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置和構造任何網路環境。 Docker 容器採用了none 網路模式,那麼容器內部就只能使用loopback網路裝置,不會再有其他的網路資源。Docker Container的none網路模式意味著不給該容器建立任何網路環境,容器只能使用127.0.0.1的本機網路。
  1 [email protected]:~# docker run -dit --name docker_host4 --network none centos7-xhy /bin/bash
  2 [email protected]:~# docker exec -it docker_host4 /bin/bash
  54_thumb1

1.5 bridge模式

見二。

二 bridge模式

2.1 bridge模式簡介

bridge模式是Docker預設的網路設定,此模式會為每一個容器分配Network Namespace、設定IP等,並將該宿主機上的Docker容器連線到一個虛擬網橋上。 使用docker run -p時,docker會在iptables寫入DNAT規則,實現埠轉發功能。可使用以下命令檢視。
  1 [email protected]:~# iptables -t nat -vnL
  55_thumb1 當Docker server啟動時,會在主機上建立一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連線到此虛擬網橋上,因此所有連線到此網橋的容器預設能互相通訊。 虛擬網橋會使該宿主機上所有容器就通過交換機連在了一個二層網路中,宿主機會選擇一個和宿主機不同的IP地址和子網分配給docker0,連線到docker0的容器就從此子網中選擇一個未佔用的IP使用。 56_thumb1

2.2 bridge模式特點

  • 使用一個 linux bridge,預設為 docker0;
  • 使用 veth 對,一端在容器的網路 namespace 中,另一端在 docker0 上;
  • 該模式下Docker Container不具有一個公有IP,因為宿主機的IP地址與veth pair的 IP地址不在同一個網段內;
  • Docker採用 NAT 方式,將容器內部的服務監聽的埠與宿主機的某一個埠port 進行“繫結”,使得宿主機以外的網路可以主動將網路報文傳送至容器內部;
  • 外界訪問容器內的服務時,需要訪問宿主機的 IP 以及宿主機的埠 port;
  • NAT 模式基於三層網路上的實現方式,故肯定會影響網路的傳輸效率;
  • 容器擁有獨立、隔離的網路棧,以便於使得容器和宿主機以外的網路通過NAT建立通訊;
57_thumb1
  1 [email protected]:~# docker run -dit --name docker_host5 -p 5005:80 training/webapp python app.py
  2 [email protected]:~# docker exec -it docker_host5 /bin/bash
  3 [email protected]:/opt/webapp# ifconfig -a
  58_thumb1
  1 [email protected]:~# iptables -t nat -vnL			#檢視埠對映
59_thumb1
  1 [email protected]:~# iptables-save
  2 ……
  3 -A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE
  4 ……
  5 -A DOCKER ! -i docker0 -p tcp -m tcp --dport 5005 -j DNAT --to-destination 172.17.0.3:80
  解釋: -s :源地址172.17.0.0/16 -o:指定資料報文流出介面為docker0 -j :動作為MASQUERADE(地址偽裝) iptables規則中nat、filter的Docker鏈中分別增加了一條規則,這兩條規則將訪問宿主機5005埠的流量轉發到了172.17.0.3的80埠上,即真正提供服務的Docker容器IP和埠,因此外界訪問Docker容器是通過iptables做DNAT(目的地址轉換)實現。

三 docker容器的DNS和主機名

3.1 DNS和主機名配置檔案

同一個Docker映象可以啟動很多Docker容器,但各自容器的主機名並不一樣,即主機名並非是被寫入映象中。 通過在容器中執行mount命令可以檢視/etc/目錄下有3個檔案,即容器啟動後被虛擬檔案覆蓋的,分別是/etc/hostname、/etc/hosts、/etc/resolv.conf:
  1 [email protected]:~# docker run -dit --name docker_host6 centos7-xhy /bin/bash
  2 [email protected]:~# docker exec -it docker_host6 /bin/bash
  3 [[email protected] /]# mount
  4 ...
  5 /dev/sda4 on /etc/resolv.conf type ext4 (rw,relatime,data=ordered)
  6 /dev/sda4 on /etc/hostname type ext4 (rw,relatime,data=ordered)
  7 /dev/sda4 on /etc/hosts type ext4 (rw,relatime,data=ordered)
  8 ...
提示:此方式能解決主機名的問題,同時也能讓DNS及時更新(改變resolv.conf)。由於這些檔案的維護方法隨著Docker版本演進而不斷變化,因此儘量不修改這些檔案。

3.2 修改dns和主機名

docker容器的dns和主機名配置可通過Docker提供的引數進行相關設定,配置方式如下:
  • -h HOSTNAME 或 --hostname=HOSTNAME:設定容器的主機名,此名稱會寫入/etc/hostname和/etc/hosts檔案中,也會在容器的bash提示符看到。但是在外部,容器的主機名是無法檢視的,不會出現在其他容器的hosts檔案中,即使使用docker ps命令也無法檢視。此引數是docker run命令的引數,而非docker daemon的啟動引數。
  • --dns=IP_ADDRESS...:為容器配置DNS,寫入/etc/resolv.conf中。該引數可以在docker daemon 啟動的時候設定,也可以在docker run時設定,預設為8.8.8.8或8.8.4.4。
注意:對以上3個檔案的修改不會被docker commit儲存,即不會儲存在映象中,重啟容器也會導致修改失效。

四 多節點docker網路

docker跨主機通訊按原理可通過以下三種方式實現:
  • 直接路由方式;
  • 橋接方式(如pipework);
  • Overlay隧道方式(如flannel、ovs+gre)等。
Docker 多節點Overlay網路模式可以分為兩類:
  • 一類是基於 VxLAN ,對跨節點網路的原生支援;
  • 另一種是通過外掛(plugin)方式引入的第三方實現方案,比如 Flannel,Calico 等等。

4.1 直接路由方式

在docker所在的不同宿主機上採用靜態路由方式實現。

4.2 橋接-pipework方式

當兩臺網路已聯通的宿主機01和02都存在多個容器組成的叢集時,需要相互訪問容器應用時,可通過靜態指定容器IP為宿主機IP同一個網路的形式,即可實現。 60_thumb1
  1 [email protected]:~# apt-get install bridge-utils	#兩臺docker宿主機都建議安裝此工具
  2 [email protected]:~# apt-get install bridge-utils	#兩臺docker宿主機都建議安裝此工具
  3 [email protected]:~# docker run -dit --name container01 --net=none centos:7 /bin/bash
  4 [email protected]:~# docker run -dit --name container02 --net=none centos:7 /bin/bash
  5 [email protected]:~# docker run -dit --name container03 --net=none centos:7 /bin/bash
  6 [email protected]:~# docker run -dit --name container04 --net=none centos:7 /bin/bash
  7 
  8 [email protected]:~# git clone https://github.com/jpetazzo/pipework
  9 [email protected]:~# git clone https://github.com/jpetazzo/pipework
 10 [email protected]:~# cp pipework/pipework /usr/local/bin/
 11 [email protected]:~# cp pipework/pipework /usr/local/bin/
 12 [email protected]:~# chmod u+x /usr/local/bin/pipework
 13 [email protected]:~# brctl show			#檢視當前預設的橋接網絡卡
  61_thumb1
  1 [email protected]:~# pipework br0 container01 172.24.8.201/[email protected]
  2 [email protected]:~# pipework br0 container02 172.24.8.202/[email protected]
  3 [email protected]:~# pipework br0 container03 172.24.8.203/[email protected]
  4 [email protected]:~# pipework br0 container04 172.24.8.204/[email protected]
  若提示Warning: arping not found,可採用以下方式安裝:apt-get -y install arping
  1 [email protected]:~# brctl show
62_thumb1
  1 [email protected]:~# brctl show
63_thumb1 提示: pipework通過network namespace,veth pair以及linux bridge完成容器網路的設定,執行過程大概如下:
  • 檢視主機是否包含br0(可以自定義)網橋,如果不存在就建立;
  • 向容器例項新增一塊網絡卡(可以設定網絡卡名),並配置相應的固定IP;
  • 若容器例項已經有預設的路由,則刪除掉,將@後面的IP設定為預設路由的閘道器;
  • 將容器例項連線到建立的br0網橋上。
注意:pipework通過link名字來判斷是bridge還是ovs switch,br開頭為網橋, ovs開頭為openvswitch,所以pipework建立的網絡卡必須以br開頭。 也可通過以下命令手動提前建立網橋:
  1 [email protected]:~# docker network create --driver bridge --subnet 172.24.8.0/24 --gateway 172.24.8.2 br1
  2 [email protected]:~# docker network inspect br1
  64_thumb1
  1 [email protected]:~# ip addr add 172.24.8.90/24 dev br0;\
  2 ip addr del 172.24.8.90/24 dev eth0;\
  3 brctl addif br0 eth0;\
  4 ip route del default;\
  5 ip route add default via 172.24.8.2 dev br0
  6 [email protected]:~# ip addr add 172.24.8.91/24 dev br0 ;\
  7 ip addr del 172.24.8.91/24 dev eth0;\
  8 brctl addif br0 eth0;\
  9 ip route del default;\
 10 ip route add default via 172.24.8.2 dev br0
  提示:將兩臺宿主機eth0橋接到br0上,並把eth0的IP配置在br0上。 65_thumb1 66_thumb1
  1 [email protected]:~# ping 172.24.8.201
67_thumb1 注意:pipework設定固定IP的情況下,容器重啟後IP會自動消失,需要重新設定。

4.3 基於etcd Docker原生overlay網路

見《007.docker etcd分散式網路部署》

4.4 基於Flannel的overlay網路

Overlay網路指一種網路架構上疊加的虛擬化技術模式,其大體框架是對基礎網路不進行大規模修改的情況下,實現應用在網路上的承載,並能與其他網路業務分離,並且以基於IP的網路技術為主。 案例見《008.docker flannel+etcd分散式網路部署》