docker network

作者: Tim_SSS | 来源:发表于2018-11-28 15:18 被阅读0次

docker 网络的种类

  1. host
  2. bridge
  3. overlay
  4. Macvlan

host

  • 如果你对一个容器使用的是host网络驱动,这个容器的网络栈并不是和docker宿主机隔离的。例如,你启动了一个容器绑定的是80端口,使用的host网络驱动,而你的应用程序将使用主机的ip和端口。
  • host网络驱动仅能在Linux上工作,不支持docker的宿主机是Mac、Windows、Windows Server.
  • 在docker 17.06 或者更高版本,你也可以在swarm service 上使用host网络,通过在docker container create 命令上设置--network host。在这种情况下,管理swarm集群和服务上仍然用overlay 网络,但是在单独的集群容器使用的主机网络和端口来发送数据的。 这样也是有一些额外限制的,例如, 如果一个服务容器,绑定的是80端口,那么仅有一个服务容器可以在指定的swarm 节点上运行。
  • 如果你的容器或者服务没有对外端口,host网络就没办法生效。

bridge

Use bridge networks(桥接网络的使用)

  • 就网络而言,桥接网络是链路层设备,用于在网络段之间转发通信。桥接可以是运行在主机内核中的硬件设备或软件设备。
  • 对docker而言,桥接网络使用的软件桥接方式,它允许容器之间使用相同桥接网络进行通信,同时与使用其他桥接网络的的容器进行隔离。docker的桥接驱动在宿主机上有自己独特的安装规则,以至于在不同的桥接网络上的容器彼此不能直接通信。
  • 桥接网络作用于同一个宿主机上的docker守护进程的容器上。对于在不同宿主机上的守护进程的容器来说,你既可以通过OS系统级别的方式来管理通信,也可以通过使用overlay网络来管理。
  • 当你启动docker,一个默认的桥接网络会被自动创建,除非另有指定,否则新启动的容器会链接它。你也可以创建自定义桥接网络。自定义桥接网络优先级会高于默认网络。

Differences between user-defined bridges and the default bridge (自定义桥接和默认桥接的不同)

1、 User-defined bridges provide better isolation and interoperability between containerized applications.(自定义桥接提供了容器化应用程序之间更好的隔离性和互操性-协同工作的能力)

  • 连接同一个自定义桥接网络的容器彼此暴露端口,而不会对外世界暴露端口。这样就可以使容器化应用之间很容易的互相通信,外面的世界也不会很容易进入的容器里。
  • 设想一个具有Web前端和数据库后端的应用程序。外部世界需要访问web前端(也许在端口80上),但是只有后端本身需要访问数据库主机和端口。使用用户定义的桥,只需要打开web端口,并且数据库应用程序不需要打开任何端口,因为web前端可以通过用户定义的桥到达它。
  • 如果在默认桥接网络上运行相同的应用程序堆栈,则需要同时打开web端口和数据库端口,并为每个端口使用-p或-publish标志。这意味着Docker主机需要通过其他方式阻止对数据库端口的访问。

2、User-defined bridges provide automatic DNS resolution between containers.(自定义桥接可以在容器之间提供自动DNS解决方案)

  • 默认桥接网络上的容器只能通过IP地址相互访问,除非使用--link选项,这被认为是遗留的问题。在用户定义的桥接网络上,容器可以通过名称或别名彼此解析。
  • 设想一下与前一点相同的应用程序,具有web前端和数据库后端。如果调用容器web和db,则无论应用程序堆栈运行在哪个Docker主机上,Web容器都可以连接到db处的db容器。
  • 如果在默认桥接网络上运行相同的应用程序堆栈,则需要在容器之间手动创建链接(使用.y--link标志)。这些链接需要在两个方向上(各个容器)创建,因此您可以看到,对于需要通信的两个以上的容器,这会变得复杂。或者,您可以在容器中操作/etc/hosts文件,但是这会产生难以调试的问题。

