Docker 网络、bridge 和 网络模式

557 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 14 天,点击查看活动详情

Docker网络

docker 容器是一块具有隔离性的虚拟系统,容器内可以有自己独立的网络空间,

  • 多个容器之间是如何实现通信的呢?
  • 容器和宿主机之间又是如何实现的通信呢?
  • 使用-p参数是怎么实现的端口映射?

带着我们就这些问题,我们来学习一下docker的网络模型,最后我会通过抓包的方式,给大家演示一下数据包在容器和宿主机之间的转换过程。

网络模式

我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式:

  • bridge模式,使用--net=bridge指定,默认设置

  • host模式,使用--net=host指定,容器内部网络空间共享宿主机的空间,效果类似直接在宿主机上启动一个进程,端口信息和宿主机共用。

  • container模式,使用--net=container:NAME_or_ID指定

指定容器与特定容器共享网络命名空间

  • none模式,使用--net=none指定

网络模式为空,即仅保留网络命名空间,但是不做任何网络相关的配置(网卡、IP、路由等)

bridge模式

那我们之前在演示创建docker容器的时候其实是没有指定的网络模式的,如果不指定的话默认就会使用bridge模式,bridge本意是桥的意思,其实就是网桥模式,那我们怎么理解网桥,如果需要做类比的话,我们可以把网桥看成一个二层的交换机设备,我们来看下这张图:

交换机通信简图

image.png

网桥模式示意图

image.png

有了网桥之后,那我们看下 docker 在启动一个容器的时候做了哪些事情才能实现容器间的互联互通

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

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

那整个过程其实是docker自动帮我们完成的,清理掉所有容器,来验证。