Libnetwork最初是由libcontainer和Docker Engine中的網絡相關的代碼合并而成的,是Docker容器網絡庫,最核心的内容是其定義的Container Network Model(CNM)。
Libnetwork CNM 定義了Docker容器的網絡模型,按照該模型開發出的driver就能與docker daemon協同工作,實作容器網絡。docker 原生的driver包括 none、bridge、overlay和macvlan,第三方driver包括flannel、weave、calico等。

CNM定義了如下三個元件:
Sandbox
Sandbox是Docker容器中一個網絡配置的隔離環境,包含容器的interface、路由表和DNS設定。Linux Network Namespace是Sandbox的标準實作。Sandbox可以包含來自不同 Network的Endpoint。
Endpoint
Endpoint是一個在Network中進行網絡通訊的接口(veth pair),用于将Sandbox接入Network。一個Endpoint隻能屬于一個Network,也隻能屬于一個Sandbox
Endpoint可以加入一個network,但多個Endpoint可以在一個Sandbox中共存。
Network
一個Network就是一個唯一的、可識别的endpoint組,組内endpoint可以互相通訊。Network的實作可以是linux Bridge、VLAN等。
通過<code>nsenter --net=&lt;SandboxKey&gt; ip add</code>可以直接進入容器的Sandbox,查詢相關的網絡資訊
建立一個自定義的overlay網絡:
隻需在manager節點建立,當有Service連接配接該overlay網絡時,将會自動在所配置設定的worker節點上自動建立該overlay網絡。
建立一個連接配接到自定義的overlay網絡的service(未指定"endpoint-mode"則預設為VIP模式)
Docker會為每個overlay網絡建立一個獨立的network namespace,其中會有一個linux bridge br0,endpoint還是由veth pair實作,一端連接配接到容器中的eth0,另一端連接配接到network namespace的br0上。
<code>br0除了連接配接所有的endpoint,還會連接配接一個vxlan裝置,用于與其他host建立vxlan tunnel。容器之間的資料就是通過這個tunnel通信的。</code>
service-name将通過内置的DNS解析到VIP位址
Service IP:<code>192.168.10.2</code>在iptables的mangle表的OUTPUT鍊中被标記為0x112(274),IPVS通過該标記将Service IP轉發到192.168.10.3和192.168.10.4的容器
VIP模式中,swarm mode為容器配置設定了一個連接配接到overlay網絡(my-network)的網卡<code>"eth0@if103"</code>且生成了VIP,同時也配置設定了一個連接配接到docker_gwbridge網絡的網卡<code>"eth1@if105"</code>用于連接配接外部網絡。
所有連接配接到my-network網絡中的容器可以通過service-name或者VIP來通路service,通過service-name通路時,将先通過内置的DNS服務解析擷取到VIP。
建立一個連接配接到自定義的overlay網絡的service,并指定endpoint-mode為dnsrr
service-name将通過内置的DNS解析到每個容器的overlay網絡位址
建立一個連接配接到自定義的overlay網絡的service,并将容器的80端口映射host的80端口
容器中除了lo,還建立了3個網卡:
eth0:連接配接到<code>ingress</code>的網絡,通過routing mesh提供外部服務通路。
eth1:當service設定了端口映射時,swarm會為Service中的每個容器另外配置設定一塊網卡,連接配接到<code>docker_gwbridge</code>網絡。當容器内部主動往外發送資料時,由docker_gwbridge SNAT轉發至外部網絡。
eth2:連接配接到<code>my-network</code>的overlay網絡。
如果在建立Service時映射了端口,swarm mode将會<code>通過routing mesh在所有節點上監聽80端口,即使節點上未建立相應的容器</code>,并通過iptables做反向NAT,當用戶端通路叢集中的任意節點的80端口,swarm負載均衡會将請求路由到一個活動的容器。若不想在未建立容器的節點上監聽published端口,則可在映射端口時通過<code>--publish mode=host,target=80,published=8080</code>進行指定。
建立完Service之後會發現Virtual IPs有兩個入口,其中<code>10.255.0.5</code>連接配接到ingress網絡,<code>192.168.10.7</code>是連接配接自定義的my-network網絡。當外部用戶端通路服務時,swarm負載均衡的流程如下:
1、使用者通路swarm-node1上的Nginx服務(172.16.100.21:80)
2、iptables将根據<code>-A DOCKER-INGRESS -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.18.0.2:80</code>的規則将請求轉發至<code>ingress sanbox</code>中的172.18.0.2:80。
3、ingress sanbox中的iptable根據不同的端口設定不同的mark(0x114/276)。
4、ipvs将根據不同的mark轉發到對應的real server(容器namespace);
<code>-> 10.255.0.7:0 Masq 1 0 0</code>
<code></code>
<code>本文轉自Vnimos51CTO部落格,原文連結:</code>http://blog.51cto.com/vnimos/2053238,如需轉載請自行聯系原作者