3、Containers can be attached and detached from user-defined networks on the fly.(正在运行的容器可以在自定义桥接网络上链接和分离)

  • 在容器的生命周期中,您可以动态地将它与用户定义的网络连接或断开。要从默认桥接网络中删除容器,需要停止容器并使用不同的网络选项重新创建容器。

4、Each user-defined network creates a configurable bridge.(每个用户定义的网络创建一个可配置的网桥。)

  • 如果容器使用默认桥接网络,则可以对其进行配置,但是所有容器都使用相同的设置,如MTU和iptables规则。此外,配置默认桥接网络发生在Docker本身之外,并且需要重新启动Docker。
  • 使用docker network create创建和配置用户定义的桥接网络。如果不同的应用程序组具有不同的网络需求,那么您可以在创建每个用户定义的桥接器时分别配置它。

5、Linked containers on the default bridge network share environment variables.(使用默认桥接网络的容器共享变量)

  • 最初,在两个容器之间共享环境变量的唯一方法是使用--link标志链接它们。这种类型的变量共享与用户定义的网络容器是不可能的。
  • 这有一些共享环境变量的方法:
  1. 多个容器可以使用Docker卷挂载包含共享信息的文件或目录。
  2. 可以使用docker-compose一起启动多个容器,并且compose文件可以定义共享变量。
  3. 您可以使用群集服务来代替独立的容器,并利用共享的秘密和配置。

连接到同一用户定义的桥接网络的容器有效地将所有端口彼此公开。要让不同网络上的容器或非Docker主机能够访问端口,必须使用-p或-publish标志发布该端口。

Manage a user-defined bridge (管理用户自定桥接)

  • 使用 docker network create 命令创建用户定义的网桥网络。
$ docker network create my-net
  • 您可以指定子网、IP地址范围、网关和其他选项。有关详细信息,请参阅docker network create 引用文档或docker network create --help 的输出。
  • 使用docker network rm 命令删除用户定义的网桥网络。如果容器当前连接到网络,首先断开它们。
$ docker network rm my-net

删除网络到底发生了什么?

在创建或删除用户定义的网桥或从用户定义的网桥连接或断开容器时,Docker使用操作系统特有的工具来管理底层网络基础设施(例如添加或删除网桥设备或在Linux上配置iptables规则)。这些细节应被视为实现细节。让docker为您管理用户定义的网络。

Connect a container to a user-defined bridge( 使用用户自定义网络链接容器)

  • 当你创建新容器时,可以指定一个或多个--network标志。此示例将NGNIX容器连接到MyNet网络。它还将容器中的端口80发布到Docker主机上的端口8080,因此外部客户端可以访问该端口。连接到my-net网络的任何其他容器都可以访问my-nginx容器上的所有端口,反之亦然。
$ docker create --name my-nginx \
  --network my-net \
  --publish 8080:80 \
  nginx:latest
  • 若要将正在运行的容器连接到现有用户定义的桥接网络,请使用docker network connect命令。以下命令将已经运行的my-nginx容器连接到已经存在的my-net网络:
$ docker network connect my-net my-nginx

Disconnect a container from a user-defined bridge (容器从自定义桥接网络断开)

  • 若要将正在运行的容器从现有用户自定义桥接网络断开,使用docker network disconnect 命令。以下命令将my-nginx容器从my-net网络断开:
$ docker network disconnect my-net my-nginx

Use IPv6

  • 如果你需要docker容器支持IPv6,则需要在创建任何IPV6网络之前或者分配IPv6地址之前,在docker进程上启动选项并重新加载其配置。
  • 当您创建网络,指定--ipv6标记来启动IPv6,不能在默认桥接网络上选择禁止IPv6.

Enable forwarding from Docker containers to the outside world (允许docker容器访问外面的世界)

  • 默认情况下,链接默认桥接网络的容器是不能和外面的世界通信的。为了能和外面的世界通信,你需要关闭安两个设置。这些设置不是docker命令,他们是影响docker宿主机内核的。
