手机版

Docker用户指南(10) – Docker容器网络

时间:2020-04-01 来源:互联网 编辑:宝哥软件园 浏览:
默认网络默认的bridge网络详细信息自定义网络bridge网络docker_gwbridge网络Docker Engine swarm模式的overylay网络依赖外部键值存储的overlay网络自定义网络插件Docker内置的DNS服务器

本文对Docker提供的几个默认网络的行为做个简单介绍。描述默认创建的网络类型,以及如何创建自己的用户定义的网络。同时说明在单台主机或跨主机集群创建网络所需的资源。

默认网络

当你安装Docker后,它自动创建了三个网络。你可以使用docker network ls命令来列出这些网络。

$ docker network ls
 
NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host

历史上,这三个网络是Docker的一部分。当你运行一个容器时,你可以使用–network参数来指定你想运行容器在哪个网络上。这三个网络仍然可用。
称为docker0的bridge网络出现在所有Docker的安装中。除非你使用docker run –network=来指定其它网络,否则Docker daemon默认连接容器到这个网络。你可以在主机使用ifconfig命令看到这个bridge是主机网络堆栈的一部分。

$ ifconfig
 
docker0   Link encap:Ethernet  HWaddr 02:42:47:bc:3a:eb
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:47ff:febc:3aeb/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1100 (1.1 KB)  TX bytes:648 (648.0 B)

none网络添加一个容器到一个容器特定网络堆栈。这样会使那个容器缺少网络接口。附加到这样一个容器,按如下来查看:

$ docker attach nonenetcontainer
 
root@0cb243cd1293:/# cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
root@0cb243cd1293:/# ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
 
root@0cb243cd1293:/#

注意:你按下CTRL-p CTRL-q与容器分离。

host网络添加一个容器到主机的网络堆栈。你会发现容器内的网络配置与主机的相同。
除了bridge网络,你不需要与这些默认的网络交互。虽然你能列出和查看它们,你不能删除它们。因为Docker的安装依赖它们。不过你可以添加你自己自定义的网络并且不再需要它们时可以删除。在学习创建你自己的网络之前,值得再看下默认的bridge网络。

默认的bridge网络详细信息

默认的bridge网络存在于所有的Docker主机中。docker network inspect网络返回关于网络的信息:

$ docker network inspect bridge
 
[
   {
       "Name": "bridge",
       "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f",
       "Scope": "local",
       "Driver": "bridge",
       "IPAM": {
           "Driver": "default",
           "Config": [
               {
                   "Subnet": "172.17.0.1/16",
                   "Gateway": "172.17.0.1"
               }
           ]
       },
       "Containers": {},
       "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": "9001"
       }
   }
]

Docker Engine自动给这个网络创建一个子网和网关。docker run命令自动地增加新容器到这个网络。

$ docker run -itd --name=container1 busybox
 
3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c
 
$ docker run -itd --name=container2 busybox
 
94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c

启动这两个容器后重新查看bridge网络会看到在这个网络有两个新启动的容器。它们的id显示在docker network inspect命令输出的“Containers”区块中:

$ docker network inspect bridge
 
{[
    {
        "Name": "bridge",
        "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {
                    "Subnet": "172.17.0.1/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Containers": {
            "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
                "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": {
                "EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/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": "9001"
        }
    }
]

上面的docker network inspect命令显示所有连接的容器和它们的网络资源。在这个默认网络的容器能够使用IP地址来互相通信。在这个默认的bridge网络Docker不支持自动服务发现。如果你想在这个默认的bridge网络使用容器名称来通信,你必须通过旧的docker run –link选项来连接容器。
你可以attach一个运行中的容器来查看它的配置:

$ docker attach container1
 
root@0cb243cd1293:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1296 (1.2 KiB)  TX bytes:648 (648.0 B)
 
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

然后使用ping来发送三个ICMP请求测试在bridge网络的容器之间的连接性。

root@0cb243cd1293:/# ping -w3 172.17.0.3
 
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.096 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.080 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.074 ms
 
--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.074/0.083/0.096 ms

最后,使用cat命令检查container1网络配置:

root@0cb243cd1293:/# cat /etc/hosts
 
172.17.0.2  3386a527aa08
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

按下CTRL-p CTRL-q离开container1,再attach到container2和重复这三个命令。

$ docker attach container2
 
root@0cb243cd1293:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03
          inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1166 (1.1 KiB)  TX bytes:1026 (1.0 KiB)
 
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
 
root@0cb243cd1293:/# ping -w3 172.17.0.2
 
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.067 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.072 ms
 
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.071/0.075 ms
/ # cat /etc/hosts
172.17.0.3  94447ca47985
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

默认的docker0 bridge网络支持端口映射的使用,docker run –link允许在docker0网络中的容器之间通信。这些技术设置起来很麻烦,容易出错。不过它们仍然可用,最后定义自己的bridge网络来避免它们。

自定义网络

你可以创建自己定义的网络来更好的隔离容器。Docker为方便创建这些网络提供了一些默认的网络驱动。你可以创建一个bridge网络,overlay网络或MACVLAN网络。你也可以创建一个写入自己规格的网络插件(network plugin)或远程网络(remote network)。
你既能创建多个网络,也能添加容器到多个网络。容器只能在它加入的网络内通信不过跨网络。一个容器附加到两个网络能与这两个网络的所有成员通信。当一个容器连接多个网络时,由第一个非内部网络提供外部连接。

bridge网络

创建最简单的自定义网络是bridge网络。这个网络类似于历史默认的docker0网络。不过增加了一些新的功能和一些旧的功能不再可用。

$ docker network create --driver bridge isolated_nw
1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b
 
$ docker network inspect isolated_nw
 
[
    {
        "Name": "isolated_nw",
        "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1/16"
                }
            ]
        },
        "Containers": {},
        "Options": {}
    }
]
 
