1、網絡虛擬化技術介紹php
一、什麼是虛擬化網絡
mysql
虛擬化網絡即由linux內核所虛擬出來的網絡,事實上,linux內核可模擬多種網絡設備
linux
可模擬網線設備:模擬的網線設備是成對出現的,一個可用在容器內,一端用在交換機內sql
可模擬交換機:容器接在這個交換機上,若是IP在同一網段,就能夠實現互相通訊,以下docker
網絡虛擬化的解決方案有不少,例如:apache
OVSbash
SDN網絡
在物理機上能夠有多個虛擬交換機,容器能夠分別接在不一樣的虛擬交換機上,若是兩個虛擬交換機不在同一個網段,那麼如何進行通訊呢?ide
此時須要進行轉發oop
可藉助於內核轉發
也能夠藉助於iptables轉發
二、如何實現兩個物理機上的容器怎麼通訊?
方法1:是橋接模式(好比vmware的橋接)
橋接模式狀況下,物理網卡會做爲交換機來使用的
全部虛擬機都接入到這個物理網卡所模擬的交換機
而後在模擬出來一個網卡給物理機使用,這個模擬的網卡也接入到交換機上
當有數據包過來的時候,物理機網絡會判斷目標mac
若是是vm1,就將這個數據包轉發到vm1
若是是物理機本身的mac地址,那就就將這個報文轉發給內部虛擬的網卡
不一樣主機上的容器,能夠用橋接的方式來實現通訊,就是將物理網卡做爲交換機
注意:
橋接模式,代價是很大的,尤爲在一個大規模部署的場景中,這樣作的結果就必定會致使網絡中的主機過多,致使風暴。
方法2:NAT模式
在nat模式場景下,每一個容器都仍是接入在一個虛擬交換機,而且容器的網關須要指向這個交換機的地址,
當容器產生數據包的時候,這個數據就會發送到虛擬機換機上
虛擬交換機是由內核模擬的是,因此這個數據包會被內核收到
內核就會檢查發現目標主機是否是本身,若是不是本身,那麼就會將這個數據包從網卡發送出去,這樣就完成了數據的發送。
注意:此時的問題問題是雖然能將數據發送出去,可是回不來
由於C所發送出去的數據包的源地址是C1,而這個地址被交換機隱藏起來的是,網絡中的其餘主機是找不到這個地址的,因此,回不來。
若是想讓數據能夠正常的回覆,就須要在H1主機上,在發送數據包的時候,將數據包的源地址修改爲H1主機的地址,同時記錄下來這個轉發規則。
這樣,當回覆數據的時候,只須要將數據回覆給H1主機,H1主機經過檢查地址轉換表,就知道了須要將這個數據包轉發給C1了。
以上兩種方式都存在各自的問題
橋接方式:容器須要直接暴露在網絡中,容器太多的時候,容器造成風暴
NAT方式:容器基於nat進行通訊,並且須要進行兩次地址轉換,效率過低
方法3:疊加網絡(Overlay network),這種網絡是基於隧道模式實現的
隧道模式下,也須要模擬一個交換機,並且容器也是接在交換機上,以下圖
此時在進行數據發送的時候,不會修改數據包的源IP 源mac,而是在會原來數據包的基礎上再封裝一層ip和mac
2、Docker網絡詳解
一、Docker的三種網絡
[root@host1 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 591c75b7dbea bridge bridge local 386d8dc4beb8 host host local eb7b7cf29f29 none null local
二、bridge就是橋接模式
這個橋並非物理網卡的橋,而是建立了一個純軟件的交換機叫作docker0
能夠用ip addr或者ip link show看到
[root@host1 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 ... 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 ... 3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 ... 4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:a4:e8:44:11 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever
[root@host1 ~]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/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 1000 link/ether 00:0c:29:3f:bf:cf brd ff:ff:ff:ff:ff:ff 3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:3f:bf:d9 brd ff:ff:ff:ff:ff:ff 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:a4:e8:44:11 brd ff:ff:ff:ff:ff:ff 6: veth7c1728b@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 9a:be:3b:60:d7:2e brd ff:ff:ff:ff:ff:ff link-netnsid 0
啓動一個容器
[root@host1 ~]# docker run --rm --name vh1 -it busybox / #
此時物理機會多出一個網卡設備
[root@host1 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 ... 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 ... 3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 ... 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:a4:e8:44:11 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:a4ff:fee8:4411/64 scope link valid_lft forever preferred_lft forever 6: veth7c1728b@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 9a:be:3b:60:d7:2e brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::98be:3bff:fe60:d72e/64 scope link valid_lft forever preferred_lft forever
這個 veth7c1728b@if5 其實就是所生成的一對網卡中,鏈接到docker0網橋上的那一部分
也就是能夠理解三個容器將網線插入到了交換機上
網卡中 @ 前面的部分是接入到虛擬機交換機中的部分
網卡中 @ 後面的部分是容器的部分了
在容器中看一下網卡信息
/ # ip addr
能夠經過brctl開控制和查看物理機網卡和容器網卡的對應關係
[root@host1 ~]# yum install bridge-utils -y [root@host1 ~]# brctl show bridge namebridge idSTP enabledinterfaces docker08000.0242a4e84411noveth7c1728b
其實在使用了Docker0網橋的時候,系統是會自動生成一個iptables規則的【POSTROUNTING規則】
[root@host1 ~]# iptables -L -n --line -t nat Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination 1 DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 1 MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 Chain DOCKER (2 references) num target prot opt source destination 1 RETURN all -- 0.0.0.0/0 0.0.0.0/0
docker的客戶端來源有三種
宿主機:例如在宿主機上訪問容器中的網站
同一宿主機上的其餘容器:兩個容器接在同一個物理機的同一個交換機上,必然能夠通訊
其餘宿主機或者其餘宿主機上的容器:這種狀況下須要經過nat方式或者疊加網絡的方式通訊
三、host模式
一個容器中要隔離6類名稱空間
user
mount
pid
uts
net
ipc
思考:有三個容器,這個三個容器只隔離三個名稱空間 user mount pid,而另外三個是容器共享的,會是什麼現象,以下圖
此時,各個容器有本身文件系統、用戶信息和進程信息,而且是互不干擾的
可是多個容器的主機名、網卡、協議棧是共享的,也就是主機名、地址都是相同的
這樣一來,一個容器訪問另外一個容器的上的資源的時候,直接用12.0.0.1就能夠了
好比一個容器安裝的apache,一個安裝了mysql,一個安裝了php,那麼這三個主機互相通訊,就徹底能夠基於127地址來完成,由於他們用的是同一個協議棧。
讓容器共享物理機的名稱空間
容器共享物理機的網卡名稱空間,這樣的話就是若是在容器中修改網卡,那麼就會修改物理機的網卡的。
這種模式就是docker 網絡中的第二類:host,也就是讓容器使用宿主機的網絡名稱空間
四、NULL模式
docker 網絡中的第三類:null
若是一個容器的的網絡設置成null網絡,那麼也就是說這個容器是沒有網絡,有的時候須要建立一個容器不須要和外部主機通訊,那麼就能夠用這種方式。
五、容器模型分類示意圖
關閉模型容器(closed)
橋解模型容器(bridged),這個橋是nat橋,不是物理橋,並且該模式是默認模式
聯盟模型容器(joined)
開放模型容器(open)
六、查看建立容器的時網絡信息
查看一下 bridged 網絡模型信息
[root@host1 ~]# docker network inspect bridge ... ... "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" ... ... ... "com.docker.network.bridge.name": "docker0", ...
查看容器的網絡類型
[root@host1 ~]# docker container inspect vh1 ... ... ... "NetworkSettings": { "Bridge": "", ... ... ...