1、设置Linux kernel 允许ip转发。
$ sysctl net.ipv4.conf.all.forwarding=1
2、改变ptables FORWARD 规则从DROP 到 ACCEPT
$ sudo iptables -P FORWARD ACCEPT

在重新启动时,这些设置不会持久存在,因此可能需要将它们添加到启动脚本中。

Use the default bridge network(使用默认桥接网络)

默认的桥接网络被认为是docker的遗留问题,不建议在生产中使用。配置它需要手动操作,而且它还有技术缺点。

Connect a container to the default bridge network (使容器容器连接默认的桥接网络)

  • 如果你没有指定网络--network标记和指定网络驱动,你的容器就链接的默认桥接网络。链接桥接网络的容器只能通过Ip地址来进行通信,出来他们使用--link legacy 标记。

Configure the default bridge network(设置默认桥接网络)

  • 为了设置默认桥接网络,你需要指定daemon.json选项。这里有一个关于的带有设置daemon.json例子。仅需要你定制这些选项就可以。
{
  "bip": "192.168.1.5/24",
  "fixed-cidr": "192.168.1.5/25",
  "fixed-cidr-v6": "2001:db8::/64",
  "mtu": 1500,
  "default-gateway": "10.20.1.1",
  "default-gateway-v6": "2001:db8:abcd::89",
  "dns": ["10.20.1.2","10.20.1.3"]
}

重启docker这些改变才生效。

Use IPv6 with the default bridge network(在默认网络上使用IPv6)

  • 如果你想docker 支持IPv6(see ),默认桥接网络也是可以自动设置成IPv6。不像用户自定义桥接网络,在默认桥接网络上,你不能选择性的禁止IPv6。

overlay

  • overlay网络驱动可以在多个docker宿主机之间创建一个分布式网络。这种网络位于宿主机特定网络之上,允许已经连接该网络的容器(包括已经连接该网络的集群服务)安全的通信。docker透明地处理每个从正确的docker主机和正确的目的地容器的数据路由。
  • 当你初始化一个swarm或者将一个docker主机加入到已经存在swarm上,在docker主机上创建了两个网络。

1、一个被称为ingress的overlay网络,它用于处理与集群的控制和数据传输。当你创建一个swarm 集群服务,没有将它连接到用户自定义网络情况下,默认它会使用ingress网络连接。

2、一个被称为docker_gwbridge的桥接网络,它用于将单个docker进程连接到swarm集群其他docker进程。

  • 你可以使用docker network create创建用户定义的overlay网络,也可以用同样的方式创建用户定义的桥接网络。服务或容器可以一次连接到一个以上的网络。服务或容器只能通过它们各自连接的网络进行通信。

  • 尽管你可以使用overlay网络链接swarm集群服务和单个容器,但是默认行为和设置关注点是不同的。由于这个原因,本主题的其余部分分为适用于所有overlay网络的操作、适用于群服务网络的操作和适用于独立容器使用的覆盖网络的操作。

Operations for all overlay networks (所有有关overlay网络的操作)

1、Create an overlay network(创建一个overlay网络)

  • 使用overlay网络的docker进程的防火墙规则。

你需要来往于每个参与overlay网络的docker的主机的端口是开放的。

TCP端口:2377 用于集群管理

TCP和UDP端口:7946用于集群管理节点

UDP端口:4789 用于overlay网络通信

在你创建overlay网络之前,你既可以使用docker swarm init命令初始化你的docker进程作为swarm 集群管理,也可以使用docker swarm join 命令加入到已经存在集群中。它们中任何一个都会创建一个imgress overlay 网络,这个网络默认是被用于swarm集群服务的。如果你没有计划使用swarm集群服务,就没必要这么做。之后,你可以创建一个附加的用户定义overlay网络。

  • 为使用swarm集群服务而创建的overlay网络,可以使用以下命令:
