Linux下docker网络管理(容器的四种网络模式)

下面,我们来学习Docker的网络管理。

Docker 在启动时会创建一个虚拟网桥 docker0,默认地址为 172.17.0.1/16,容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址 (IP地址都会在172.17.0.1基础上递增 ==,第一个容器它获取到的IP为172.17.0.2)

  • docker0默认地址

  • 网桥

  • 容器桥接docker0后,自动分配ip地址

  • 容器桥接docker0后,再次查看docker0的网桥,会发现docker0增加了相应的接口。

  • 容器桥接docker0后,使用命令"ip  a",会发现多了相应的虚拟网卡。


解释:veth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth8aa2220(通常命名为veth*),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信。


一、实验环境(rhel7.3版本)

1.selinux和firewalld状态为disabled

2.各主机信息如下:

主机 ip
server1(安装好docker) 172.25.83.1

二、容器的四种网络模式

Docker在创建容器时有三种网络模式,bridge为默认不需要用–net去指定,其他三种模式需要在创建容器时使用–net去指定。

  • bridge模式,使用--net=bridge指定,默认设置。
  • none模式,使用--net=none指定。
  • host模式,使用--net=host指定。
  • container模式,使用--net=container:容器名称或ID指定

以下是docker网络初始化过程:

1、Bridge 桥接模式

Bridge 桥接模式的实现步骤主要如下:

  1. Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。
  2. Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
  3. Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。

Bridge桥接模式的缺陷:

bridge 桥接模式下的 Docker Container 在使用时,并非为开发者包办了一切。

  1. 最明显的是,该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。
  2. 虽然 NAT 模式经过中间处理实现了这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器内部服务的访问者需要使用服务发现获知服务的外部端口等。
  3. 另外 NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。

2、Host 模式

在这里插入图片描述

Host 网络模式:

host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。

Host 网络模式的缺陷:

当然,有这样的方便,肯定会损失部分其他的特性。

  1. 最明显的是 Docker Container 网络环境隔离性的弱化。即容器不再拥有隔离、独立的网络栈。
  2. 另外,使用 host 模式的 Docker Container 虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;
  3. 另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网络模式容器的端口映射。

3、Container 模式

Container 网络模式的实现步骤主要如下:

  1. 查找 other container(即需要被共享网络环境的容器)的网络 namespace;
  2. 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用other container 的 namespace。

Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。
在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。
 

Container网络模式的缺陷:

  1. 但是需要注意的是,它并没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他设备)。

 

4、None 模式

网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了none 网络模式,那么容器内部就只能使用 loopback 网络设备(即lo回环接口),不会再有其他的网络资源。可以说 none 模式为 Docker Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。

在 none 网络模式下分配固定 ip:
netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备及 iptables 规则等都是独立的,就好像进入了另外一个网络一样。

 

三、Docker的四种模式部署

1、Bridge 桥接模式

[root@server1 ~]# docker run -it --name vm1 ubuntu

  • 其中vm1容器所属的 namespace所在的位置为:/proc/Pid对应的数字/ns/net

2、Host 模式

[root@server1 ~]# docker run -it --name vm2 --net host ubuntu


用host网络模式启动的容器vm2,拥有与宿主机server1完全相同的结构。


我们可以用下面的方式来验证host模式开启的容器与宿主机的结构是一模一样的。

[root@server1 ~]# docker rm -f vm2   #删除之前用host模式开启的容器vm2
[root@server1 ~]# netstat -antulpe | grep 80   #确保宿主机的80端口是没有被占用的。这样才能测试出,用host模式开启的容器和宿主机的结构是一模一样的。
[root@server1 ~]# docker run -d --name vm2 --net host nginx   #用nginx镜像运行容器vm2
  • 我们访问宿主机的ip地址172.25.83.1,可以访问成功(宿主机的80端口并没有开)。所以访问的其实是容器vm2。

3、Container 模式

[root@server1 ~]# docker run -it --name vm3 --net container:vm1 ubuntu

[root@server1 ~]# brctl show   #docker0的桥接接口只有一个;新创建的vm3容器,使用的是vm1的namespace
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02426b0d90ce	no		veth8aa2220

4、None 模式

[root@server1 ~]# docker run -it --name vm4 --net none ubuntu


 

猜你喜欢

转载自blog.csdn.net/qq_42303254/article/details/88744072