Docker網絡

整理自《Docker進階與實戰》docker

Docker網絡現狀

爲了解決容器網絡性能低下、功能不足的問題,Docker啓動了子項目「Libnetwork」。Libnetwork提出了新的容器網絡模型(Container Network Model,簡稱CNM),定義了標準的API用於爲容器配置網絡,其底層能夠適配各類網絡驅動(如圖Docker-network01所示)。CNM有三個:shell

  • 沙盒
    沙盒是一個隔離的網絡運行環境,保存了容器網絡棧的配置,包括了對網絡接口、路由表和DNS配置的管理。在Linux平臺上,沙盒是用Linux Network Namespace實現的,在其餘平臺上多是不一樣的概念,如FreeBSD Jail。一個沙盒能夠包括來自多個網絡的多個Endpoint(端點)。ubuntu

  • Endpoint
    Endpoint將沙盒加入一個網絡,Endpoint的實現能夠是一對veth pair或者OVS內部端口,當前的Libnetwork使用的是veth pair。一個Endpoint只能隸屬於一個沙盒及一個網絡。經過給沙盒增長多個Endpoint能夠將一個沙盒加入多個網絡。segmentfault

  • 網絡
    網絡包括一組能互相通訊的Endpoint。網絡的實現能夠是Linux bridge、vlan等。 圖Docker-network01 CNM概念模型安全

從CNM的概念角度講,Libnetwork的出現使得Docker具有了跨主機多子網的能力,同一個子網內的不一樣容器能夠運行在不一樣主機上。好比,同屬於192.168.0.0/24子網IP地址分別爲192.168.0.1和192.168.0.2的容器能夠位於不一樣的主機上且能夠直接通訊,而持有IP 192.168.1.1的容器即便與IP爲192.168.0.1的容器處於同一主機也不能互通。bash

Libnetwork已經實現了五種驅動(driver):網絡

  • bridge
    Docker默認的容器網絡驅動。Container經過一對veth pair鏈接到docker0網橋上,由Docker爲容器動態分配IP及配置路由、防火牆規則等。函數

  • host
    容器與主機共享同一Network Namespace,共享同一套網絡協議棧、路由表及iptables規則等。容器與主機看到的是相同的網絡視圖。性能

  • null
    容器內網絡配置爲空,須要用戶手動爲容器配置網絡接口及路由等。spa

  • remote
    Docker網絡插件的實現。Remote driver使得Libnetwork能夠經過HTTP RESTful API對接第三方的網絡方案,相似SocketPlane的SDN方案只要實現了約定的HTTP URL處理函數及底層的網絡接口配置方法,就能夠替換Docker原生的網絡實現。

  • overlay
    Docker原生的跨主機多子網網絡方案。主要經過使用Linux bridge和vxlan隧道實現,底層經過相似於etcd或consul的KV存儲系統實現多機的信息同步。overlay驅動當前還未正式發佈,但開發者能夠經過編譯實驗版的Docker來嘗試使用,Docker實驗版同時提供了額外的network和service子命令來進行更靈活的網絡操做,不過,須要內核版本>=3.16纔可正常使用。

以上五種驅動已經隨Docker 1.8一同發佈。

基本網絡配置

Linux平臺下,Docker容器網絡資源經過內核的Network Namespace機制實現隔離,不一樣的Network Namespace有各自的網絡設備、協議棧、路由表、防火牆規則等,反之,同一Network Namespace下的進程共享同一網絡視圖。經過對Network Namespace的靈活操縱,Docker提供了五種容器網絡模式。

  • none

不爲容器配置任何網絡功能。
在該模式下,須要以-–net=none參數啓動容器

$ docker run --net=none -ti ubuntu:latest ip addr show

使用-–net=none啓動容器以後,仍然能夠手動爲容器配置網絡。

  • container

與另外一個運行中的容器共享Network Namespace,共享相同的網絡視圖。
舉個例子,首先以默認網絡配置(bridge模式)啓動一個容器,設置hostnamedockerNetdns8.8.4.4

$ docker run -h dockerNet --dns 8.8.4.4 -tid ubuntu:latest bash
964286222ab53c67b2d6fb1882b2364c745be718a4a13530b016fe51b4968054