$ docker network create -d overlay my-overlay
  • 为使用swarm集群服务或者单个容器与其他docker守护进程的容器通信,可以使用--attachable 标记:
$ docker network create -d overlay --attachable my-attachable-overlay

你可以指定ip段,子网络,网关或者其他选项。具体可以参考:docker network create --help

2、 Encrypt traffic on an overlay network(在overlay网络上使用加密通信)

  • 所有的集群管理通信默认都是加密的,使用的是AES的加密方式。群中的管理节点每12小时轮换下用于加密gossip数据的秘钥。
  • 同样也是可以加密应用数据的,在创建overlay网络的时候,添加--opt encrypted 。这使得IPSEC加密在vxlan等级上。这种加密会带来性能损耗,所以在上线之前,应该对其进行测试。
  • 当启用加密overlay加密网络,docker创建IPSEC通道在所有节点之间,服务的任务调度依附于overlay网络。这些通道使用AES加密方式,管理节点每12小时轮换秘钥。

不能在windows节点上使用加密overlay网络

overlay 网络加密方式在windows上是不支持的。如果windows节点尝试连接加密的overlay网络,不会出现错误,但是节点之间不能通信。

3、swarm mode overlay networks and standalone containers (集群下的overlay网络和单个容器)

  • 你可以使用overlay网络的一些特点,--opt encrypted --attachable 然后让一个没有被管理的容器依附到这个网络上:
$ docker network create --opt encrypted --driver overlay --attachable my-attachable-multi-host-network

4、Customize the default ingress network (定制默认的ingress网络)

  • 大多数用户没必要设置ingress网络,但是docker17.05或者更高版本允许你需改。如果自动分配的子网络有和你现在已经存在的网络有冲突,或许你可以设置其他低一级网络,例如MTU网络。
  • 定制ingress网络包括删除和从新创建网络。这通常需要你在开启swarm 服务之前做这些事情。如果你的服务已经存在并且已经对外暴露端口,需要你在移除ingress网络之前,删除服务。
  • 在不存在ingress网络的期间,不发布端口的现有服务继续发挥作用,但是不会被负载均衡。这样会影响发布端口的服务,例如发布端口80的WordPress服务。

1、使用docker network inspect ingress 命令检测ingress网络,删除任何已经连接这个网络服务。这些服务已经暴露了端口,例如对外暴露80端口wordpress服务。如果这样的服务没有停止,下一步将会出现错误。

2、删除已经存在ingress网络:

$ docker network rm ingress

WARNING! Before removing the routing-mesh network, make sure all the nodes
in your swarm run the same docker engine version. Otherwise, removal may not
be effective and functionality of newly created ingress networks will be
impaired.
Are you sure you want to continue? [y/N]

3、创建一个overlay网络,使用--ingress标记,跟随一些定制化选项。下面一个示例,设置MTU到1200设置子网段,和设置网关。

$ docker network create \
  --driver overlay \
  --ingress \
  --subnet=10.11.0.0/16 \
  --gateway=10.11.0.2 \
  --opt com.docker.network.driver.mtu=1200 \
  my-ingress

Note:你可以将ingress网络命名其他ingress的名字,但只能只要一个。尝试命名第二个将会失败。

4、重启你刚才在第一步停止的服务。

5、Customize the docker_gwbridge interface(定制化docker 桥接接口)

  • docker_gwbridge 是一个虚拟的桥,它可以链接overlay网络(包括ingress网络)到docker守护进程物理网络上。当你初始化从docker swarm集群时,docker自动创建它,但是它不是docker设备。它存在docker主机的内核中。如果你需要定制设置它,你必须在加入docker集群之前,做这些事情,或者暂时将docker宿主机从集群移除之后。

1、停止docker。

2、删除已经存在docker_gwbridge 接口。

$ sudo ip link set docker_gwbridge down

$ sudo ip link del dev docker_gwbridge