$ docker network ls
 
NETWORK ID          NAME                DRIVER
9f904ee27bf5        none                null
cf03ee007fb4        host                host
7fca4eb8c647        bridge              bridge
c5ee82f76de3        isolated_nw         bridge

创建网络后,你可以使用docker run –network=选项来加入这个网络。

$ docker run --network=isolated_nw -itd --name=container3 busybox
 
8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c
 
$ docker network inspect isolated_nw
[
    {
        "Name": "isolated_nw",
        "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {
            "8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c": {
                "EndpointID": "93b2db4a9b9a997beb912d28bcfc117f7b0eb924ff91d48cfa251d473e6a9b08",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {}
    }
]

你要加入到这个网络的容器必须在同一台docker主机上。在这个网络的每一个容器能马上与在这个网络的其它容器通信。虽然网络本身将容器与外部网络隔离了。
Docker用户指南(10) – Docker容器网络
在一个自定义的bridge网络中,linking是不支持的。你可以在这个网络的容器公开和发布容器端口。如果你想使bridge的一部分容器可用于一个外部的网络会非常有用。

你想在一个主机运行一个相关的小的网络这种场景下,可以使用bridge网络。

docker_gwbridge网络

在两种不同的情况下docker会自动创建一个本地bridge网络docker_gwbridge:

当你初始化或加入一个swarm,docker创建docker_gwbridge网络并用它来与不同的主机上的swarm节点之间通信。 当没有一个容器网络能提供外部连接时,docker连接容器到docker_gwbridge网络以及容器的其它网络,以使得容器能连接外部网络或其它swarm节点。

如果你需要一个自定义的配置你可以提前创建docker_gwbridge网络,否则docker会根据需要创建它。下面的示例使用一些自定义选项来创建docker_gwbridge网络。

$ docker network create --subnet 172.30.0.0/16 
                        --opt com.docker.network.bridge.name=docker_gwbridge 
            --opt com.docker.network.bridge.enable_icc=false 
            docker_gwbridge

当你使用overlay网络时docker_gwbridge始终存在。

Docker Engine swarm模式的overylay网络

你可以在运行着swarm模式的管理节点上创建一个不需要外部键值存储的overylay网络。overlay网络只可用于服务依赖它的swarm节点上。当你创建一个服务使用overlay网络时,管理节点自动扩展overlay网络到运行服务任务的节点上。
下面的示例显示如何创建一个网络并设置一个服务使用这个网络:

# Create an overlay network `my-multi-host-network`.
$ docker network create 
  --driver overlay 
  --subnet 10.0.9.0/24 
  my-multi-host-network
 
400g6bwzd68jizzdx5pgyoe95
 
# Create an nginx service and extend the my-multi-host-network to nodes where
# the service's tasks run.
$ docker service create --replicas 2 --network my-multi-host-network --name my-web nginx
 
716thylsndqma81j6kkkb5aus

依赖外部键值存储的overlay网络

如果你的Docker Engine没有运行在swarm模式中,overlay网络则需要一个有效的键值存储服务。支持键值存储包括Consul, Etcd和ZooKeeper(分布式存储)。在这个Engine版本创建这个网络前,你必须安装和配置一个键值存储服务。要加入到这个网络的docker主机和服务必须能与这个键值存储服务通信。

注意:运行在swarm模式的docker engine与使用一个外部键值存储的网络不兼容。

docker
在这个网络的每一个主机必须运行一个docker engine实例。
docker
在每一个主机之间需要开放如下端口。

协议 端口 描述 udp 4789 Data plane (VXLAN) tcp/udp 7946 Control plane

要创建一个overlay网络,还需要在每个主机的docker daemon配置如下选项:

选项 描述 –cluster-store=PROVIDER://URL 键值服务地址 –cluster-advertise=HOST_IP|HOST_IFACE:PORT 用于集群的IP地址,接口和端口 –cluster-store-opt=KEY-VALUE OPTIONS TLS证书或调整发现时间等选项

在集群中一个机器上创建一个overlay网络。

$ docker network create --driver overlay my-multi-host-network

这使得一个网络可以跨越多个主机。overlay网络为容器提供完全的隔离。
docker
然后,在每个主机上运行容器时确保指定网络名称。

$ docker run -itd --network=my-multi-host-network busybox

一旦容器连接到这个网络,每个容器就有权限访问这个网络中的所有容器,不管容器是在哪个主机运行的。
docker

自定义网络插件

如果你想,你如果编写自己的网络驱动插件。网络驱动插件使用Docker的插件基础设施。在这个基础设施中,插件是在与Docker守护程序相同的Docker主机上运行的进程。网络插件遵循与其他插件相同的限制和安装规则。所有插件都使用插件API。它们具有包括安装,启动,停止和激活的生命周期。一旦创建并安装了自定义网络驱动程序,就可以像内置网络驱动一样使用它。 例如:

$ docker network create --driver weave mynet

你可以查看这个自定义网络,添加容器到这个网络等等。

Docker内置的DNS服务器

Docker daemon运行一个内置的DNS服务器为连接到自定义网络的容器提供自动服务发现功能。从容器发来的域名解析请求首先由内置的DNS服务器处理。如果内置的DNS服务器无法解析这个请求,那么它就将此请求转发到容器配置的外部DNS服务器。

版权声明:Docker用户指南(10) – Docker容器网络是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。

相关文章推荐