单一docker主机网络

Posted zangxueyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单一docker主机网络相关的知识,希望对你有一定的参考价值。

一. 容器网络模型:

Docker定义了一个非常简单的网络模型,叫做container network model(CNM).如下图所示:

技术分享图片


CNM模型有三个元素---sandbox, endpoint, 和network

  • sandbox:不允许从外面的网络连接到容器,实现了完美的隔离功能。
  • Endpoint: 终端节点可以认为是network到sandbox中间的一个节点,可以想像成是到容器的一个门。
  • network: 是终端和终端之间进行通信的保障。也是一个特别重要的组件。


下图描述了容器网络常见的几种方式和作用范围:

NetworkCompanyScopeDescription
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信息

[[email protected] ~]# 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

[[email protected] ~]# docker network create --driver bridge sample-net
b4b881419620c448a18ec5aa1a09d8945b657a19a74c250f843311c62b3cb1da


(3) 检查创建的sample-net bridge相关的subnet信息

[[email protected] ~]# docker network inspect sample-net | grep Subnet
                     "Subnet": "172.20.0.0/16",


(4) 创建bridge,并指定分配的子网信息。

[[email protected] ~]# docker network create --driver bridge --subnet "10.1.0.0/16" test-net
92377dbb1f7d74382a017c624f7b8ba83543c53f56ef2d835e3932b0d6cdfbfe


2. 关联birdge到指定的容器上,案例如下

(1)创建一个容器,名字为c1。网络使用默认的

[[email protected] ~]# 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: [email protected]: <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

[[email protected] ~]# docker container run --name c2 -d alpine:latest ping 127.0.0.1
6771f308f6df35fd7f8335d80f001fdb4c71090e8a5dd928d385a3003c044470


(6)检查容器C2网络的IP地址

[[email protected] ~]# 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.

[[email protected] ~]# docker container run --name c3 -d --network test-net \
> alpine:latest ping 127.0.0.1
b7273876aa8880e285ddb566e5cdf08dd64fbfd4be2223c7277263976c22d1d5
[[email protected] ~]# docker container run --name c4 -d --network test-net \
> alpine:latest ping 127.0.0.1
27aa55af5c781e6b522c6d26c9e4ed8abcba8bf5c3f7378595a7863ccebe50cd


(9) 检查桥test-net信息

[[email protected] ~]# 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容器

[[email protected] ~]# 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)移除创建的桥网络

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


注意:如果创建的桥被其它容器正在引用,无法删除,需要先删除关联的容器,再删除相关的桥。


(14)删除容器

[[email protected] ~]# dockere container rm -f $(docker container ls -aq)


(15)删除创建的桥

[[email protected] ~]# docker network rm sample-net

[[email protected] ~]# docker network rm test-net


三. The host network

1. 关联docker host网络,运行以下指令

[[email protected] ~]# 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网络,运行以下命令

[[email protected] ~]# 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


五. 运行在一个已经存在的网络命名空间

运行多个容器在单 一网络全名空间如下

技术分享图片


1. 创建网络桥,名字为test-net

[[email protected] ~]# docker network create --driver bridge test-net


2. 运行一个容器,并关联到桥test-net

[[email protected] ~]# docker container run --name web -d --network test-net nginx:alpine

ead5f17f047e47fedca5d54ebcfea729aa12c5be2776e3b2868f01f2330658f9


3. 运行另外一个容器,网络使用第2步创建的容器的网络命名空间。

[[email protected] ~]# 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. 删除创建的容器和网络(实验结束)

[[email protected] ~]# docker container rm --force web
web

[[email protected] ~]# docker network rm test-net


六. 端口管理

1. 端口映射

(1)端口映射(一个随机的32xxx端口)

[[email protected] ~]# docker container run --name web -P -d nginx:alpine
78e5086b7e0ad6f1283dff7485f74f27c492b1d8a96f602e9937fd8e0bcf96f4


(2)查看映射的端口

[[email protected] ~]# docker container port web
80/tcp -> 0.0.0.0:32768


也可以通过下列方式查看端口映射关系:

[[email protected] ~]# docker container inspect web | grep HostPort
                         "HostPort": "32768"

或者:

[[email protected] ~]# 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)手工指定要映射的端口(不随机分配 )

[[email protected] ~]# docker container run --name web2 -p 8080:80 -d nginx:alpine
f8e6775b9c2537094a8e811c9fd927cd918436676e7d5d4a39482262f40770d9

以上是关于单一docker主机网络的主要内容,如果未能解决你的问题,请参考以下文章

DockerSwarm 集群环境搭建

docker容器网络

docker 怎么把宿主机的文件拷贝到运行的容器中

Docker网络与Iptables浅析

Docker网络管理之docker跨主机通信

docker swarm网络问题