而後以–-net=container:96428方式啓動另外一個容器

$ docker run --net=container:96428 -ti ubuntu:latest bash

進入容器,經過ip addr show命令能夠發現兩個容器的IP地址、DNS、hostname都是相同的。實質上兩個容器是共享同一個Network Namespace的,網絡配置天然也是徹底相同的。

  • host

與主機共享Root Network Namespace,容器有完整的權限能夠操縱主機的協議棧、路由表和防火牆等,因此被認爲是不安全的。
相應的,host模式啓動時須要指定-–net=host參數。舉個例子

$ docker run -ti --net=host ubuntu:latest bash

host模式下,容器能夠操縱主機的網絡配置,這是危險的,除非萬不得已,應該儘量避免使用host模式。

  • bridge

Docker設計的NAT網絡模型。
Docker daemon啓動時會在主機建立一個Linux網橋(默認爲docker0,可經過-b參數手動指定)。容器啓動時,Docker會建立一對veth pair(虛擬網絡接口)設備,veth設備的特色是成對存在,從一端進入的數據會同時出如今另外一端。Docker會將一端掛載到docker0網橋上,另外一端放入容器的Network Namespace內,從而實現容器與主機通訊的目的。bridge模式下的網絡拓撲圖如圖docker-network02所示:

圖Docker-network02 bridge模式的網絡拓撲圖

在橋接模式下,Docker容器與Internet的通訊,以及不一樣容器之間的通訊,都是經過iptables規則控制的。總之,Docker網絡的初始化動做包括:建立docker0網橋、爲docker0網橋新建子網及路由、建立相應的iptables規則等。Bridge模式是Docker默認的容器運行模式,以bridge模式啓動的容器,默認會從172.17.42.1/16子網內分配IP。

  • overlay

Docker原生的跨主機多子網模型。
overlay網絡模型比較複雜,底層須要相似consul或etcd的KV存儲系統進行消息同步,核心是經過Linux網橋與vxlan隧道實現跨主機劃分子網。如圖Docker-network03所示,每建立一個網絡,Docker會在主機上建立一個單獨的沙盒,沙盒的實現實質上是一個Network Namespace。在沙盒中,Docker會建立名爲br0的網橋,並在網橋上增長一個vxlan接口,每一個網絡佔用一個vxlan ID,當前Docker建立vxlan隧道的ID範圍爲256~1000,於是最多能夠建立745個網絡。當添加一個容器到某一個網絡上時,Docker會建立一對veth網卡設備,一端鏈接到此網絡相關沙盒內的br0網橋上,另外一端放入容器的沙盒內,並設置br0的IP地址做爲容器內路由默認的網關地址,從而實現容器加入網絡的目的。

圖Docker-network03 overlay模式的網絡拓撲圖

以圖Docker-network03爲例,容器1和容器4同屬一個網絡,容器1須要經過256號vxlan隧道訪問另外一臺主機的容器4。Docker經過vxlan和Linux網橋實現了跨主機的虛擬子網功能。
使用shell命令查看overlay網絡拓撲

# 建立網絡
$ docker network create -d overlay dev
# 顯示網絡列表
$ docker network ls
9101d162c6db bridge bridge
fcd0327f5104 dev overlay
f5f9c8723777 none null
eb81445767e1 host host
# fcd0327f5104實質上是dev網絡的網絡ID,建立軟連接的目的是爲了可以使用ip命令操縱名字空間。
# ln -s /var/run/docker/netns/fcd0327f5104 /var/run/netns/fcd0327f5104
# 查看端口詳細信息
$ ip netns exec fcd0327f5104 ip addr show
# 查看網橋信息
$ ip netns exec fcd0327f5104 brctl show
# 查看vxlan詳細信息
$ ip netns exec fcd0327f5104 ip -d link show vxlan1

綜上所述,Docker的整個網絡模型,是創建在Network Namespace、Linux網橋、vxlan隧道、iptables規則之上的,也正是因爲過於依賴網橋與iptables,致使Docker的網絡效率不高。

Docker網絡相關參數

關於Docker網絡相關參數請參考「Docker(1.11.1)命令」。

待續···

相關文章
相關標籤/搜索