3. docker网络模式

1 基本概念

网络命名空间
Linux 网络命名空间是内核中隔离的网络栈,具有自己的接口,路由和防火墙规则。它负责容器和 Linux 的安全方面,用于隔离容器。

在网络术语中,它们类似于 VRF,它将主机内的网络控制和数据隔离。网络命名空间确保同一主机上的两个容器无法相互通信,甚至无法与主机本身通信,除非通过 Docker 网络进行配置。通常,Docker网络驱动程序为每个容器实现单独的命名空间。但是,容器可以共享相同的网络命名空间,甚至可以是主机网络命名空间的一部分。主机网络命名空间容纳主机接口和主机路由表。此网络命名空间称为全局网络命名空间。

虚拟以太网设备
虚拟以太网设备或简称 veth 是 Linux 网络接口,充当两个网络命名空间之间的连接线。veth 是一个全双工链接,每个命名空间中都有一个接口。一个接口中的流量被引导出另一个接口。Docker 网络驱动程序利用 veth 在创建 Docker 网络时提供名称空间之间的显式连接。当容器连接到 Docker 网络时,veth 的一端放在容器内(通常被视为 ethX 接口),而另一端连接到 Docker 网络。

2 Bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,默认主机上启动的Docker容器会连接到这个虚拟网桥上,从docker0子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker 将 veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过brctl show命令查看。

bridge模式是 docker 的默认网络模式,不写--network参数,就是bridge模式。使用docker run -p时,docker 实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。我们也可以创建自定义bridge以满足个性化的网络需求。

3 Host 模式

docker run ... --network host
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口,主机名也是使用宿主机的。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

host 模式的容器可以访问主机上的其他任一容器。

4 None模式

docker run ... --network none
使用none模式,Docker 容器拥有自己的 Network Namespace,但是,并不为Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。

5 Container模式

docker run ... --network container:已运行的容器名称|ID


在创建容器时通过参数--network container:已运行的容器名称|ID指定,处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。
Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围、主机名等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。

6 Overlay模式

overlay 使用 Swarm 分布式控制面板,在非常大规模的集群中提供集中化管理、稳定性和安全性。
启动docker swarm之后会在host上启动了2个端口,docker_gwbridgeingress:

  • ingress是overlay网络, 用来与其他容器跨host通信.
  • docker_gwbridgebridge模式的网络,通过bridge方式提供容器与host的通信,以及与外部网络通信
  1. 容器的网络命名空间与overlay网络的网络命名空间通过一对veth pair连接起来,当容器对外通信时,veth pair起到网线的作用,将流量发送到overlay网络的网络命名空间中。
  2. 容器的veth pair对端veth2与vxlan设备通过br0这个Linux bridge桥接在一起,br0在同一宿主机上起到虚拟机交换机的作用,如果目标地址在同一宿主机上,则直接通信,如果不再则通过设置在vxlan1这个vxlan设备进行跨主机通信。
  3. vxlan1设备上会在创建时,由docker daemon为其分配vxlan隧道ID,起到网络隔离的作用。
  4. docker主机集群通过key/value存储共享数据,在7946端口上,相互之间通过gossip协议学习各个宿主机上运行了哪些容器。守护进程根据这些数据来在vxlan1设备上生成静态MAC转发表。
  5. 根据静态MAC转发表的设置,通过UDP端口4789,将流量转发到对端宿主机的网卡上。
  6. 根据流量包中的vxlan隧道ID,将流量转发到对端宿主机的overlay网络的网络命名空间中。
  7. 对端宿主机的overlay网络的网络命名空间中br0网桥,起到虚拟交换机的作用,将流量根据MAC地址转发到对应容器内部。

7 Macvlan模式

docker run ... --network macvlan网络名
macvlan 不使用 Linux 网桥进行隔离,而是简单地与 Linux 以太网接口或子接口相关联,以强制实现网络之间的分离以及与物理网络的连接。
macvlan 驱动程序使用父接口的概念。此接口可以是物理接口,例如 eth0,用于 802.1q VLAN 标记的子接口,如 eth0.10(.10 表示 VLAN 10),或者甚至是bond接口。macvlan 子接口和原来的主接口是完全独立的,可以单独配置 MAC 地址和 IP 地址,而 VLAN 子接口和主接口共用相同的 MAC 地址。VLAN 用来划分广播域,而 macvlan 共享同一个广播域
Docker只支持macvlan的bridge模式,这种模式下,模拟的是 Linux bridge 的功能,但比 bridge 要好的一点是每个接口的 MAC 地址是已知的,不用学习。所以,这种模式下,子接口之间就是直接可以通信的。

Macvlan 需要物理网口开启混杂模式,这样才能接受非网卡mac 地址的数据包。
临时开启:
ip link set [interface] promisc on
永久开启:
vim /etc/sysconfig/network-scripts/ifcfg-eth1
PROMISC=yes

