Docker网络


docker0网卡

服务器安装了docker,就会有一个网卡docker0,docker0网卡使用nat直连到服务器的物理网卡。

evth-pair

evth-pari 是一种虚拟网络设备,是一对的虚拟设备接口,它们都是成对出现的,一端连着内核协议栈 ,一端彼此相连着,一个设备收到协议栈的数据发送请求后,会将数据发送到另一个设备上去,正因为这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备;OpenStack,Docker容器之间的连接, OVS的连接,都是使用 evth-pair 技术。

上图中,docker0扮演的角色可以比作容器依赖的路由器,容器不指定网络的情况下,都是通过docker0路由的,docker会给容器分配一个默认的可用ip,只要容器被删除,对应的evth-pari接口就没了 。docker中通过evth-pair连接到docker0的网络连接模式称之为桥接模式,该模式下的任意容器之间是可以相互ping通的。

桥接到docker0网卡的方式缺点也很明显,无法预知容器IP,且在容器重启后IP可能会发生变化,导致容器内的应用之间存在依赖时,不方便配置,如数据库IP等。

docker0 IP分配方式

需要注意的是,docker0分配IP的方式是按顺序分配,如已经分配了容器A(172.17.0.1)、容器B(172.17.0.2),下一个容器C的IP为172.17.0.3,如果此时容器B停止或被删除,再新建容器D时,其IP为172.17.0.2。

link方式连接

容器桥接到docker0的网络连接方式显然不能满足部署需求,如果能使用容器名进行网络连接,就不必担心容器重启后IP改变的问题了,docker提供了link方式的网络连接;

docker run启动容器时使用--link选项连接到其它容器:命令示例:docker run -it --link <容器id或容器名>:[alias] centos

  • docker run -it --name=mycentos --link mysql-dev centos:启动一个名为mycentos的容器,且连接到名为mysql-dev的容器,此时在mycentos容器内可以使用ping mysql-dev的方式ping通名为mysql-dev的容器
  • docker run -it --name=mycentos --link mysql-dev:db centos:alias是容器在link模式下的别名,同上,在mycentos容器内还可以使用ping db的方式ping通名为mysql-dev的容器

link方式连接原理

在源容器的hosts文件写入目标容器名、目标容器link下的别名、目标容器id,均指向目标容器的IP,当目标容器的IP发生变化时,hosts文件的配置也跟着发生变化,这是通过docker容器的环境变量完成的。

缺点

  • 显然的,源容器通过link方式连接到目标容器时,可以通过容器名访问目标容器,反过来则不行,因为是通过写hosts的形式去实现的。
  • 当目标容器被删除时,源容器的hosts配置还存在,此时新的容器“占据”旧目标容器IP时(依据docker0的 IP分配方式),源容器的hosts配置并不会发生改变,故而连接到新的容器。

官方已经已经不推荐使用link方式去设计容器的网络了。

自定义网络(核心)

既然docker通过容器模拟了一个小型的linux操作系统,自然也少不了计算机网络。docker提供docker network命令来管理网络,使用docker创建网络的主要参数有:网络名称,网络模式,子网,网关。

docker的网络模式

  • bridge

    桥接模式,docker默认的网络模式,该模式下容器桥接到docker0网卡

  • none

    不配置网络

  • host

    和宿主机共享网络,即使用宿主机的IP端口

  • container

    容器网络连通(用得少,局限大)

网络管理

docker network create

作用:创建网络;

命令格式:docker network create [options] <网络名>

常见命令格式:docker network create --driver <网络模式> --subnet <子网> --gateway <网关地址> <网络名称>

常用option选项:

  • --driver:指定网络模式,不指定默认为桥接模式(driver),一般使用桥接模式较多
  • --subnet:指定子网,写法为网段 + 掩码,如10.0.0.0/16
  • --gateway:指定网关地址
  • --ip-range:指定ip网络内可动态分配的IP范围,写法为网段 + 掩码,如10.0.0.0/16

示例:docker network create --driver bridge --subnet 10.0.0.0/16 --gateway 10.0.0.254 mynet,该命令创建了一个网络,名称为”mynet”,网络模式为桥接模式(bridge ),子网为10.0.0.0/16,网关为10.0.0.254,此时宿主机网络情况如下

docker network ls

查看当前所有网络;常见命令格式:docker network ls [option]

示例:docker network ls -f 'driver=bridge':查看所有网络中网络模式为桥接的网络。

docker network inspect

查看网络详情;常见命令格式:docker network inspect <网络id或网络名称>

该命令可查看网络创建时的基本信息和使用该网络的容器信息等。

docker network rm

删除网络;常见命令格式:docker network rm <网络id或网络名称>

容器连接或断开网络

可以使用docker run新建容器时可使用--network--net将容器连接到指定的网络:docker run -it --net <网络id或网络名> centos,另一种便是使用docker network connect命令。

docker network connect

作用:将容器连接到网络;

常见的命令格式:docker network connect <网络id或网络名称> [options] <容器名>

option选项:

  • --alias :指定该容器在该网络中的别名
  • --ip:指定IP地址(常用)
  • --ip6:指定IPv6地址
  • --link:链接到另一个容器
  • --link-local-ip:添加容器的链接本地地址

docker network connect的选项几乎全都可在docker run时使用。

docker network disconnect

作用:将容器与网络断开;

常见的命令格式:docker network disconnect [option] <网络id或网络名称> <容器名>

断开条件:容器必须正在运行才能将其与网络断开连接;

option选项:

  • -f:强制断开容器与网络的连接

容器连接到网络之后,容器内都有一个默认的DNS服务器配置,这样任意容器之间均可通过容器名互相访问,而不需要像link方式般由hsots文件维护容器名与IP的关系。

停止、暂停或重启容器对网络的影响

暂停、重新启动和停止连接到网络的容器,容器在运行时会连接到其配置的网络:

  • 若未容器指定IP(动态IP),容器启动时自动获取网络内可分配的IP
  • 若未容器指定了IP(静态IP),容器启动时应用容器的 IP 地址,如果 IP 地址不再可用,则容器无法启动。

保证 IP 地址可用的一种方法:

使用--ip-range指定一个网络自动分配的IP的范围,使用--ip给容器指定该范围之外的IP地址(静态IP),可确保在此容器不在网络上时不会将 IP 地址提供给另一个容器。

如:docker network create --driver bridge --subnet 10.0.0.0/24 --ip-range 10.0.0.0/25 --gateway 10.0.0.254 mynet,创建一个网络名叫”mynet”,子网为10.0.0.0/24,可动态分配的地址范围为10.0.0.0/25,网关为10.0.0.254,新建容器A、容器B、容器C且都加入mynet网络,容器C使用--ip指定IP地址。