Docker系列4:Docker網絡虛擬化基礎

1、網絡虛擬化技術介紹php

一、什麼是虛擬化網絡
mysql

虛擬化網絡即由linux內核所虛擬出來的網絡,事實上,linux內核可模擬多種網絡設備
linux

  • 可模擬網線設備:模擬的網線設備是成對出現的,一個可用在容器內,一端用在交換機內sql

  • 可模擬交換機:容器接在這個交換機上,若是IP在同一網段,就能夠實現互相通訊,以下docker

    image.png

網絡虛擬化的解決方案有不少,例如:apache

  • OVSbash

  • SDN網絡

在物理機上能夠有多個虛擬交換機,容器能夠分別接在不一樣的虛擬交換機上,若是兩個虛擬交換機不在同一個網段,那麼如何進行通訊呢?ide

    image.png 

此時須要進行轉發oop

    image.png

  • 可藉助於內核轉發

  • 也能夠藉助於iptables轉發

二、如何實現兩個物理機上的容器怎麼通訊?

方法1:是橋接模式(好比vmware的橋接)

  • 橋接模式狀況下,物理網卡會做爲交換機來使用的

  • 全部虛擬機都接入到這個物理網卡所模擬的交換機

  • 而後在模擬出來一個網卡給物理機使用,這個模擬的網卡也接入到交換機上

    image.png

當有數據包過來的時候,物理機網絡會判斷目標mac

  • 若是是vm1,就將這個數據包轉發到vm1

  • 若是是物理機本身的mac地址,那就就將這個報文轉發給內部虛擬的網卡

  • 不一樣主機上的容器,能夠用橋接的方式來實現通訊,就是將物理網卡做爲交換機

    image.png

注意:

  • 橋接模式,代價是很大的,尤爲在一個大規模部署的場景中,這樣作的結果就必定會致使網絡中的主機過多,致使風暴。

方法2:NAT模式

  • 在nat模式場景下,每一個容器都仍是接入在一個虛擬交換機,而且容器的網關須要指向這個交換機的地址,

  • 當容器產生數據包的時候,這個數據就會發送到虛擬機換機上

  • 虛擬交換機是由內核模擬的是,因此這個數據包會被內核收到

  • 內核就會檢查發現目標主機是否是本身,若是不是本身,那麼就會將這個數據包從網卡發送出去,這樣就完成了數據的發送。

    image.png

注意:此時的問題問題是雖然能將數據發送出去,可是回不來

  • 由於C所發送出去的數據包的源地址是C1,而這個地址被交換機隱藏起來的是,網絡中的其餘主機是找不到這個地址的,因此,回不來。

  • 若是想讓數據能夠正常的回覆,就須要在H1主機上,在發送數據包的時候,將數據包的源地址修改爲H1主機的地址,同時記錄下來這個轉發規則。

  • 這樣,當回覆數據的時候,只須要將數據回覆給H1主機,H1主機經過檢查地址轉換表,就知道了須要將這個數據包轉發給C1了。

以上兩種方式都存在各自的問題

  • 橋接方式:容器須要直接暴露在網絡中,容器太多的時候,容器造成風暴

  • NAT方式:容器基於nat進行通訊,並且須要進行兩次地址轉換,效率過低

方法3:疊加網絡(Overlay network),這種網絡是基於隧道模式實現的

  • 隧道模式下,也須要模擬一個交換機,並且容器也是接在交換機上,以下圖

    image.png

  • 此時在進行數據發送的時候,不會修改數據包的源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,而另外三個是容器共享的,會是什麼現象,以下圖

    image.png

  • 此時,各個容器有本身文件系統、用戶信息和進程信息,而且是互不干擾的

  • 可是多個容器的主機名、網卡、協議棧是共享的,也就是主機名、地址都是相同的

  • 這樣一來,一個容器訪問另外一個容器的上的資源的時候,直接用12.0.0.1就能夠了

  • 好比一個容器安裝的apache,一個安裝了mysql,一個安裝了php,那麼這三個主機互相通訊,就徹底能夠基於127地址來完成,由於他們用的是同一個協議棧。

讓容器共享物理機的名稱空間

  • 容器共享物理機的網卡名稱空間,這樣的話就是若是在容器中修改網卡,那麼就會修改物理機的網卡的。

  • 這種模式就是docker 網絡中的第二類:host,也就是讓容器使用宿主機的網絡名稱空間

四、NULL模式

  • docker 網絡中的第三類:null

  • 若是一個容器的的網絡設置成null網絡,那麼也就是說這個容器是沒有網絡,有的時候須要建立一個容器不須要和外部主機通訊,那麼就能夠用這種方式。

五、容器模型分類示意圖

  image.png

  • 關閉模型容器(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": "",
        ...
        ...
        ...
相關文章
相關標籤/搜索