目录

目录

一、docker网络类型

二、查看容器网络

三、网络类型详解

1、host网络模式

2、bridge网络模式

2.1、bridge网络介绍

2.2、bridge网络工作原理

2.3、自定义bridge和默认bridge网络区别

2.4、bridge模式docker0网络更改

2.5、创建自定义bridge网络

3、none模式

3.1、none网络介绍

3.2、设置方式


一、docker网络类型

查看本地docker支持的网络类型

docker network ls

docker 配置网卡 docker 多网卡_docker

docker的6种网络模式:

  • bridge:默认网络驱动,用于单宿主机的docker容器和主机通信;
  • overlay:叠加网络,用于连接多个宿主机Docker进程管理的容器和swarm services;
  • macvlan:将容器的虚拟网卡直接连接在主机所在的物理网络上;
  • host:Docker 17.06+ 创建swarm services时支持,容器直接使用docker主机的网卡和网络;
  • none:禁用容器的网络,不连接任何网络,swarm services不支持该类型;
  • Network plugins:安装第三方网络插件,实现自定义的网络类型
     

二、查看容器网络

#查看my_nginx容器信息
docker inspect my_nginx

docker 配置网卡 docker 多网卡_桥接_02

#查看bridge网络信息
docker inspect bridge

docker 配置网卡 docker 多网卡_网络_03

 可以看到my_nginx容器处于bridge网络下

同时如下图可以看到每起一个容器,在宿主机网络都会新增一个veth-pair

docker 配置网卡 docker 多网卡_docker 配置网卡_04

三、网络类型详解

1、host网络模式

Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。

host模式类似于Vmware的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

如下图所示:容器与主机在相同的网络命名空间下面,使用相同的网络协议栈,容器可以直接使用主机的所有网络接口

docker 配置网卡 docker 多网卡_docker 配置网卡_05

 示例:

# 注:官方的nginx镜像里面不包含ip addr和vim命令,这里是基于官方nginx镜像安装了iproute2
#和vim重新commit了一个guianjun/mynginx:v2.0基础镜像,便于实验
docker run -itd --name my_nginx --net=host -p 80:80 guianjun/mynginx:v2.0 /bin/bash

docker ps -a


#在容器中执行ip addr命令,查看网络
docker exec -it my_nginx ip addr

docker 配置网卡 docker 多网卡_桥接_06

docker 配置网卡 docker 多网卡_网络_07

 

docker 配置网卡 docker 多网卡_网络_08

#可以在host网络信息里面查到,my_nginx容器已经处于hosts模式下
docker inspect host

docker 配置网卡 docker 多网卡_linux_09

可以看到容器my_nginx的网络配置与宿主机hosts的网络配置完全一样,在容器中可以看到host的所有网卡,并且连hostname也是跟宿主机一样的。从网络层面来看,host模式下的容器只是宿主机上的一个端口,比如这里的my_nginx容器映射的是宿主机上的80端口,那么可以根据宿主机ip+映射端口来实现对容器的访问。

docker 配置网卡 docker 多网卡_linux_10

host模式的特点和应用场景:host 模式简单并且网络传输性能高,host 模式下面的网络模型是最简单和最低延迟的模式,容器进程直接与主机网络接口通信,与物理机性能一致,host 不利于网络自定配置和管理,并且所有主机的容器使用相同的IP。也不利于主机资源的利用,需要考虑端口冲突问题,缺乏灵活性,如果是对网络性能要求比较高的情况下可以使用该模式,否则应该使用其他模式。

2、bridge网络模式

2.1、bridge网络介绍

docker的桥接网络使用虚拟网桥docker0,bridge网络用于同一主机上的docker容器相互通信,连接到同一个网桥的docker容器可以相互通信,当我们启动docker时,会自动创建一个默认bridge网络,除非我们进行另外的配置,新创建的容器都会自动连接到这个网络,我们也可以自定义自己的bridge网络,docker文档建议使用自定义bridge网络,默认的bridge网络具有一定的缺陷

连接到同一bridge网络的容器可以相互访问彼此任意一个端口,如果不发布端口,外界将无法访问这些容器,在创建容器时,通过-p或是--publish指令发布端口。
 

