Docker网络
Docker网络的容器互联是横向的,各个容器的地位平等;与宿主机进行端口映射的容器互联是纵向的。当互联时,通过容器的IP映射,我们只需要知道容器名称即可完成网络连接,这实质上是绕过了IP的端口转发。
Docker网络通讯中,只有在同一个网络的容器可以进行网络连接与通讯,如果对处于不同网络的容器进行连接,docker会提示报错。
核心概念
Docker中有三个核心概念,分别是沙盒(Sandbox)、网络(Network)和端点(Endpoint)。
沙盒
通过沙盒可以使容器实现独立的网络环境。沙盒提供了虚拟网络栈,包括Socket、Route Table、Firewall等。 实现的独立的网络环境,也就是对宿主机和容器的网络隔离。
网络
通过网络可以实现安全的通讯环境。用于容器内部的通讯。 通过网络可以构建虚拟子网,虚拟子网同宿主机网络之间也相互隔离。
端点
通过端点可以进行网络与网络之间的数据传输。 容器端点同网络端点相连接便可以进行数据传输。
内部驱动
Docker有五种网络驱动。简单记忆可以通过连接适用性的广度来:无驱动=>Macvlan驱动=>主机驱动=>桥接驱动=>覆盖驱动
- Bridge Driver(桥接驱动)
- 桥接网络是 Docker 默认的网络驱动程序,它为每个容器分配一个独立的 IP 地址,使得容器可以通过桥接接口与主机通信。容器间可以互相通信,也可以通过主机暴露的端口与外部通信。
- Host Driver(主机驱动)
- 使用主机网络驱动程序时,容器共享主机的网络命名空间,可以直接使用主机上的网络资源和接口,使得容器与主机共享网络栈。这种驱动程序可以提高网络性能,但容器之间的隔离性会降低。
- Overlay Driver(覆盖驱动)
- 覆盖网络驱动程序允许在跨多个 Docker 守护程序和主机之间创建网络,提供了跨主机通信的能力。它适用于跨多个节点的容器通信和集群部署。
- Macvlan Driver(MacVLAN 驱动)
- MacVLAN 驱动程序允许容器直接绑定到物理网络的子接口,使得容器可以拥有独立的 MAC 地址。这种驱动程序适用于需要直接与物理网络进行交互的应用程序,提供了更高的网络性能和更好的隔离性。
- 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的情况下,就只能通过手动的端口映射配置了。