Skip to content

Docker网络


Docker网络的容器互联是横向的,各个容器的地位平等;与宿主机进行端口映射的容器互联是纵向的。当互联时,通过容器的IP映射,我们只需要知道容器名称即可完成网络连接,这实质上是绕过了IP的端口转发。

Docker网络通讯中,只有在同一个网络的容器可以进行网络连接与通讯,如果对处于不同网络的容器进行连接,docker会提示报错。

核心概念

Docker中有三个核心概念,分别是沙盒(Sandbox)、网络(Network)和端点(Endpoint)。

  • 沙盒

    通过沙盒可以使容器实现独立的网络环境。沙盒提供了虚拟网络栈,包括Socket、Route Table、Firewall等。
    实现的独立的网络环境,也就是对宿主机和容器的网络隔离。
  • 网络

    通过网络可以实现安全的通讯环境。用于容器内部的通讯。
    通过网络可以构建虚拟子网,虚拟子网同宿主机网络之间也相互隔离。
  • 端点

    通过端点可以进行网络与网络之间的数据传输。
    容器端点同网络端点相连接便可以进行数据传输。

内部驱动

Docker有五种网络驱动。简单记忆可以通过连接适用性的广度来:无驱动=>Macvlan驱动=>主机驱动=>桥接驱动=>覆盖驱动

  1. Bridge Driver(桥接驱动)
    • 桥接网络是 Docker 默认的网络驱动程序,它为每个容器分配一个独立的 IP 地址,使得容器可以通过桥接接口与主机通信。容器间可以互相通信,也可以通过主机暴露的端口与外部通信。
  2. Host Driver(主机驱动)
    • 使用主机网络驱动程序时,容器共享主机的网络命名空间,可以直接使用主机上的网络资源和接口,使得容器与主机共享网络栈。这种驱动程序可以提高网络性能,但容器之间的隔离性会降低。
  3. Overlay Driver(覆盖驱动)
    • 覆盖网络驱动程序允许在跨多个 Docker 守护程序和主机之间创建网络,提供了跨主机通信的能力。它适用于跨多个节点的容器通信和集群部署。
  4. Macvlan Driver(MacVLAN 驱动)
    • MacVLAN 驱动程序允许容器直接绑定到物理网络的子接口,使得容器可以拥有独立的 MAC 地址。这种驱动程序适用于需要直接与物理网络进行交互的应用程序,提供了更高的网络性能和更好的隔离性。
  5. None Driver(无驱动)
    • 当使用无驱动程序时,容器不会附加到任何网络,它将没有网络接口。这意味着容器将与外部网络隔离,只能与自己的文件系统进行通信,适用于一些特殊的使用场景。

容器间通讯

通过Docker network,我们可以使得容器与容器之间进行通讯。打通了容器间通讯的容器也更符合开闭原则,使得原本单独的积木能组装起来。

具体指令,我们通过docker create / docker run的指令中添加--link选项。容器间的通讯是针对容器的,所以这种方法适用于一个是容器一个是镜像的情况。

docker run -d --name <alias> --link <container> <image-name / imageID>

我们只需要将容器的别名填入到连接地址中,就可以连接容器了,底层的IP映射等工作都由Docker来完成。

端口暴露

在容器层面,服务通讯往往需要暴露端口。拿Mysql为例,其需要暴露的端口就是3306

docker run -d --name mysql --expose 23306 mysql:latest

通过docker ps可以查看容器情况,在port列我们可以看到具体暴露的端口以及协议

网络管理

我们使用docker run时,会自动使用底层的Bridge Driver创建默认的桥接网络,如果不指定网络的话默认都会连接到一个桥接网络上。而同一个容器是通讯的前提,这与计算机网络是一样的,不同主机只有在同一个子网下才能互相访问

通过运行docker inspect 命令,我们可以看到容器对应的networkSettings以及bridge信息。

network相关指令

通过docker ps可以查看network网络和映射情况

docker ps

创建网络。-d是指定网络驱动类型,上文有所提及

docker network create -d <driver type> <network-name>

查看网络

docker network ls

容器创建时指定要加入的网络。通过--network可指定容器加入的网络

docker run -d --name xxx --network <network-name> ooo:ooo

网络映射。通过-p选项指定,p是pulish的缩写

docker run -d --name xxx -p 80:80 -p 443:443 ooo:ooo

* -p <监听IP>:<宿主机端口>:<容器端口>,默认监听IP为0.0.0.0,只传入两个参数指定的是<宿主机端口>:<容器端口>,比如 -p 3000:80 表示将容器的80端口映射到宿主机的3000端口

docker提供的网络映射指令,完成的确实是宿主机和容器之间端口的映射,不过实质上是对容器端口和虚拟的Linux OS端口的映射(Docker运行在Linux之上),真正从容器到原生的宿主机还需要通过Linux到Windows / Mac的端口映射。

而在Docker提供的Docker Desktop和Docker for Mac这两个软件中,从Linux到宿主机的端口映射会帮我们自动完成,所以我们运行上述操作后,在宿主机就可以直接看到映射结果,这也是为什么tips中直接写的是宿主机端口:容器端口,最终的效果就是如此。

聪明的你可能想到了,在较低版本使用virtualbox的情况下,就只能通过手动的端口映射配置了。