Docker安装时会创建一个命名为docker0的Linux bridge。如果不指定-network,创建的容器默认都会挂到docker0上,容器默认网络模式就是bridge模式。

brctl show

未有bridge容器运行时的宿主机网桥状态:

docker 配置网卡 docker 多网卡_网络_11

docker run -itd --name my_nginx2 guianjun/mynginx:v2.0 /bin/bash

brctl show

运行一个bridge模式的容器后的宿主机网桥状态:

docker 配置网卡 docker 多网卡_linux_12

2.2、bridge网络工作原理

docker 配置网卡 docker 多网卡_网络_13

我们安装Docker后守护进程将创建一个linux虚拟以太网桥docker0,它会在连接到其上的所有接口之间转发数据包,默认情况下主机上的所有容器都连接到这个内部桥接器,它会将一个接口(虚拟设备对veth pair)作为容器的eth0接口和主机命名空间中的另一个接口。这样容器就获得了私有 IP 地址分配。同时为了防止本地网络上的 ARP 冲突,Docker 守护进程从分配的 IP 地址上生成一个随机 MAC 地址。这样一来容器就和网桥连接起来了,然后通过iptables NAT规则和主机上eth0网卡交换数据。

对比宿主机和容器网卡信息:

docker 配置网卡 docker 多网卡_linux_14

docker 配置网卡 docker 多网卡_桥接_15

veth pair。 veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡, 网卡的一头(eth0@if7) 在容器中,另一头(veth699c76b) 挂在网桥docker0 上,其效果就是将eth0@if7 也挂在了docker0上。

     这里的容器分配的ip地址的网段取决于docker0的网络状态,一般容器的网关就是docker0的ip,

docker 配置网卡 docker 多网卡_桥接_16

docker inspect my_nginx2

docker 配置网卡 docker 多网卡_linux_17

2.3、自定义bridge和默认bridge网络区别

除了使用默认的bridge网络,也可以使用自定义bridge网络,因为自定义bridge网络有一定的缺陷,如下是自定义bridge与默认bridge网络对比:

  • 自定义 bridge 提供更好的隔离性和容器间的互操作性

连接到同一个自定义 bridge 网络的容器会自动将所有端口相互暴露,并且无法连接到容器之外的网络。这使得容器化的应用能轻松地相互通信,并且与外部环境产生了良好的隔离性。

例如一个包含了 web 应用,数据库,redis 等组件的应用程序。很有可能只希望对外界暴露 80 端口,而不允许外界访问数据库端口和 redis 端口,而又不至于让 web 应用本身无法访问数据库和 redis, 便可以使用自定义 bridge 网络轻松实现。如果在默认 bridge 网络上运行相同的应用程序,则需要使用 -p 或 —publish 标志打开 web 端口,数据库端口,redis 端口。这意味着 Docker 宿主机需要通过其他方式阻止对数据库端口,redis 端口的访问,无意增大了工作量。

  • 自定义 bridge 提供容器间的自动 DNS 解析

这一点在上一节的实验中已经验证过了。默认 bridge 网络上的容器只能通过 IP 地址互相访问,除非使用在 docker run 时添加 —link 参数。这么做个人认为有两点不好的地方:

(1):容器关系只要稍微复杂一些,便会对管理产生不便。

(2): —link 参数在官方文档中已经被标记为过期的参数,不被建议使用。

在用户定义的桥接网络上,容器可以通过容器名称(--name 指定的名称)或别名来解析对方。可能有人说,在默认 bridge 模式下我可以去修改 /etc/hosts文件呀,但这显然不是合理的做法。

  • 容器可以在运行中与自定义 bridge 网络连接和分离

在容器的生命周期中,可以在运行中将其与自定义网络连接或断开连接。 而要从默认 bridge 网络中移除容器,则需要停止容器并使用不同的网络选项重新创建容器。

  • 每个自定义的 bridge 网络都会创建一个可配置的网桥

如果容器使用默认 bridge 网络,虽然可以对其进行配置,但所有容器都使用相同的默认设置,例如 MTU 和防火墙规则。另外,配置默认 bridge 网络隔离于 Docker 本身之外,并且需要重新启动 Docker 才可以生效。

