文章目錄
基礎理論
在頂層設計中,Docker 網絡架構由 3 個主要部分構成:CNM、Libnetwork 和驅動。
- CNM 是設計標準。在 CNM 中,規定了 Docker 網絡架構的基礎組成要素。
- Libnetwork 是 CNM 的具體實現,並且被 Docker 採用,Libnetwork 通過 Go 語言編寫,並實現了 CNM 中列舉的核心組件。
- 驅動通過實現特定網絡拓撲的方式來拓展該模型的能力。
下圖展示了頂層設計中的每個部分是如何組裝在一起的。
libnetwork(CNM)介紹
Docker 網絡架構源自一種叫作容器網絡模型(CNM)的方案,該方案是開源的並且支持插接式連接。
Libnetwork 是 Docker 對 CNM 的一種實現,提供了 Docker 核心網絡架構的全部功能。不同的驅動可以通過插拔的方式接入 Libnetwork 來提供定製化的網絡拓撲。
libnetwork是容器網絡庫,其核心內容是其定義的Container Network Model,這個模型對容器網絡進行了抽象,由三個組件組成
-
Sandbox(沙盒)
沙盒是一個隔離的網絡運行環境,保存了容器網絡棧的配置,包括了對網絡接口、路由表和DNS的管理。在Linux平臺上,Sandbox是用Linux Network Namespace實現的,Sandbox可以包含來自多個網絡的多個Endpoint(端點)。
-
Endpoint
Endpoint的作用是將Sandbox接入Network,Endpoint的典型實現是veth pair。一個Endpoint只能屬於一個網絡,也只能屬於一個Sandbox。通過給沙盒增加多個Endpoint可以將沙盒加入多個網絡
-
Network
包含一組Endpoint,同一Network的Endpoint可以直接通信。Network的實現driver可以是Linux Bridge,VxLAN等。
veth pair介紹
veth-pair 就是一對的虛擬設備接口,和 tap/tun 設備不同的是,它都是成對出現的。一端連着協議棧,一端彼此相連着。它常常充當着一個橋樑,連接着各種虛擬網絡設備,典型的例子像“兩個 namespace 之間的連接”,“Bridge、OVS 之間的連接”,“Docker 容器之間的連接” 等等,以此構建出非常複雜的虛擬網絡結構,比如 OpenStack Neutron。
網絡驅動
Docker的網絡子系統是可插拔的,使用驅動程序。默認情況下存在多個驅動程序,並提供核心網絡功能:
- bridge:Docker默認的容器網絡驅動。Container通過一對veth pair連接到docker0網橋上,由Docker爲容器分配IP及配置路由、防火牆規則等。
- host:容器與主機共享同一Network Namespace,共享同一套網絡協議棧、路由表及iptables規則等。容器與主機看到的是相同的網絡視圖。
- null:容器內網絡配置爲空,需要用戶收到爲容器配置網絡接口及路由等。
- macvlan:Macvlan網絡允許爲容器分配MAC地址,使其顯示爲網絡上的物理設備。Docker守護程序通過其MAC地址將流量路由到容器。macvlan在處理期望直接連接到物理網絡的傳統應用程序時,使用驅動程序有時是最佳選擇,而不是通過Docker主機的網絡堆棧進行路由。
- overlay:overlay將多個Docker守護程序連接在一起,並使羣集服務能夠相互通信。overlay是Docker原生的跨主機多子網網絡方案。主要通過使用Linux bridge和vxlan隧道實現,底層通過類似於etcd或consul的KV存儲系統實現多機的信息同步。
- remote:Docker網絡插件的實現。Remote driver使得Libnerwork可以通過HTTP RESTful API對接第三方的網絡方案,類似SockerPlane的SDN方案只有實現了約定的HTTP URL處理函數及底層的網絡接口配置方法,就可以替換Docker原生的網絡實現。
網絡類型
1、none模式網絡
使用–network =none指定,生成只包含環回口的容器,用於封閉場景
2、host模式網絡
容器與主機共享Root Network Namespace,連接到host網絡的容器共享host的網絡棧,容器的配置與host完全一樣,用於對網絡性能要求高的場景。但是這種配置讓容器有完整的權限可以操縱主機的協議、路由表和防火牆等,所以被認爲是不安全的
3、bridge模式網絡(默認模式)
Docker daemon啓動時會在主機創建一個Linux網橋(默認爲docker0,可通過-b參數手動指定)。容器啓動時,Docker會創建一對veth pair(虛擬網絡接口)設備,veth設備的特點是成對存在,從一端進入的數據會同時出現在另一端。Docker會將一端掛載到docker0網橋上,另一端放入容器的Network Namespace內,從而實現容器與主機通信的目的。
例子
此時我們可以在另一個終端看到docker0下多了一個接口,且容器和網橋處於同一網段
4、container模式網絡
與另一個運行中的容器共享Network Namespace,共享相同的網絡視圖。
例子:
首先以默認網絡配置(bridge模式)啓動一個容器,設置hostname爲dockerNet,dns爲114.114.114.114
然後以–network=container:9bb方式啓動另一個容器
可以看到,使用–net=container:9bb參數啓動的容器,容器ip地址,dns,hostname都繼承了容器9bb…,實質上兩個容器是共享同一個Network Namespace的,自然網絡配置也是完全相同的
5、user-defined模式網絡
用戶自定義模式主要可選的有三種網絡驅動:bridge、overlay、macvlan。bridge驅動用於創建類似於前面提到的bridge網絡;overlay和macvlan驅動用於創建跨主機的網絡。
使用overlay實現的多host網絡通信
overlay類型的網絡的網絡驅動器爲overlay,overlay網絡的實現是基於VXLAN的。overlay要正常使用需要內核版本>=3.16
什麼是 VXLAN?
VXLAN(Virtual eXtensible Local Area Network,虛擬擴展局域網),是由IETF定義的NVO3(Network Virtualization over Layer 3)標準技術之一,本質上是一種隧道技術。通過將原始數據幀添加VXLAN頭後封裝在UDP報文中,並以傳統IP網絡的傳輸方式轉發該UDP報文。報文到達目的端點後,去掉外層封裝的部分,將原始數據幀交付給目標終端。
VXLAN本質上是一種隧道技術,能在三層網絡的基礎上建立二層以太網網絡隧道,從而實現跨地域的二層互連。
VXLAN 是將二層建立在三層上的網絡,通過將二層數據封裝到 UDP 的方式來擴展數據中心的二層網段數量。
VXLAN 是一種在現有物理網絡設施中支持大規模多租戶網絡環境的解決方案。
VXLAN 的傳輸協議是 IP + UDP
若想對VXLAN有更多的瞭解,可以看以下文章
https://support.huawei.com/enterprise/zh/doc/EDOC1100087027?partNo=10042
key-value 數據庫
Docerk overlay 網絡需要一個 key-value 數據庫用於保存網絡狀態信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 軟件,我們這裏使用 Consul。
overlay環境準備
這裏準備了三臺centos7的虛擬機,下面以host0,host1,host2代替,注意:overlay要正常使用需要內核版本>=3.16
1、在host0部署consul組件
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
通過 http://IP:8500 訪問consul
2、修改 host1 和 host2 的 docker daemon配置
vim /lib/systemd/system/docker.service
#host1
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store consul://192.168.189.133:8500 --cluster-advertise 192.168.189.135:2375
#host2
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store consul://192.168.189.133:8500 --cluster-advertise 192.168.189.136:2375
--cluster-store 指定 consul 的地址。
--cluster-advertise 告知 consul 自己的連接地址。
3、host1,host2重啓docker
#加載新service配置文件
systemct daemon-reload
#啓動
systemctl restart docker
4、查看consule的key/value信息
在overlay中運行容器
1、在host1上創建overlay網絡
#創建overlay網絡
[root@localhost ~]# docker network create -d overlay ov_net1
0b09ef758f172ecbee829c93cb7c5bc2b984a73b1819de79e3e59ccdb327a1cd
查看,在host1,host2都能看到
#[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
16a3cafba630 bridge bridge local
bc33d5d6a62d docker_gwbridge bridge local
b892f32d2fdd host host local
5e181b658ef2 none null local
0b09ef758f17 ov_net1 overlay global
#查看詳細信息
docker network inspect ov_net1
2、在host1,host2上創建容器運行加入overlay網絡
#host1:
docker run -itd --name bbox1 --net ov_net1 busybox
#host2:
docker run -itd --name bbox2 --net ov_net1 busybox
3、測試聯通性
ping x.x.x.x
ping bbox1