1. 单机中的docker网络

在你安装Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡, 这就将所有容器和本地主机都放到同一个物理网络。

[root@pdai ~]# docker network ls
 NETWORK ID          NAME                DRIVER              SCOPE
 b8c5abdb0bec        bridge              bridge              local 
 84e86bc93121        host                host                local 
 8e521527a897        none                null                local

Docker 安装时会自动在 host 上创建三个网络:nonehost和bridge。我们看下docker0 网桥: (brctl可以通过yum install bridge-utils安装)

[root@pdai ~]# brctl show 
bridge name     bridge id               STP enabled     interfaces 
docker0         8000.0242703f9d02       no              veth0004826 
                                                        veth4ad3278

Docker 在创建一个容器的时候,会执行如下操作:

  • 创建一对虚拟接口/网卡,也就是veth pair,分别放到本地主机和新容器中;
  • 本地主机一端桥接到默认的docker0或指定网桥上,并具有一个唯一的名字,如 vethxxxxx
  • 容器一端放到新容器中,并修改名字作为eth0,这个网卡/接口只在容器的名字空间可见;
  • 从网桥可用地址段中(也就是与该bridge对应的network)获取一个空闲地址分配给容器的eth0,并配置默认路由到桥接网卡 vethxxxx

如果不指定--network,创建的容器默认都会挂到docker0上,使用本地主机上docker0接口的IP作为所有容器的默认网关。

当有多个容器创建后,容器网络拓扑结构如下:

2. docker网络模式

2.1 bridge模式

桥接模式(bridge)是Docker的默认网络模式。当Docker进程启动的时候,它会在主机上创建一个名称为docker0的虚拟网桥。主机 上启动的docker容器会连接到这个虚拟网桥上,这个虚拟网桥的工作方式类似于一个物理交换机,使得主机上的所有容器都通过交换机 连接在一个二层网络中。 这种模式下,Docker会为每个新创建的容器分配独立的Network Namespace和IP段等,同时文件系统、进程等也是隔离的。容器内部 会有一个虚拟网卡,名为eth0,容器之间可以通过这个虚拟网卡和内部的IP地址进行通信。另外,从docker0子网中分配一个IP给容器 使用,并设置docker0的IP地址为容器的默认网关。

图中颜色相同的两组虚拟网卡分别是两对虚拟网卡对。

使用:--net=bridge 指定
例:docker run -d -name tomcat01 --net=bridge -p 8085:80 tomcat:latest

2.2 host模式

host网络模式将容器直接融入到主机的网络栈中,使得容器直接使用主机的网络接口和IP地址。在这种模式下,容器不会获得一个独立 的Network Namespace,而是和宿主机共用一个Network Namespace。因此,容器内部的服务可以使用宿主机的网络地址和 端口,无需进行NAT转换,网络性能较好。host模式因为和宿主主机共享network namespace,会有可能出现端口冲突的情况。 典型场景是需要容器与宿主机共享网络资源或者容器需要快速访问宿主机网络服务的场景。例如,如果需要在容器内部运行一些网络 相关的应用,如网络监控、日志收集等。

由于容器与宿主机共用一个网络栈,因此容器的网络隔离性较差,可能存在安全隐患。如果需要在不同主机上运行容器并实现跨主机 通信,则不能使用host网络模式。

使用:--net=host 指定

2.3 none模式

Docker的none网络模式是Docker提供的一种特殊网络模式,它将容器与宿主机隔离开来,不提供任何网络能力。在这种模式下,容器 内部没有网卡、IP地址、路由等信息,只有一个回环网络(loopback)接口。这意味着容器不能访问外部网络,也不能被外部网络访问。

none网络模式通常用于一些特殊场景,比如需要在容器内部运行一些独立的、与网络无关的应用程序,或者需要进行一些网络调试。 由于容器与外部网络完全隔离,这种模式可以增加容器的安全性。

使用:--net=none 指定

2.4 container模式

该模式≈bridge+host的混合模式,指定一个容器以bridge方式启动,后面容器启动时指定网络模式为container,它们自动共享第一 个容器的网络资源。

  • 新创建的容器,仅同前面已存在的容器,共享网络空间,不与宿主机共享网络。
  • 新创建的容器,不会有自己的虚拟网卡和IP,后面新创建容器的网络资源用的是上一个容器的。
  • 新创建的容器,仅仅是网络和第一个容器共享,其他资源彼此还都是相互隔离的。

第一个指定容器服务一旦停掉,后续的容器也没有办法继续运行。

使用:–-net={容器id 或容器name} 指定

3. docker网络驱动

Docker使用Linux内核的一些特性来实现其网络功能,而这些功能是通过不同的网络驱动程序来实现的。Docker支持多种网络驱 动程序,每种驱动程序都有其特定的用途和场景。通过docker network ls命令可以看到默认情况下每种网络模式的驱动程序。

  • bridge:Docker的默认网络驱动程序。它会在宿主机上创建一个虚拟网桥(通常是docker0),并将容器连接到这个网桥上。 容器之间以及容器与宿主机之间可以通过这个网桥进行通信。bridge模式适用于单个宿主机上的容器互联场景。

  • host:host网络驱动程序将容器直接融入主机的网络栈中,容器将共享主机的网络接口和IP地址。这意味着容器内部的服务可以 直接使用主机的网络地址和端口,无需进行NAT转换。host模式适用于需要容器与宿主机共享网络资源的场景,但需要注意安全性和隔 离性问题。

  • overlay:overlay网络驱动程序用于创建跨多个Docker守护进程的分布式网络。它通过内置的DNS服务实现容器之间的跨主 机通信。overlay模式适用于需要构建分布式应用程序的场景,可以让容器在不同宿主机之间进行通信。

  • macvlan:macvlan网络驱动程序允许容器使用宿主机的物理网络接口,并为其分配一个MAC地址。这样,容器可以像虚拟机 一样直接连接到物理网络上,并与其他设备通信。macvlan模式适用于需要容器直接访问物理网络的场景。

  • ipvlan:ipvlan是另一种类似于macvlan的网络驱动程序,但它基于IP地址而不是MAC地址来分配网络。ipvlan模式提供 了更好的扩展性和灵活性,适用于不同的网络场景。

  • none:none网络驱动程序不提供任何网络功能,容器将处于完全隔离的状态。它通常用于一些特殊场景,如运行与网络无关 的应用程序或进行网络调试。

4. docker网络配置

docker network create命令用于在docker中创建一个新的网络,这个命令允许指定网络名称,驱动,以及子网配置等选项, 用于满足不同的网络需求。

docker network create \  
  --driver bridge \                          # 指定驱动
  --subnet=172.25.0.0/16 \                   # 指定子网
  --gateway=172.25.0.1 \                     # 指定网关
  --ip-range=172.25.50.0/24 \                # 指定网络的ip范围
  --aux-address="my-router=172.25.50.10" \   # 指定网络的辅助地址
  my-custom-network                          # 网络名称