3、启动docker。不要加入和初始化集群。

4、使用docker network create命令,来定制化设置手动创建或者重新创建docker_gwbridge接口。以下示例在子网络下10.11.0.0/16下,有关可定制选项的完整列表,请参见“桥驱动程序选项”。

$ docker network create \
--subnet 10.11.0.0/16 \
--opt com.docker.network.bridge.name=docker_gwbridge \
--opt com.docker.network.bridge.enable_icc=false \
--opt com.docker.network.bridge.enable_ip_masquerade=true \
docker_gwbridge

5、初始化或者加入集群。由于网桥已经存在,docker就不会自动创建和设置它。

Operations for swarm services(对swarm 集群操作)

1、Publish ports on an overlay network(暴露overlay网络端口)

  • 连接到同一覆盖网络的群服务有效地将所有端口彼此公开。对于要在服务外访问的端口,必须使用-p或--publish标志在docker服务创建或docker服务更新上发布该端口。支持传统的冒号分隔语法和更新的逗号分隔值语法。语法越长越好,更能表明自己在做什么。
标记值 描述
-p 8080:80 或-p published=8080,target=80 默认协议Tcp,在服务上用的80端口,在路由表上用的8080端口(对外)
-p 8080:80/udp 或-p published=8080,target=80,protocol=udp 指定协议udp,在服务上用的80端口,在路由表上用的8080端口(对外)
-p 8080:80/tcp -p 8080:80/udp 或 -p published=8080,target=80,protocol=tcp -p published=8080,target=80,protocol=udp 设置以上两个协议和对应的端口

2、Bypass the routing mesh for a swarm service(让swarm集群绕过路由网络)

  • 默认情况下,swarm 集群使用routing 网络暴露端口。当你连接到任意集群节点上的已发布端口(无论它是是否运行给定服务),你将被重定向到运行该服务的worker上。有效地,docker对于你的swarm集群将扮演一个负载均衡角色。
  • 要想绕过路由网络,可以通过--endpoint-mode标志设置为dnsrr,使用DNS循环模式来开启服务。你必须在服务前面,设置自己的负载均衡。对于docker主机上服务名称的一次dns查询,将返回一系列有关服务节点的IP地址。把这些IP列表配置到你的负载均衡器上,来负载节点之间的通信。

3、Separate control and data traffic (将控制和数据传输分开)

  • 默认情况下,与群管理相关的控制通信和来往应用程序之间的通信,都是在相同网络下,但是与集群控制相关的通信是加密的。你可以设置docker配置,使用不同网络接口来控制两种类型的网络通信。当你初始化或者加入集群的时候,分别指定--advertise-addr 和 --datapath-addr.对于每个加入集群的节点,你都必须啊这么做。

Operations for standalone containers on overlay networks(在overlay网络下,对容器单例的操作)

1、Attach a standalone container to an overlay network (将一个容器实例依附于一个overlay网络)

  • 在不带--attachable标记创建ingress网络,这意味着只有swarm集群可以使用,单个容器实例是不能使用的。你可以使用自定义带有--attachable标记overlay网络来连接单体容器实例。这使运行在不同Docker守护进程上的独立容器能够进行通信,而无需在单独的Docker守护进程主机上设置路由。

Publish ports(设置对外端口)

标记值 描述
-p 8080:80 默认协议Tcp,在容器内的80端口,在overlay网络上用的8080端口(对外)
-p 8080:80/udp 指定协议udp,,在容器内的80端口,在overlay网络上用的8080端口(对外)
-p 8080:80/sctp 指定协议sctp,,在容器内的80端口,在overlay网络上用的8080端口(对外)
-p 8080:80/tcp -p 8080:80/udp 使用tcp和udp协议,在容器内的80端口,在overlay网络上用的8080端口(对外)

2、Container discovery (容器自我发现)

  • 对于大多数情况,您应该理解服务名称,服务名称会负载均衡到服务后面的所有容器(也可以理解为tasks)上。为了得到服务后面的所有tasks(容器),要做一次tasks的dns查找<service-name>。

