Docker五種網絡管理

docker五種網絡管理目錄.png

1、有哪五種模式網絡:

docker的網絡模式大體能夠分紅五種類型:python

  • 默認是bridge模式網絡 使用–net =bridge指定,默認網絡驅動程序。當你的應用程序在須要通訊的獨立容器中運行時,一般會使用橋接網絡。linux

  • host模式網絡 使用–net =host指定,對於獨立容器,刪除容器和Docker主機之間的網絡隔離,並直接使用主機的網絡nginx

  • none模式網絡 使用–net =none指定,對於此容器,禁用全部網絡 另外兩種:docker

  • container模式網絡 使用–net =container:指定容器名,能夠多個容器共用一個網絡ubuntu

  • user-defined模式網絡:centos

    • overlay模式網絡 使用--net=overlay,覆蓋網絡將多個Docker守護程序鏈接在一塊兒,並使羣集服務可以相互通訊。還可使用覆蓋網絡來促進羣集服務和獨立容器之間的通訊,或者在不一樣Docker守護程序上的兩個獨立容器之間進行通訊
    • macvlan:Macvlan網絡容許您爲容器分配MAC地址,使其顯示爲網絡上的物理設備。Docker守護程序經過其MAC地址將流量路由到容器。macvlan 在處理指望直接鏈接到物理網絡的傳統應用程序時,使用驅動程序有時是最佳選擇,而不是經過Docker主機的網絡堆疊進行路由

在安裝完docker以後,宿主機上會建立三個網絡: 默認docker主機會存在三種類型的網絡,可使用docker network ls命令查看安全