7.1 不同host主机,相同macvlan网络的通信


两个host创建相同的macvlan网络,将container加入进去

docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=eth0 mac1

7.2 不同host主机,不同macvlan网络的通信


由于 macvlan 网络会独占物理网卡,也就是说一张物理网卡只能创建一个 macvlan 网络,如果我们想创建多个 macvlan 网络就得用多张网卡,使用子接口解决这个问题。

将不同macvlan绑定到不同的子接口上,不同网段的互通借助外部3层IP网关解决

docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=eth0.10 mac10
docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=eth0.20 mac20

8 IPVlan模式

IPVlan 和 macvlan 类似,都是从一个主机接口虚拟出多个虚拟网络接口。一个重要的区别就是所有的虚拟接口都有相同的 mac 地址,而拥有不同的 ip 地址。因为所有的虚拟接口要共享 mac 地址,所有有些需要注意的地方:

  • DHCP 协议分配 ip 的时候一般会用 mac 地址作为机器的标识。这个情况下,客户端动态获取 ip 的时候需要配置唯一的 ClientID 字段,并且 DHCP server 也要正确配置使用该字段作为机器标识,而不是使用 mac 地址

NOTE: containers不能ping通底层host接口,Linux会将他们隔离开来。

两种模式
ipvlan 有两种不同的模式:L2 和 L3。一个父接口只能选择一种模式,依附于它的所有虚拟接口都运行在这个模式下,不能混用模式。
L2模式
ipvlan L2 模式和 macvlan bridge 模式工作原理很相似,父接口作为交换机来转发子接口的数据。同一个网络的子接口可以通过父接口来转发数据,而如果想发送到其他网络,报文则会通过父接口的路由转发出去。
L3模式
L3 模式下,ipvlan 有点像路由器的功能,它在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同,即使虚拟机/容器不在同一个网络,也可以互相 ping 通对方,因为 ipvlan 会在中间做报文的转发工作。

9 网络配置

docker network COMMAND

Commands:
  connect     将container连接到一个network上
  create      创建一个network
  disconnect  将container与network解除连接
  inspect     显示network的详细信息
  ls          显示当前已创建的所有network
  prune       删除所有没有被使用的network
  rm          删除1个或多个network

9.1 docker network create

docker network create [OPTIONS] network名字 创建一个新的网络

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver               网络模式,默认是bridge,可选ipvlan、macvlan、overlay
      --gateway              IPv4 或 IPv6 网关,不配置docker会指定subnet第1个地址X.X.X.1,如配置ip-range,指定ip-range第1个地址X.X.X.0
      --ingress              overlay模式,作为与其他容器跨host通信的网络时配置
      --internal             限制外部访问网络
      --ip-range             执行容器的IP范围,格式同subnet参数,容器不配置--ip参数,默认从这段分配ip
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              设置特殊参数,eg:macvlan/ipvlan模式设置主机接口,parent=eth0/br0...
      --scope                Control the network's scope
      --subnet               网络地址范围,eg:172.17.0.0/16

例子:
创建bridge模式的br0网络

docker network create \
  --driver=bridge \
  --subnet=172.28.0.0/16 \
  --ip-range=172.28.5.0/24 \
  --gateway=172.28.5.254 \
  br0

创建macvlan模式的my-macvlan-net网络,host物理接口是eth0

docker network create -d macvlan \
  --subnet=172.16.86.0/24 \
  --gateway=172.16.86.1 \
  -o parent=eth0 \
  my-macvlan-net

9.2 docker network connect

docker network connect [OPTIONS] NETWORK名字 CONTAINER名字 将容器连接到网络,可以按名称或ID连接容器。连接后,容器可以与同一网络中的其他容器通信。

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      网络的驱动程序选项
      --ip string               指定IPv4地址
      --ip6 string              指定IPv6地址
      --link list               Add link to another container
      --link-local-ip strings   指定IPv6 link-local地址

例子:

docker network connect --ip 10.10.36.122 multi-host-network container2

9.3 docker network disconnect

docker network disconnect [OPTIONS] NETWORK名字 CONTAINER名字 断开容器与网络的连接

9.4 docker network inspect

docker network inspect [OPTIONS] NETWORK名字1 [NETWORK名字2...] 返回有关一个或多个网络的信息。默认情况下,此命令将所有结果呈现在JSON对象中。

10 docker run --link

容器需要使用另外一些容器提供的服务,使用--link建立两个容器间通信。link是单向的,相当于在容器内添加到目标容器name或alias的host解析,可以通过容器name或alias访问目标容器。
--link=name-or-id[:alias]alias是可选项,是为目标容器起的别名

你可能感兴趣的:(3. docker网络模式)