Macvlan

  • 一些应用程序,尤其遗留的应用程序或者监控网络传输的应用程序,期望直接连接物理网络。在这种情况下,你可以使用Macvlan网络驱动分配一个MAC地址到每一个容器虚拟网络接口上,使它看起来像一个物理网络接口直接连接到另一个物理网络接口上。在这种情况下,你需要在你的宿主机上指明一个物理网络接口使用Macvlan网络,同时指定Macvlan子网络和网关。你也可以使用不同的物理网络接口来隔离你的Macvlan网络。请注意一下几点:

1、由于IP地址的耗尽或者VLAN扩展而意外损耗网络是不可避免的,在这种情况下你的网络中,会出现大量不合理的唯一MAC地址。

2、你的网络设备需要能处理混杂模式,一个物理网卡,可以被分配多个MAC地址。

3、如果你的应用程序使用桥接(单个容器实例)或者overlay网络(多个docker主机的通信),从长远角度来看,这些解决方案也许是更好。

Create a macvlan network (创建一个Macvlan网络)

  • 当你创建一个Macvlan网络,它既可以在桥接模式下,又可以在802.1q中继桥接模式下。

1、在桥接模式下,Macvlan通信是通过主机上的物理网卡进行传输的。

2、在802.1q中继网络模式下,docker会在fly上创建一个子接口,通信会在这种情况下进行传输。它允许你控制路由和过滤更多等级的网络。

1、Bridge mode(桥接模式)

  • 要创建与给定物理网络接口桥接的Macvlan网络,使用带有--driver macvlan 选项 docker network create 命令.你也需要指定parent,parent是通过docker主机进行传输的通信接口。
$ docker network create -d macvlan \
  --subnet=172.16.86.0/24 \
  --gateway=172.16.86.1  \
  -o parent=eth0 pub_net
  • 如果你需要从Macv网络中过滤一些IP地址,当你已经使用一些网络地址,你可以使用--aux-addresses选项:
$ docker network create -d macvlan  \
  --subnet=192.168.32.0/24  \
  --ip-range=192.168.32.128/25 \
  --gateway=192.168.32.254  \
  --aux-address="my-router=192.168.32.129" \
  -o parent=eth0 macnet32

2、802.1q trunk bridge mode(中继桥接网络)

  • 使用一个包含小数的父接口名称,例如:eth0.50,
    Docker会将其解释为eth0的子接口,并自动创建子接口。
$ docker network  create  -d macvlan \
    --subnet=192.168.50.0/24 \
    --gateway=192.168.50.1 \
    -o parent=eth0.50 macvlan50

3、Use an ipvlan instead of macvlan(使用一个ipvlan代替macvlan网络)

  • 在以下示例中,你仍然可以使用L3桥接。你也可以是用ipvlan代替,得到一个L2桥接。指明-o ipvlan_mode=l2。
$ docker network create -d ipvlan \
    --subnet=192.168.210.0/24 \
    --subnet=192.168.212.0/24 \
    --gateway=192.168.210.254  \
    --gateway=192.168.212.254  \
     -o ipvlan_mode=l2 ipvlan210

Use IPv6

  • 如果你设置docker使用IPv6,你也可以IPv4和IPv6的Macvlan网络。
$ docker network  create  -d macvlan \
    --subnet=192.168.216.0/24 --subnet=192.168.218.0/24 \
    --gateway=192.168.216.1  --gateway=192.168.218.1 \
    --subnet=2001:db8:abc8::/64 --gateway=2001:db8:abc8::10 \
     -o parent=eth0.218 \
     -o macvlan_mode=bridge macvlan216

以上内容是对docker 网络内容的相关翻译和自己的理解。

相关文章

网友评论

    本文标题:docker network

    本文链接:https://www.haomeiwen.com/subject/faaaqqtx.html