單一docker主機網路

大牛不會太遙遠發表於2018-06-06

一. 容器網路模型:

Docker定義了一個非常簡單的網路模型,叫做container network model(CNM).如下圖所示:

單一docker主機網路

CNM模型有三個元素—sandbox, endpoint, 和network

  • sandbox:不允許從外面的網路連線到容器,實現了完美的隔離功能。
  • Endpoint: 終端節點可以認為是network到sandbox中間的一個節點,可以想像成是到容器的一個門。
  • network: 是終端和終端之間進行通訊的保障。也是一個特別重要的元件。

下圖描述了容器網路常見的幾種方式和作用範圍:


Network Company Scope Description
Bridge Docker local Simple network based on Linux bridges allowing networking on a single host
Macvlan Docker Local

Configures multiple layer 2(that is, MAC) addresses on a single physical host interface

Overlay Docker Global Multinode-capable container network based on Virtual Extensible LAN(VXLan)
Weave Net Weaveworks Global Simple, resilient, multihost Docker networking
Contiv Network Plugin Cisco Global Open source container networking

二. The bridge network

1. 建立bridge

(1) 檢查bridge資訊

[root@c720120 ~]# docker network inspect bridge
[
     {
         “Name”: “bridge”,
         “Id”: “8d4ce133354ba6e3ab01684cf18b88535230647e78a6d698f1ef8d79f767b169”,
         “Created”: “2018-05-29T22:57:29.986412028+08:00”,
         “Scope”: “local”,
         “Driver”: “bridge”,
         “EnableIPv6”: false,
         “IPAM”: {
             “Driver”: “default”,
             “Options”: null,
             “Config”: [
                 {
                     “Subnet”: “172.17.0.0/16”,
                     “Gateway”: “172.17.0.1”
                 }
             ]
         },
         “Internal”: false,
         “Attachable”: false,
         “Ingress”: false,
         “ConfigFrom”: {
             “Network”: “”
         },
         “ConfigOnly”: false,
         “Containers”: {
             “0145aa8906d9e62823e091c3fbcfbce50bc27b27224f2cca456182d0dc52d9bc”: {
                 “Name”: “my-mongo”,
                 “EndpointID”: “829f503daadc5a23b401ae20a0825d920a01d15a6d426692aa7072937a4d9b16”,
                 “MacAddress”: “02:42:ac:11:00:03”,
                 “IPv4Address”: “172.17.0.3/16”,
                 “IPv6Address”: “”
             },
             “557b896ff138395489dfa2cf327366fe6e8d17baf72eb0d09bbeade4ee5eee5b”: {
                 “Name”: “my-site”,
                 “EndpointID”: “036f11da0b3d5c3da9f69f9a04569422d9e7d57b98eb920fc1cd046c1951d616”,
                 “MacAddress”: “02:42:ac:11:00:02”,
                 “IPv4Address”: “172.17.0.2/16”,
                 “IPv6Address”: “”
             }
         },
         “Options”: {
             “com.docker.network.bridge.default_bridge”: “true”,
             “com.docker.network.bridge.enable_icc”: “true”,
             “com.docker.network.bridge.enable_ip_masquerade”: “true”,
             “com.docker.network.bridge.host_binding_ipv4”: “0.0.0.0”,
             “com.docker.network.bridge.name”: “docker0”,
             “com.docker.network.driver.mtu”: “1500”
         },
         “Labels”: {}
     }
]

(2) 建立一個bridge,名字為samle-net

[root@c720120 ~]# docker network create –driver bridge sample-net
b4b881419620c448a18ec5aa1a09d8945b657a19a74c250f843311c62b3cb1da

(3) 檢查建立的sample-net bridge相關的subnet資訊

[root@c720120 ~]# docker network inspect sample-net | grep Subnet
                     “Subnet”: “172.20.0.0/16”,

(4) 建立bridge,並指定分配的子網資訊。