自定义的 bridge 是使用 docker network create 创建和配置的。如果不同的应用程序组具有不同的网络要求,则可以在创建时分别配置每个用户定义的 bridge 网络,这无疑增加了灵活性和可控性。

  • 使用默认 bridge 容器共享所有的环境变量

在 Docker 的旧版本中,两个容器之间共享环境变量的唯一方法是使用 —link 标志来进行链接。这种类型的变量共享对于自定义的网络是不存在的。但是,自定义网络有更好方式来实现共享环境变量:

        a、多个容器可以使用 Docker 卷来挂载包含共享信息的文件或目录。

        b、多个容器可以使用 docker-compose 一起启动,并且 docker-compose.yml 文件可以定义共享变量。

        c、使用集群服务而不是独立容器,并利用共享密钥和配置。

2.4、bridge模式docker0网络更改

默认安装的docker一般是以网桥bridge模式提供一个网络,默认的地址是172.17.0.1/16,如果发现这个docker0的网段跟已有网段冲突的话,这就需要更改docker0网段,避免网段冲突引发的一系列网络问题。

更改docker0网络配置步骤:

#停止或删除所有容器(注意备份)
docker stop $(docker ps -qa)
docker rm -f $(docker ps -qa)

#停止docker
systemctl stop docker

#修改docker配置文件,添加新的网段信息,如果没有该文件就新建
vim  /etc/docker/daemon.json

docker 配置网卡 docker 多网卡_网络_18

 添加如上图内容,将docker0改为192.168.100.1/24

systemctl restart docker

ifconfig docker0

docker 配置网卡 docker 多网卡_docker_19

docker 配置网卡 docker 多网卡_网络_20

网段更改完成 

2.5、创建自定义bridge网络

(1)、创建自定义网络命令:docker network create

(2)、示例

docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 mynet1

【参数说明】:

--driver bridge 表示自定义创建的网络属于桥接模式(默认也是bridge,所以可以不写)

--subnet 172.20.0.0/16 表示子网ip

--gateway 172.20.0.1表示网关

mynet 表示网络名

创建自定义桥接如果不需要指定网段的话也可以简写成如下:

#不指定driver即使用默认的bridge,不指定子网和网关则随机分配
docker network create mynet2

查看已创建的网络:

docker network ls

docker 配置网卡 docker 多网卡_docker 配置网卡_21

#查看mynet1网络配置信息
docker network inspect mynet1

#查看mynet2网络配置信息
docker network inspect mynet2

docker 配置网卡 docker 多网卡_桥接_22

 

docker 配置网卡 docker 多网卡_docker_23

使用自定义桥接创建容器

docker run -itd --name my_nginx1 --network mynet1 guianjun/mynginx:v3.0 /bin/bash

docker run -itd --name my_nginx2 --network mynet1 guianjun/mynginx:v3.0 /bin/bash

#自定义桥接可以支持直接主机名互访,自带dns解析
docker exec -it my_nginx1 ping my_nginx2

docker exec -it my_nginx2 ping my_nginx1

docker 配置网卡 docker 多网卡_桥接_24

自定义创建的桥接可以自带支持dns解析,实现容器名互访,这也是和默认桥接模式的一个明显区别,但和--link机制不同,--link是在/etc/hosts添加域名解析,是单向解析,而自定义创建的桥接是在/etc/resolv.conf里添加了dns地址配置,是双向解析,比较方便,--link机制已经被官方认定过时了。自定义桥接自带的resolv.conf配置如下:

docker exec -it my_nginx1 cat /etc/resolv.conf

docker exec -it my_nginx2 cat /etc/resolv.conf

docker 配置网卡 docker 多网卡_docker_25


3、none模式

3.1、none网络介绍

none网络就是什么都没有的网络。挂在这个网络下的容器除了lo,没有其他任何网卡。容器创建时,可以通过-network=none指定使用none网络。

主要用于一些对安全性要求高并且不需要联网的应用可以使用none网络。比如某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取。

3.2、设置方式

docker run -itd --net=none --name my_nginx2 guianjun/mynginx:v2.0 /bin/bash

docker exec -it my_nginx2 ip addr

docker 配置网卡 docker 多网卡_桥接_26