[root@VM_0_6_centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f88b1c490d20        bridge              bridge              local
0954ad9627bc        host                host                local
7dbe186a84e8        none                null                local

複製代碼

1.bridge模式網絡

容器的默認網絡模式,docker在安裝時會建立一個名爲docker0的Linux bridge,在不指定--network的狀況下,建立的容器都會默認掛到docker0上面

在該模式(見下圖)中,Docker守護進程建立了一個虛擬以太網橋`docker0`,附加在其上的任何網卡之間都能自動轉發數據包。默認狀況下,守護進程會建立一對對等接口,將其中一個接口設置爲容器的eth0接口,另外一個接口放置在宿主機的命名空間中,從而將宿主機上的全部容器都鏈接到這個內部網絡上。同時,守護進程還會從網橋的私有地址空間中分配一個IP地址和子網給該容器
複製代碼

1.1 如,docker主機會有一個默認使用的橋接網卡bridge0,它是在運行docker容器時,若是不指定網絡,默認使用的網絡:docker0bash

[root@VM_0_6_centos ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe69:660/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:74:13:f5:ff 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:74ff:fe13:f5ff/64 scope link 
       valid_lft forever preferred_lft forever
複製代碼

1.2 當運行一個容器時,咱們能夠看到在docker主機上多了一個網卡(vethd579570@if38),並且master指向docker0網絡

[root@VM_0_6_centos ~]# docker run -d -P --net=bridge nginx:1.9.1
59abbf7dbeedf974349fd971970300e311d4ff56aef7e17f8071ec84e8b8e795
[root@VM_0_6_centos ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe69:660/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:74:13:f5:ff 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:74ff:fe13:f5ff/64 scope link 
       valid_lft forever preferred_lft forever
39: vethd579570@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 7e:79:90:55:97:1d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::7c79:90ff:fe55:971d/64 scope link 
       valid_lft forever preferred_lft forever
複製代碼
由於bridge模式是Docker的默認設置,因此你也可使用`docker run -d -P nginx:1.9.1`。若是你沒有使用-P(發佈該容器暴露的全部端口)或者-p
host_port:container_port(發佈某個特定端口),IP數據包就不能從宿主機以外路由到容器中。
複製代碼

1.3 這時候咱們在查看該容器的網絡信息(ip地址和網關)。發現它的ip地址和docker0一個網段,網關則是docker0的地址架構

[root@VM_0_6_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
59abbf7dbeed        nginx:1.9.1         "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:32771->80/tcp, 0.0.0.0:32770->443/tcp   competent_cori
[root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} 59abbf7dbeed
172.17.0.2
[root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} 59abbf7dbeed
172.17.0.1
複製代碼

1.4 bridge網絡的特色

使用一個 linux bridge,默認爲 docker0
使用veth 對,一頭在容器的網絡 namespace中,一頭在docker0上
該模式下Docker Container不具備一個公有IP,由於宿主機的IP地址與veth pair的IP地址不在同一個網段內
Docker採用NAT方式,將容器內部的服務監聽的端口與宿主機的某一個端口進行「綁定」,使得宿主機之外的世界能夠主動將網絡報文發送至容器內部
外界訪問容器內的服務時,須要訪問宿主機的 IP 以及宿主機的端口 port
NAT 模式因爲是在三層網絡上的實現手段,故確定會影響網絡的傳輸效率。
容器擁有獨立、隔離的網絡棧;讓容器和宿主機之外的世界經過NAT創建通訊
複製代碼

咱們查看iptables的nat表,能夠看到,在POSTROUTING鏈上作了一個MASQUERADE,源是172.17.0.0/1

2.host模式網絡

該模式將禁用Docker容器的網絡隔離。由於容器共享了宿主機的網絡命名空間,直接暴露在公共網絡中。所以,你須要經過端口映射(port mapping)來進行協調。

經過命令--network=host指定,使用host模式的容器能夠直接使用docker host的IP地址與外界通訊,容器內部的服務端口也可使用宿主機的端口,不須要進行NAT,host最大的優點就是網絡性能比較好,可是docker host上已經使用的端口就不能再用了,網絡的隔離性很差

2.1 Host模式並無爲容器建立一個隔離的網絡環境。該模式下的Docker容器會和host宿主機共享同一個網絡namespace,因此容器能夠和宿 主機同樣,使用宿主機的eth0,實現和外界的通訊。

特色:

這種模式下的容器沒有隔離的network namespace
容器的IP地址同 Docker主機的IP地址
須要注意容器中服務的端口號不能與Docker主機上已經使用的端口號相沖突
host模式可以和其它模式共存
複製代碼

2.2 首先我經過ss查看一下,個人docker主機80端口並無使用。當我啓動一個提供nginx應用的容器時,在查看發現個人主機使用了80端口

[root@VM_0_6_centos ~]# ss -lnt |grep 80
[root@VM_0_6_centos ~]# docker run -itd --privileged --name nginx001 --network host nginx:latest
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f5d23c7fed46: Already exists 
918b255d86e5: Pull complete 
8c0120a6f561: Pull complete 
Digest: sha256:eb3320e2f9ca409b7c0aa71aea3cf7ce7d018f03a372564dbdb023646958770b
Status: Downloaded newer image for nginx:latest
c7ea10aa92dd09b312f844aa70a359861c8da8d4eea2bbae2353505008beea27
[root@VM_0_6_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
c7ea10aa92dd        nginx:latest        "nginx -g 'daemon of…"   About a minute ago   Up About a minute                                                   nginx001
[root@VM_0_6_centos ~]# ss -lnt |grep 80
LISTEN     0      128          *:80                       *:*                  
複製代碼

2.3 咱們還能夠經過docker inspect nginx001查看它的網絡信息。發現IP地址和網關處根本沒有值。由於使用了host網絡,它是共用了docker主機的網絡

[rootVM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} nginx001
<no value>
[root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} nginx001
<no value>
複製代碼

2.4 再例如:

[root@VM_0_6_centos ~]# docker run -d --net=host ubuntu:14.04 tail -f /dev/null
Unable to find image 'ubuntu:14.04' locally
14.04: Pulling from library/ubuntu
a7344f52cb74: Pull complete 
515c9bb51536: Pull complete 
e1eabe0537eb: Pull complete 
4701f1215c13: Pull complete 
Digest: sha256:2f7c79927b346e436cc14c92bd4e5bd778c3bd7037f35bc639ac1589a7acfa90
Status: Downloaded newer image for ubuntu:14.04
cb5860bbcf61d006c9654cb4678fe3a2b9cb93c2f09cc84da142113d245b6e83
[root@VM_0_6_centos ~]# ip addr | grep -A 2 eth0:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0

[root@VM_0_6_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
cb5860bbcf61        ubuntu:14.04        "tail -f /dev/null"      About a minute ago   Up 59 seconds                                                       hungry_payne
[root@VM_0_6_centos ~]# docker exec -it cb5860bbcf61 ip addr
inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0

複製代碼

咱們能夠從上例中看到:容器和宿主機具備相同的IP地址172.16.0.6

在下圖中,咱們能夠看到:當使用host模式網絡時,容器實際上繼承了宿主機的IP地址。該模式比bridge模式更快(由於沒有路由開銷),可是它將容器直接暴露在公共網絡中,是有安全隱患的

3.none模式網絡

這種網絡模式下容器只有lo迴環網絡,沒有其餘網卡。none網絡能夠在容器建立時經過--network=none來指定。這種類型的網絡沒有辦法聯網,封閉的網絡能很好的保證容器的安全性。一旦 Docker Container 採用了none網絡模式,那麼容器內部就只能使用 loopback 網絡設備,不會再有其餘的網絡資源。在沒有網絡配置的狀況下,做爲 Docker 開發者,才能在這基礎作其餘無限多可能的網絡定製開發。

3.1 在 none 網絡模式下分配固定 ip: netns 是在 linux 中提供網絡虛擬化的一個項目,使用 netns 網絡空間虛擬化能夠在本地虛擬化出多個網絡環境,目前 netns 在 lxc 容器中被用來爲容器提供網絡。使用 netns 建立的網絡空間獨立於當前系統的網絡空間,其中的網絡設備以及 iptables 規則等都是獨立的,就好像進入了另一個網絡同樣

[root@VM_0_6_centos ~]# docker run -it --name vm5 --net none ubuntu

複製代碼

3.2 這種方式建立沒有網絡,能夠本身指定設置網絡

[root@VM_0_6_centos ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
複製代碼

4.container模式網絡 共享模式

用於容器和容器直接頻繁交流的狀況。

這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立本身的網卡,配置本身的 IP,而是和一個指定的容器共享 IP、端口範圍等。一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過 lo 網卡設備通訊。

建立容器時使用--network=container:NAME_or_ID這個模式在建立新的容器的時候指定容器的網絡和一個已經存在的容器共享一個Network Namespace,可是並不爲docker容器進行任何網絡配置,這個docker容器沒有網卡、IP、路由等信息,須要手動的去爲docker容器添加網卡、配置IP等

(1) 查找 other container(即須要被共享網絡環境的容器)的網絡 namespace; (2) 將新建立的 Docker Container(也是須要共享其餘網絡的容器)的 namespace,使用 other container 的 namespace。 Docker Container 的 other container 網絡模式,能夠用來更好的服務於容器間的通訊。 在這種模式下的 Docker Container 能夠經過 localhost 來訪問 namespace 下的其餘容器,傳輸 效率較高。雖然多個容器共享網絡環境,可是多個容器造成的總體依然與宿主機以及其餘 容器造成網絡隔離。另外,這種模式還節約了必定數量的網絡資源。可是須要注意的是,

它並無改善容器與宿主機之外世界通訊的狀況

4.1 建立一個nat模式,看一下這個容器ip:

[root@VM_0_6_centos ~]# docker run -it --name busyboxl busybox sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
34: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # hostname
d9e5c9ad1193
/ # 
複製代碼

4.2 建立一個container網絡模式的ip,建立完成後,能夠看到這兩個ip地址是如出一轍的,而且是能夠直接通訊的

[root@VM_0_6_centos ~]# docker run -it --name busybox2 --net=container:busybox1 busybox sh
docker: Error response from daemon: cannot join network of a non running container: 4d33b98101f85aa77e576967c64d8b83b535f99d22d82a89bdd62b15f3f96070.
[root@VM_0_6_centos ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe69:660/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:74:13:f5:ff 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:74ff:fe13:f5ff/64 scope link 
       valid_lft forever preferred_lft forever
複製代碼

4.3 確認是兩個容器:

[root@VM_0_6_centos ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
1af412b5e1d7        busybox             "sh"                58 seconds ago      Created                                             busybox2
4d33b98101f8        busybox             "sh"                2 minutes ago       Exited (0) About a minute ago                       busybox1
複製代碼

4.4 None,不會建立網絡,裏面就不會有ip,最經常使用的是nat模式和container網絡模式,container網絡模式用於容器和容器直接頻繁交流的狀況。

[root@VM_0_6_centos ~]# docker run -it --name none --net=none busybox sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
/ # 
複製代碼

5.user-defined模式

用戶自定義模式主要可選的有三種網絡驅動:bridge、overlay、macvlan。bridge驅動用於建立相似於前面提到的bridge網絡;overlay和macvlan驅動用於建立跨主機的網絡。

2、外部網絡訪問容器內應用

1.-P隨機指定一個docker主機端口給容器中的端口作映射

[root@VM_0_6_centos ~]# docker run -itd -P --name nginx001 nginx:latest
b718bc214f766d154b0608819edac97da066e1edbf1617125d4b707ac4b5c6e4
[root@VM_0_6_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
b718bc214f76        nginx:latest        "nginx -g 'daemon of…"   8 seconds ago       Up 7 seconds        0.0.0.0:32772->80/tcp   nginx001
[root@VM_0_6_centos ~]# 
複製代碼

2.-p將docker主機的一個端口映射容器的一個端口

[root@VM_0_6_centos ~]# docker run -itd -p 8000:80 --name nginx002 nginx:latest
bb4cce60ff9da6c7e57d24f0a4d63921925e8990a3172c613d25865eb8b8ab50

[root@VM_0_6_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
bb4cce60ff9d        nginx:latest        "nginx -g 'daemon of…"   13 seconds ago      Up 13 seconds       0.0.0.0:8000->80/tcp    nginx002
b718bc214f76        nginx:latest        "nginx -g 'daemon of…"   2 minutes ago       Up 2 minutes        0.0.0.0:32772->80/tcp   nginx001
[root@VM_0_6_centos ~]# 
複製代碼

訪問網站測試(個人docker主機的地址爲129.204.207.***,記住要在docker主機上放行32772和8000端口)

首先訪問32768端口:129.204.207.***:32772 訪問8000端口。(均可以正常提供服務)

3、用戶自定義網絡

經過docker network create --driver network_type network_name命令便可建立自定義網絡。其中--driver後面支持的類型有三種:bridge、macvlan、overlay

[root@VM_0_6_centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f88b1c490d20        bridge              bridge              local
0954ad9627bc        host                host                local
7dbe186a84e8        none                null                local

[root@VM_0_6_centos ~]# ip a

[root@VM_0_6_centos ~]# docker network create --driver bridge my_bridge
326493de5458416e3a1ccbceea5e03760268ae3412c9fe78fe551dadbfc53c95

[root@VM_0_6_centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f88b1c490d20        bridge              bridge              local
0954ad9627bc        host                host                local
326493de5458        my_bridge           bridge              local
7dbe186a84e8        none                null                local
[root@VM_0_6_centos ~]# ip a

複製代碼

經過docker network inspect network_name能夠查看該網絡的信息

[root@VM_0_6_centos ~]# docker network inspect my_bridge
[
    {
        "Name": "my_bridge",
        "Id": "326493de5458416e3a1ccbceea5e03760268ae3412c9fe78fe551dadbfc53c95",
        "Created": "2019-08-06T15:16:08.50367479+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
複製代碼

並且經過ip addr能夠看到自動在docker主機上建立了一個網卡

[root@VM_0_6_centos ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe69:660/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:74:13:f5:ff 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:74ff:fe13:f5ff/64 scope link 
       valid_lft forever preferred_lft forever
41: vethd9e30c6@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ca:e9:0a:6d:c6:09 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c8e9:aff:fe6d:c609/64 scope link 
       valid_lft forever preferred_lft forever
43: veth2946b2c@if42: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:65:c5:d4:31:e6 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::65:c5ff:fed4:31e6/64 scope link 
       valid_lft forever preferred_lft forever
44: br-326493de5458: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:00:7c:2f:07 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-326493de5458
       valid_lft forever preferred_lft forever

複製代碼

查看主機的 NAT 規則: 再次查看咱們nat表,也能夠看到在POSTROUTING上作的MASQUERADE

[root@VM_0_6_centos ~]# iptables -t nat -vnL
Chain POSTROUTING (policy ACCEPT 198 packets, 12868 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !br-326493de5458  172.18.0.0/16        0.0.0.0/0 
複製代碼

這樣咱們就能夠運行容器使用該網絡了

[root@VM_0_6_centos ~]# docker run -itd --name=nginx001 --network my_bridge nginx
0200f80a916ad188be333232d8eed64c87f19b4c9229c948bc6de1376bd76125
[root@VM_0_6_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
0200f80a916a        nginx               "nginx -g 'daemon of…"   6 seconds ago       Up 5 seconds        80/tcp              nginx001
[root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} nginx001
172.18.0.1
[root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} nginx001
172.18.0.2
複製代碼

4、docker network管理命令的使用

1.基本使用:

# 建立一個網絡
[root@VM_0_6_centos ~]# docker network create --driver bridge bridge_1
b3a6a2b1063dcca0e6dd26d92c60fbb0dc7ba8bf5b55dff9fb10849343d28b0d

# 查看全部網絡
[root@VM_0_6_centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f88b1c490d20        bridge              bridge              local
b3a6a2b1063d        bridge_1            bridge              local
0954ad9627bc        host                host                local
326493de5458        my_bridge           bridge              local
7dbe186a84e8        none                null                local

# 斷開一個網路的鏈接
[root@VM_0_6_centos ~]# docker network disconnect bridge_1
"docker network disconnect" requires exactly 2 arguments.
See 'docker network disconnect --help'.

Usage:  docker network disconnect [OPTIONS] NETWORK CONTAINER

Disconnect a container from a network

#鏈接一個網絡
[root@VM_0_6_centos ~]# docker network connect bridge_1
"docker network connect" requires exactly 2 arguments.
See 'docker network connect --help'.

Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

# 刪除一個網絡
[root@VM_0_6_centos ~]# docker network rm bridge_1
bridge_1

# 查看全部網絡
[root@VM_0_6_centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f88b1c490d20        bridge              bridge              local
0954ad9627bc        host                host                local
326493de5458        my_bridge           bridge              local
7dbe186a84e8        none                null                local
[root@VM_0_6_centos ~]# 
複製代碼

2.顯示一個網絡的信息:

[root@VM_0_6_centos ~]# docker inspect host
[
    {
        "Name": "host",
        "Id": "0954ad9627bc02e971eb92c9f625dced9c86d994d09217d5fbc609aa4efc608d",
        "Created": "2019-07-30T18:03:34.674156886+08:00",
        "Scope": "local",
        "Driver": "host",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": []
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

複製代碼

5、跨主機docker容器通訊方案介紹

1.基於實現方式的分類

隧道方案(Overlay Networking):
Weave:UDP廣播,本機創建新的BR,經過PCAP互通。
Open vSwitch(OVS):基於VxLAN和GRE協議,可是性能方面損失比較嚴重。
Flannel:UDP廣播,VxLan。
複製代碼
路由方案:
Calico:基於BGP協議的路由方案,支持很細緻的ACL控制,對混合雲親和度比較
高。
Macvlan:從邏輯和Kernel層來看隔離性和性能最優的方案,基於二層隔離,因此
須要二層路由器支持,大多數雲服務商不支持,因此混合雲上比較難以實現。
複製代碼

2.基於網絡模型分類

Docker Libnetwork Container Network Model(CNM):
Docker Swarm overlay
Macvlan & IP network drivers
Calico
Contiv(from Cisco)
##Docker Libnetwork的優點就是原生,並且和Docker容器生命週期結合緊密;缺點也能夠理解爲是原生,被Docker「綁架」。
複製代碼
Container Network Interface(CNI):
Kubernetes
Weave
Macvlan
Flannel
Calico
Contiv
Mesos CNI
##CNI的優點是兼容其餘容器技術(e.g. rkt)及上層編排系統(Kuberneres & Mesos),並且社區活
躍勢頭迅猛,Kubernetes加上CoreOS主推;缺點是非Docker原生。
複製代碼

3.以Flannel方案爲例

Flannel以前的名字是Rudder,它是由CoreOS團隊針對Kubernetes設計的一個重載網絡工具,它的主要思路是:預先留出一個網段,每一個主機使用其中一部分,而後每一個容器被分配不一樣的ip;讓全部的容器認爲你們在同一個直連的網絡,底層經過UDP/VxLAN等進行報文的封裝和轉發。 下面這張是Flannel網絡的經典架構圖(從網上找的)

Flannel網絡1.png

1. 容器直接使用目標容器的ip訪問,默認經過容器內部的eth0發送出去。 
2. 報文經過veth pair被髮送到vethXXX。 
3. vethXXX是直接鏈接到虛擬交換機docker0的,報文經過虛擬bridge docker0發送出去。 
4. 查找路由表,外部容器ip的報文都會轉發到flannel0虛擬網卡,這是一個P2P的虛擬網卡,而後報文就被轉發到監聽在另外一端的flanneld。 
5. flanneld經過etcd維護了各個節點之間的路由表,把原來的報文UDP封裝一層,經過配置的iface發送出去。 
6. 報文經過主機之間的網絡找到目標主機。 
7. 報文繼續往上,到傳輸層,交給監聽在8285端口的flanneld程序處理。 
8. 數據被解包,而後發送給flannel0虛擬網卡。 
9. 查找路由表,發現對應容器的報文要交給docker0。 
10. docker0找到連到本身的容器,把報文發送過去。
複製代碼
相關文章
相關標籤/搜索