5 Docker 容器网络4种模式

目录

1 Bridge 模式

1.1 概述

1.2 网络模式指令

1.3 网桥相关指令

1.4 创建自定义网络

1.5 同一子网下的容器间通信

2 Host 模式

3 None 模式

4 Container 模式


1 Bridge 模式

1.1 概述

当 Docker 启动时,会自动在主机上创建一个名为 docker0 的虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。

同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1,掩码为 255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。

当创建一个 Docker 容器的时候,同时会创建一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

5 Docker 容器网络4种模式

接下来测试下上述内容的正确性:

  • 查看docker0网桥:brctl show docker0,此时网桥上空空如也,没有挂载任何veth

5 Docker 容器网络4种模式

  •  查看宿主机ip,可找到docker0的ip:ip addr

5 Docker 容器网络4种模式

  •  分别创建2个容器,网络模式为默认

5 Docker 容器网络4种模式

  • 查看容器ip发现:容器ip与docker0的ip在同一网段下

 5 Docker 容器网络4种模式

  • 此外:docker0下挂载了2个容器分别对应的veth

5 Docker 容器网络4种模式

由此发现:docker0作为桥梁,一方面连接容器与容器,另一方面连接容器与宿主机,实现其通通信。

1.2 网络模式指令

  • 查看docker网络模式指令:docker network ls
  • 查看某个网络模式的具体信息:docker  inspect 网络模式id

1.3 网桥相关指令

  • 安装网桥管理工具包:yum install bridge-utils
  • 查询网桥docker0的信息:brctl show docker0
  • 查看ip信息:ip a

1.4 创建自定义网络

  • 创建一个自定义网络(默认bridge模式):docker network create test
  • 创建一个容器,并且把该容器连接到目标网络上:docker run -id --name=ng1 --network test nginx:1.16
  • 创建容器时,即便不指定网络,也会默认连接到docker0这个bridge类型的网络上
  • bridge模式是Docker中的默认网络模式

1.5 同一子网下的容器间通信

这里先直接给出结论

  • 如果容器间直接通过ip访问,在创建容器时可以不通过 --network 参数来指定该容器的网络模式
  • 如果容器间要通过主机名访问,在创建容器时,必须要自定义网络模式

详细过程如下

  1. 进入主机名称为my_box的容器中,在该容器中可以使用常用的Linux指令(使用的默认docker0网桥):docker run -it --hostname=my_box busybox sh
  2. 上面的指令,是想分别创建两个busybox容器,然后ifconfig看一下这两个容器是否在同一个子网下(可相互通信),结果是可以的(如果退出了busybox容器后再想进去的话,exec指令最后要用sh而不是bash!)~
  3. 这时候问题来了:容器间访问难道要直接通过ip吗?是否可以通过主机名称访问呢?
  4. 于是,通过在busybox其中一个容器中输入“hostname”,获取到当前容器的主机名后,让另一个容器去ping这个主机名,结果竟然不能访问!
  5. 这就说明:默认的桥接模式(使用网桥docker0)并不具备DNS解析能力(将主机名解析为目标容器的ip地址)
  6. 接下来重新创建2个容器并且自定义网桥,看看是否能够通过主机名实现同一子网下容器之间的访问,这下就可以啦,如下图~
  7. docker run -it --hostname=my_box2 --network=test busybox sh
  8. docker run -it --hostname=my_box3 --network=test busybox sh

5 Docker 容器网络4种模式

2 Host 模式

  • 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。
  • 也就是说:容器不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
  • 但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的
  • 在默认模式下,创建一个容器(部署redis)需要指定端口映射(宿主机端口到容器端口),然而使用host模式则不需要进行端口映射,因为用的端口就是宿主机端口

  • 通过host网络方式启动一个容器部署redis:docker run -id --name=r1 --net=host redis
  • 查看宿主机被占用的端口,发现6379端口被redis占用:ss -antp

3 None 模式

  • 使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
  • 这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

4 Container 模式

  • 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。
  • 新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。
  • 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
  • 创建容器,网络命名空间与现存的容器共用一个:

docker run -id --name=容器名 --net=container:其他容器id 镜像名字 

上一篇:mysql+keepalived+orchestrator 构建高可用mysql


下一篇:Java面试题2020中高级,docker0网桥