Docker 网络基础

背景知识

  • 桥接模式:虚拟机直接连接外部的物理网络,主机起到了网桥的作用,虚拟机可以直接访问外网,并且是透明的。
  • NAT 模式:NAT 服务器和 DHCP 服务器会对 IP 进行地址转换,虚拟机通过共享主机 IP 可以访问外部网络,而外网是不能访问虚拟机的。

作用

  • 容器之间的互连和通信以及端口映射
  • 容器 IP 变动时候可以通过服务名直接网络通信而不受到影响

docker0 虚拟网桥

  • Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为 docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络
  • Docker 默认指定了 docker0 接口的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。 alt

docker0 具体如何工作?

  • docker0 创建一对对等虚拟设备接口一个叫veth、一个叫eth0,成对匹配
  • 整个宿主机的网桥模式都是 docker0,类似于一个交换机有一堆接口,每个接口叫 veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此连通,这样一对接口叫 veth pair
  • 每个容器实例内部也有一块网卡,每个接口叫 eth0。docker0 上面的每个 veth 匹配某个容器实例内部的 eth0,两两配对,一一匹配
  • 这样将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一网络下,会从这个网关下各自拿到分配的 IP,此时两个容器的网络是互通的

alt


常用基础命令

名称 命令
查看网络 docker network ls alt
在外部 Docker 中查看网络源数据 docker network inspect 网络名称
在容器内部查看网络源数据 ip addr
创建自定义网络 docker network create 自定义的网络名称
删除网络 docker network rm 网络名称

注意

  • Docker 容器和 docker0 之间使用桥接的方式,docker0 再到宿主机则是通过 NAT 模式
  • Docker 容器内部的 IP 是有可能改变的,一般固定容器名称作为唯一指定


Docker 网络模式

bridge

  • 默认使用网桥模式为 bridge
  • Docker 使用 Linux 桥接,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。

host

  • 使用命令 --network host 指定
  • 容器将不会获得一个独立的 Network Namespace,而是和宿主机共有一个 Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的 IP 和端口,不再需要额外进行 NAT 转换,类似于桥接模式
  • 此时 docker 启动时如果指定 -p 端口映射,-p 设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增 alt

none

  • 使用命令 --network none 指定
  • 容器有独立的 network namespace,但并没有对其进行任何网络设置
  • 此 Docker 没有 veth pair、网卡、IP、路由等信息,只有 lo 本地回环地址。需要我们自己为 Docker 容器添加网卡、配置 IP 等 alt

container

  • 使用命令 --network container:NAME/容器ID 指定
  • 新建的容器和已经存在的一个容器共享一个网络 IP 配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的
  • 新建容器为 name1,指定的共享容器为 name2。此时,如果 name2 关闭了,name1 的共享网络连接也关闭了 alt

自定义网络模式

  • 创建自定义网络:docker network create 自定义的网络名称
  • 由于 Docker 容器内部的 IP 是有可能改变的,所以不能直接使用 IP 地址连接不同的 docker 容器。然而直接使用 容器名作为唯一指定 ping 不通。所以需要自定义网络模式,容器启动的时候通过“--network 自定义的网络名称” 连接。这样可以通过容器名称来通信了
  • 自定义网络本身维护好了主机名与ip的对应关系(ip和域名都能通)
名称 命令
创建自定义网络 alt
启动容器使用自定义网络 alt
进入 tomcat2 容器 ping tomcat1 ping tomcat1
进入 tomcat1 容器 ping tomcat2 ping tomcat2