4、容器虚拟化网络概述
Docker 網(wǎng)絡(luò)
Docker 的網(wǎng)絡(luò)實現(xiàn)其實就是利用了 Linux 上的網(wǎng)絡(luò)名稱空間和虛擬網(wǎng)絡(luò)設(shè)備(特別是 veth pair)。
Linux 網(wǎng)絡(luò)命名空間:https://www.jianshu.com/p/369e50201bce
Linux虛擬網(wǎng)絡(luò)設(shè)備之veth:?https://segmentfault.com/a/1190000009251098
監(jiān)控和調(diào)整Linux網(wǎng)絡(luò)堆棧:接收數(shù)據(jù):https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/
Linux網(wǎng)絡(luò)-數(shù)據(jù)包的發(fā)送過程:https://segmentfault.com/a/1190000008926093
Docker網(wǎng)絡(luò)核心原理? ?http://blog.51cto.com/ganbing/2087598
?
基本原理
首先,要實現(xiàn)網(wǎng)絡(luò)通信,機器需要至少一個網(wǎng)絡(luò)接口(物理接口或虛擬接口)來收發(fā)數(shù)據(jù)包;此外,如果不同子網(wǎng)之間要進行通信,需要路由機制。
Docker 中的網(wǎng)絡(luò)接口默認(rèn)都是虛擬的接口。虛擬接口的優(yōu)勢之一是轉(zhuǎn)發(fā)效率較高。Linux 通過在內(nèi)核中進行數(shù)據(jù)復(fù)制來實現(xiàn)虛擬接口之間的數(shù)據(jù)轉(zhuǎn)發(fā),發(fā)送接口的發(fā)送緩存中的數(shù)據(jù)包被直接復(fù)制到接收接口的接收緩存中。
對于本地系統(tǒng)和容器內(nèi)系統(tǒng)看來就像是一個正常的以太網(wǎng)卡,只是它不需要真正同外部網(wǎng)絡(luò)設(shè)備通信,速度要快很多。
Docker 容器網(wǎng)絡(luò)就利用了這項技術(shù)。它在本地主機和容器內(nèi)分別創(chuàng)建一個虛擬接口,并讓它們彼此連通(這樣的一對接口叫做?veth pair)。
?
veth設(shè)備的特點
?
- veth和其它的網(wǎng)絡(luò)設(shè)備都一樣,一端連接的是內(nèi)核協(xié)議棧。
- veth設(shè)備是成對出現(xiàn)的,另一端兩個設(shè)備彼此相連
- 一個設(shè)備收到協(xié)議棧的數(shù)據(jù)發(fā)送請求后,會將數(shù)據(jù)發(fā)送到另一個設(shè)備上去。
?
參考自??http://blog.51cto.com/ganbing/2087598? ??https://segmentfault.com/a/1190000009251098
使用docker run命令創(chuàng)建一個執(zhí)行shell(/bin/bash)的Docker容器,假設(shè)容器名稱為con1。
? ? ?在con1容器中可以看到它有兩個網(wǎng)卡lo和eth0。lo設(shè)備不必多說,是容器的回環(huán)網(wǎng)卡;eth0即為容器與外界通信的網(wǎng)卡,eth0的ip 為 172.17.0.2/16,和宿主機上的網(wǎng)橋docker0在同一個網(wǎng)段。
? ? ?查看con1的路由表,可以發(fā)現(xiàn)con1的默認(rèn)網(wǎng)關(guān)正是宿主機的docker0網(wǎng)卡,通過測試, con1可以順利訪問外網(wǎng)和宿主機網(wǎng)絡(luò),因此表明con1的eth0網(wǎng)卡與宿主機的docker0網(wǎng)卡是相互連通的。
? ? ?這時再來查看(ifconfig)宿主機的網(wǎng)絡(luò)設(shè)備,會發(fā)現(xiàn)有一塊以"veth"開頭的網(wǎng)卡,如veth60b16bd,我們可以大膽猜測這塊網(wǎng)卡肯定是veth設(shè)備了,而veth pair總是成對出現(xiàn)的。veth pair通常用來連接兩個network namespace,
? ? ?那么另一個應(yīng)該是Docker容器con1中的eth0了。之前已經(jīng)判斷con1容器的eth0和宿主機的docker0是相連的,那么veth60b16bd也應(yīng)該是與docker0相連的,不難想到,docker0就不只是一個簡單的網(wǎng)卡設(shè)備了,而是一個網(wǎng)橋。
? ? ?真實情況正是如此,下圖即為Docker默認(rèn)網(wǎng)絡(luò)模式(bridge模式)下的網(wǎng)絡(luò)環(huán)境拓?fù)鋱D,創(chuàng)建了docker0網(wǎng)橋,并以eth pair連接各容器的網(wǎng)絡(luò),容器中的數(shù)據(jù)通過docker0網(wǎng)橋轉(zhuǎn)發(fā)到eth0網(wǎng)卡上。
? ? 這里的網(wǎng)橋概念等同于交換機,為連在其上的設(shè)備轉(zhuǎn)發(fā)數(shù)據(jù)幀。網(wǎng)橋上的veth網(wǎng)卡設(shè)備相當(dāng)于交換機上的端口,可以將多個容器或虛擬機連接在上面,這些端口工作在二層,所以是不需要配置IP信息的。
? ? 圖中docker0網(wǎng)橋就為連在其上的容器轉(zhuǎn)發(fā)數(shù)據(jù)幀,使得同一臺宿主機上的Docker容器之間可以相互通信。
? ? 大家應(yīng)該注意到docker0既然是二層設(shè)備,它上面怎么設(shè)置了IP呢?docker0是普通的linux網(wǎng)橋,它是可以在上面配置IP的,可以認(rèn)為其內(nèi)部有一個可以用于配置IP信息的網(wǎng)卡接口
? ?(如同每一個Open vSwitch網(wǎng)橋都有一個同名的內(nèi)部接口一樣)。在Docker的橋接網(wǎng)絡(luò)模式中,docker0的IP地址作為連于之上的容器的默認(rèn)網(wǎng)關(guān)地址存在。
在Linux中,可以使用brctl命令查看和管理網(wǎng)橋(需要安裝bridge-utils軟件包),比如查看本機上的Linux網(wǎng)橋以及其上的端口:
# yum install bridge-utils
# brctl show? ?//四個虛擬接口
bridge name bridge id STP enabled interfaces docker0 8000.02428f0e6a12 no veth6a95f3bveth6d97324veth7314b3evethb2e752fvethdb62bce更多關(guān)于brctl命令的功能和用法,大家通過man brctl或brctl --help查閱。
? ? docker0網(wǎng)橋是在Docker daemon啟動時自動創(chuàng)建的,其IP默認(rèn)為172.17.0.1/16,之后創(chuàng)建的Docker容器都會在docker0子網(wǎng)的范圍內(nèi)選取一個未占用的IP使用,并連接到docker0網(wǎng)橋上。
? ? 除了使用docker0網(wǎng)橋外,還可以使用自己創(chuàng)建的網(wǎng)橋,比如創(chuàng)建一個名為br0的網(wǎng)橋,配置IP:
# ip link show? ? //veth7314b3e和if8是一對
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000link/ether 00:0c:29:ee:53:1e brd ff:ff:ff:ff:ff:ff 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:8f:0e:6a:12 brd ff:ff:ff:ff:ff:ff 9: veth7314b3e@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 42:a0:eb:96:15:cf brd ff:ff:ff:ff:ff:ff link-netnsid 0 11: vethb2e752f@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 5a:8e:fa:1c:7f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 1 13: veth6d97324@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 4a:2f:07:20:53:15 brd ff:ff:ff:ff:ff:ff link-netnsid 2 17: vethdb62bce@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 8a:1a:78:56:07:d8 brd ff:ff:ff:ff:ff:ff link-netnsid 3 19: veth6a95f3b@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether aa:02:b6:a3:44:87 brd ff:ff:ff:ff:ff:ff link-netnsid 4?
iptables規(guī)則
?Docker安裝完成后,將默認(rèn)在宿主機系統(tǒng)上增加一些iptables規(guī)則,以用于Docker容器和容器之間以及和外界的通信,可以使用iptables-save命令查看。其中nat表中的POSTROUTING鏈有這么一條規(guī)則:
參數(shù)說明:
-s :源地址172.17.0.0/16
-o:指定數(shù)據(jù)報文流出接口為docker0
-j :動作為MASQUERADE(地址偽裝)
?? 上面這條規(guī)則關(guān)系著Docker容器和外界的通信,含義是:將源地址為172.17.0.0/16的數(shù)據(jù)包(即Docker容器發(fā)出的數(shù)據(jù)),當(dāng)不是從docker0網(wǎng)卡發(fā)出時做SNAT。
? ? 這樣一來,從Docker容器訪問外網(wǎng)的流量,在外部看來就是從宿主機上發(fā)出的,外部感覺不到Docker容器的存在。
?? 那么,外界想到訪問Docker容器的服務(wù)時該怎么辦呢?我們啟動一個簡單的web服務(wù)容器,觀察iptables規(guī)則有何變化。
?
OVS:全稱是Open VSwitch,就是一個虛擬交換機,用于虛擬機VM環(huán)境。在虛擬化環(huán)境中,一個虛擬交換機主要有兩個作用:傳遞虛擬機VM之間的通信,以及實現(xiàn)VM和外界網(wǎng)絡(luò)的通信。
OVS主要由以下4層組成:
虛擬網(wǎng)卡:位于虛擬機內(nèi),在虛擬機創(chuàng)建后,會掛載在OVS上,每個虛擬網(wǎng)卡都有不同的MAC地址。
虛擬交換層:通過2個ovs虛擬交換機完成通信。OVS除提供基本網(wǎng)絡(luò)交換外,還提供一些高級功能,如NetFlow等。
bond層:bond是由linux提供的將多個物理網(wǎng)卡綁定在一起的技術(shù),另一種說法叫trunk。Bond模式主要有:負(fù)載平衡、主備模式。目前主要使用的是主備模式,在主備模式下,有一個網(wǎng)卡是主用狀態(tài),其它網(wǎng)卡均是備用狀態(tài)。這一層是可選的,如果沒有這一層,物理網(wǎng)卡可以直接掛在ovs上。
物理網(wǎng)卡:真正執(zhí)行收發(fā)包的物理設(shè)備,一般都會掛載在trunk上,常見的物理網(wǎng)卡有Intel 82599 10G網(wǎng)卡、Intel 82576 1G網(wǎng)卡、Intel I350 1G網(wǎng)卡、SIGMA mellanox 10G網(wǎng)卡。
按照這樣的解釋,應(yīng)該就比較清楚了。
OVS與傳統(tǒng)的硬件交換機工作原理也沒什么區(qū)別,就是基于MAC地址實現(xiàn)報文的交換。
host? ?https://blog.csdn.net/wangguohe/article/details/81535942
容器不會獲得一個獨立的network namespace,而是與宿主機共用一個。
在容器中使用ifconfig查看網(wǎng)絡(luò)發(fā)現(xiàn)顯示的是宿主機的網(wǎng)絡(luò)
host
父進程在創(chuàng)建子進程時,如果不使用```CLONE_NEWNET```這個參數(shù)標(biāo)志,那么創(chuàng)建出的子進程會與父 進程共享同一個網(wǎng)絡(luò)namespace。
Docker就是采用了這個簡單的原理,在創(chuàng)建進程啟動容器的過程中,沒有傳入CLONE_NEWNET參數(shù)標(biāo)志,實現(xiàn)Docker Container與宿主機共享同一個網(wǎng)絡(luò)環(huán)境,即實現(xiàn)host網(wǎng)絡(luò)模式。
優(yōu)勢:
- 可以直接使用宿主機的IP地址與外界進行通信,若宿主機的eth0是一個公有IP,那么容器也擁有這個公有IP。
- 同時容器內(nèi)服務(wù)的端口也可以使用宿主機的端口,無需額外進行NAT轉(zhuǎn)換。
缺陷:
- 最明顯的是Docker Container網(wǎng)絡(luò)環(huán)境隔離性的弱化,即容器不再擁有隔離、獨立的網(wǎng)絡(luò)棧。
- 使用host模式的Docker Container雖然可以讓容器內(nèi)部的服務(wù)和傳統(tǒng)情況無差別、無改造的使用,但是由于網(wǎng)絡(luò)隔離性的弱化,該容器會與宿主機共享競爭網(wǎng)絡(luò)棧的使用;
- 容器內(nèi)部將不再擁有所有的端口資源,原因是部分端口資源已經(jīng)被宿主機本身的服務(wù)占用,還有部分端口已經(jīng)用以bridge網(wǎng)絡(luò)模式容器的端口映射。
none
獲取獨立的network namespace,但不為容器進行任何網(wǎng)絡(luò)配置,之后用戶可以自己進行配置,容器內(nèi)部只能使用loopback網(wǎng)絡(luò)設(shè)備,不會再有其他的網(wǎng)絡(luò)資源。
創(chuàng)建docker網(wǎng)絡(luò)
# docker network ls
NETWORK ID NAME DRIVER SCOPE 5ebae7e509fa bridge bridge local //默認(rèn)網(wǎng)絡(luò) b255b50dc21e host host local db26f5263d07 none null local# docker container run --help
?--network string? ? ? ? ? ? ? ? ?Connect a container to a network (default "default")? ?//string指明要使用哪個網(wǎng)絡(luò),默認(rèn)是bridge
# docker network inspect bridge? ? //查看bridge的信息
# docker container inspect web1? ?//查看容器web1的詳細(xì)信息
?
轉(zhuǎn)載于:https://www.cnblogs.com/hanshanxiaoheshang/p/10397966.html
總結(jié)
以上是生活随笔為你收集整理的4、容器虚拟化网络概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Takeown--夺取文件or文件夹所有
- 下一篇: 番茄工作软件介绍