[root@c720120 ~]# docker network create –driver bridge –subnet “10.1.0.0/16” test-net
92377dbb1f7d74382a017c624f7b8ba83543c53f56ef2d835e3932b0d6cdfbfe

2. 關聯birdge到指定的容器上,案例如下

(1)建立一個容器,名字為c1。網路使用預設的

[root@c720120 ~]# docker container run –name c1 -it –rm alpine:latest /bin/sh
/ #

(2)檢查容器C1的網路設定

“NetworkSettings”: {
             “Bridge”: “”,
             “SandboxID”: “4c6dddcd6563b82fcf1e6c4360996a1fc183417224af2f82b1cf75b33a127cb5”,
             “HairpinMode”: false,
             “LinkLocalIPv6Address”: “”,
             “LinkLocalIPv6PrefixLen”: 0,
             “Ports”: {},
             “SandboxKey”: “/var/run/docker/netns/4c6dddcd6563”,
             “SecondaryIPAddresses”: null,
             “SecondaryIPv6Addresses”: null,
             “EndpointID”: “e9e70391b5a812e5237d29390a62dd9ad30229f5a952868cb05f406261ea9d38”,
             “Gateway”: “172.17.0.1”,
             “GlobalIPv6Address”: “”,
             “GlobalIPv6PrefixLen”: 0,
             “IPAddress”: “172.17.0.4”,
             “IPPrefixLen”: 16,
             “IPv6Gateway”: “”,
             “MacAddress”: “02:42:ac:11:00:04”,
             “Networks”: {
                 “bridge”: {
                     “IPAMConfig”: null,
                     “Links”: null,
                     “Aliases”: null,
                     “NetworkID”: “8d4ce133354ba6e3ab01684cf18b88535230647e78a6d698f1ef8d79f767b169”,
                     “EndpointID”: “e9e70391b5a812e5237d29390a62dd9ad30229f5a952868cb05f406261ea9d38”,
                     “Gateway”: “172.17.0.1”,
                     “IPAddress”: “172.17.0.4”,
                     “IPPrefixLen”: 16,
                     “IPv6Gateway”: “”,
                     “GlobalIPv6Address”: “”,
                     “GlobalIPv6PrefixLen”: 0,
                     “MacAddress”: “02:42:ac:11:00:04”,
                     “DriverOpts”: null
                 }

(3)在容器內部檢查IP地址

/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
     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
92: eth0@if93: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
     link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
     inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
        valid_lft forever preferred_lft forever

(4)在容器內部檢查route資訊

default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link  src 172.17.0.4

(5)執行容器C2

[root@c720120 ~]# docker container run –name c2 -d alpine:latest ping 127.0.0.1
6771f308f6df35fd7f8335d80f001fdb4c71090e8a5dd928d385a3003c044470

(6)檢查容器C2網路的IP地址

[root@c720120 ~]# docker container inspect –format “{{.NetworkSettings.IPAddress}}” c2
172.17.0.5

(7)再次檢查橋的資訊

“63ea128f076aa697e425eba4c7ca485d73c39f4d08d4a25d300372d00fec87c8”: {
      “Name”: “c1”,
      “EndpointID”: “e9e70391b5a812e5237d29390a62dd9ad30229f5a952868cb05f406261ea9d38”,
      “MacAddress”: “02:42:ac:11:00:04”,
      “IPv4Address”: “172.17.0.4/16”,
      “IPv6Address”: “”
  },
  “6771f308f6df35fd7f8335d80f001fdb4c71090e8a5dd928d385a3003c044470”: {
      “Name”: “c2”,
      “EndpointID”: “d7bee7887e97cdb0a4fa9d32bc30c8db0f0aaf6385dd4aa37f61db3557266b98”,
      “MacAddress”: “02:42:ac:11:00:05”,
      “IPv4Address”: “172.17.0.5/16”,
      “IPv6Address”: “”
  }

(8)建立 c3和c4容器,並指定網路為我們建立的橋test-net.

[root@c720120 ~]# docker container run –name c3 -d –network test-net
> alpine:latest ping 127.0.0.1
b7273876aa8880e285ddb566e5cdf08dd64fbfd4be2223c7277263976c22d1d5
[root@c720120 ~]# docker container run –name c4 -d –network test-net
> alpine:latest ping 127.0.0.1
27aa55af5c781e6b522c6d26c9e4ed8abcba8bf5c3f7378595a7863ccebe50cd

(9) 檢查橋test-net資訊

[root@c720120 ~]# docker network inspect test-net
[
     {
         “Name”: “test-net”,
         “Id”: “92377dbb1f7d74382a017c624f7b8ba83543c53f56ef2d835e3932b0d6cdfbfe”,
         “Created”: “2018-06-06T10:29:52.724830511+08:00”,
         “Scope”: “local”,
         “Driver”: “bridge”,
         “EnableIPv6”: false,
         “IPAM”: {
             “Driver”: “default”,
             “Options”: {},
             “Config”: [
                 {
                     “Subnet”: “10.1.0.0/16”
                 }
             ]
         },
         “Internal”: false,
         “Attachable”: false,
         “Ingress”: false,
         “ConfigFrom”: {
             “Network”: “”
         },
         “ConfigOnly”: false,
         “Containers”: {
             “27aa55af5c781e6b522c6d26c9e4ed8abcba8bf5c3f7378595a7863ccebe50cd”: {
                 “Name”: “c4”,
                 “EndpointID”: “f0b67945ac99fa496b592a2d589d611e7d804007d18d81fc7690e633edaa5588”,
                 “MacAddress”: “02:42:0a:01:00:03”,
                 “IPv4Address”: “10.1.0.3/16”,
                 “IPv6Address”: “”
             },
             “b7273876aa8880e285ddb566e5cdf08dd64fbfd4be2223c7277263976c22d1d5”: {
                 “Name”: “c3”,
                 “EndpointID”: “2928052cf121f4511356ae4ddc5c7fb2b7cef7781f108b56ec31484f9fa1afa1”,
                 “MacAddress”: “02:42:0a:01:00:02”,
                 “IPv4Address”: “10.1.0.2/16”,
                 “IPv6Address”: “”
             }
         },
         “Options”: {},
         “Labels”: {}
     }
]

(10) 進入到c3容器

[root@c720120 ~]# docker container exec -it c3 /bin/sh

(11)檢查到c4的網路是否可以互通。

/ # ping c4
PING c4 (10.1.0.3): 56 data bytes
64 bytes from 10.1.0.3: seq=0 ttl=64 time=0.371 ms
64 bytes from 10.1.0.3: seq=1 ttl=64 time=0.159 ms
64 bytes from 10.1.0.3: seq=2 ttl=64 time=0.183 ms
64 bytes from 10.1.0.3: seq=3 ttl=64 time=0.181 ms

(12)檢查到c2的網路是否可以互通。

/ # ping c2
ping: bad address `c2`

結論:關聯到相同的橋網路可以互相通訊,不同橋之間是無法通訊的,且bridge的作用範圍僅限本機。


(13)移除建立的橋網路

[root@c720120 ~]# docker network rm test-net
Error response from daemon: network test-net id 92377dbb1f7d74382a017c624f7b8ba83543c53f56ef2d835e3932b0d6cdfbfe has active endpoints

注意:如果建立的橋被其它容器正在引用,無法刪除,需要先刪除關聯的容器,再刪除相關的橋。

(14)刪除容器

[root@c720120 ~]# dockere container rm -f $(docker container ls -aq)

(15)刪除建立的橋

[root@c720120 ~]# docker network rm sample-net

[root@c720120 ~]# docker network rm test-net

三. The host network

1. 關聯docker host網路,執行以下指令

[root@c720120 ~]# docker container run –rm -it –network host alpine:latest /bin/sh

2. 在容器內部檢視網路資訊

/ # ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
     link/ether 52:54:00:da:66:d3 brd ff:ff:ff:ff:ff:ff
     inet 192.168.20.120/24 brd 192.168.20.255 scope global eth0

3. 在容器內部檢視路由資訊

/ # ip route
default via 192.168.20.1 dev eth0  metric 100
10.1.0.0/16 dev br-92377dbb1f7d scope link  src 10.1.0.1
10.244.0.0/24 dev cni0 scope link  src 10.244.0.1
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
10.244.3.0/24 via 10.244.3.0 dev flannel.1 onlink
10.244.4.0/24 via 10.244.4.0 dev flannel.1 onlink
172.17.0.0/16 dev docker0 scope link  src 172.17.0.1
172.18.0.0/16 dev br-4d8fecd89ea0 scope link  src 172.18.0.1
172.19.0.0/16 dev docker_gwbridge scope link  src 172.19.0.1
172.20.0.0/16 dev br-b4b881419620 scope link  src 172.20.0.1
192.168.20.0/24 dev eth0 scope link  src 192.168.20.120  metric 100

四. The null network

1. 關聯null網路,執行以下命令

[root@c720120 ~]# docker container run –rm -it –network none alpine:latest /bin/sh
/ #

2. 在容器內部檢視IP地址資訊

/ # ip addr show eth0
ip: can`t find device `eth0`

3. 在容器內部檢視路由資訊

/ # ip route

五. 執行在一個已經存在的網路名稱空間

執行多個容器在單 一網路全名空間如下

單一docker主機網路

1. 建立網路橋,名字為test-net

[root@c720120 ~]# docker network create –driver bridge test-net

2. 執行一個容器,並關聯到橋test-net

[root@c720120 ~]# docker container run –name web -d –network test-net nginx:alpine

ead5f17f047e47fedca5d54ebcfea729aa12c5be2776e3b2868f01f2330658f9

3. 執行另外一個容器,網路使用第2步建立的容器的網路名稱空間。

[root@c720120 ~]# docker container run -it –rm –network container:web alpine:latest /bin/sh
/ #

4.測試 localhost是否可以訪問web容器中的內容

/ # wget -qO – localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
     body {
         width: 35em;
         margin: 0 auto;
         font-family: Tahoma, Verdana, Arial, sans-serif;
     }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href=”http://nginx.org/”>nginx.org</a>.<br/>
Commercial support is available at
<a href=”http://nginx.com/”>nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>Next Section
</html>

5. 刪除建立的容器和網路(實驗結束)

[root@c720120 ~]# docker container rm –force web
web

[root@c720120 ~]# docker network rm test-net

六. 埠管理

1. 埠對映

(1)埠對映(一個隨機的32xxx埠)

[root@c720120 ~]# docker container run –name web -P -d nginx:alpine
78e5086b7e0ad6f1283dff7485f74f27c492b1d8a96f602e9937fd8e0bcf96f4

(2)檢視對映的埠

[root@c720120 ~]# docker container port web
80/tcp -> 0.0.0.0:32768

也可以通過下列方式檢視埠對映關係:

[root@c720120 ~]# docker container inspect web | grep HostPort
                         “HostPort”: “32768”

或者:

[root@c720120 ~]# docker container ls
CONTAINER ID        IMAGE                                                     COMMAND                  CREATED             STATUS              PORTS                   NAMES
78e5086b7e0a        nginx:alpine                                              “nginx -g `daemon of…”   2 minutes ago       Up 2 minutes        0.0.0.0:32768->80/tcp   web

(3)手工指定要對映的埠(不隨機分配 )

[root@c720120 ~]# docker container run –name web2 -p 8080:80 -d nginx:alpine
f8e6775b9c2537094a8e811c9fd927cd918436676e7d5d4a39482262f40770d9

相關文章