资讯专栏INFORMATION COLUMN

Docker网络

Euphoria / 2258人阅读

摘要:容器与主机共享同一,共享同一套网络协议栈路由表及规则等。基本网络配置平台下,容器网络资源通过内核的机制实现隔离,不同的有各自的网络设备协议栈路由表防火墙规则等,反之,同一下的进程共享同一网络视图。设计的网络模型。

整理自《Docker进阶与实战》

Docker网络现状

为了解决容器网络性能低下、功能不足的问题,Docker启动了子项目“Libnetwork”。Libnetwork提出了新的容器网络模型(Container Network Model,简称CNM),定义了标准的API用于为容器配置网络,其底层可以适配各种网络驱动(如图Docker-network01所示)。CNM有三个:

沙盒
沙盒是一个隔离的网络运行环境,保存了容器网络栈的配置,包括了对网络接口、路由表和DNS配置的管理。在Linux平台上,沙盒是用Linux Network Namespace实现的,在其他平台上可能是不同的概念,如FreeBSD Jail。一个沙盒可以包括来自多个网络的多个Endpoint(端点)。

Endpoint
Endpoint将沙盒加入一个网络,Endpoint的实现可以是一对veth pair或者OVS内部端口,当前的Libnetwork使用的是veth pair。一个Endpoint只能隶属于一个沙盒及一个网络。通过给沙盒增加多个Endpoint可以将一个沙盒加入多个网络。

网络
网络包括一组能互相通信的Endpoint。网络的实现可以是Linux bridge、vlan等。

从CNM的概念角度讲,Libnetwork的出现使得Docker具备了跨主机多子网的能力,同一个子网内的不同容器可以运行在不同主机上。比如,同属于192.168.0.0/24子网IP地址分别为192.168.0.1和192.168.0.2的容器可以位于不同的主机上且可以直接通信,而持有IP 192.168.1.1的容器即使与IP为192.168.0.1的容器处于同一主机也不能互通。

Libnetwork已经实现了五种驱动(driver):

bridge
Docker默认的容器网络驱动。Container通过一对veth pair连接到docker0网桥上,由Docker为容器动态分配IP及配置路由、防火墙规则等。

host
容器与主机共享同一Network Namespace,共享同一套网络协议栈、路由表及iptables规则等。容器与主机看到的是相同的网络视图。

null
容器内网络配置为空,需要用户手动为容器配置网络接口及路由等。

remote
Docker网络插件的实现。Remote driver使得Libnetwork可以通过HTTP RESTful API对接第三方的网络方案,类似SocketPlane的SDN方案只要实现了约定的HTTP URL处理函数及底层的网络接口配置方法,就可以替换Docker原生的网络实现。

overlay
Docker原生的跨主机多子网网络方案。主要通过使用Linux bridge和vxlan隧道实现,底层通过类似于etcd或consul的KV存储系统实现多机的信息同步。overlay驱动当前还未正式发布,但开发者可以通过编译实验版的Docker来尝试使用,Docker实验版同时提供了额外的network和service子命令来进行更灵活的网络操作,不过,需要内核版本>=3.16才可正常使用。

以上五种驱动已经随Docker 1.8一同发布。

基本网络配置

Linux平台下,Docker容器网络资源通过内核的Network Namespace机制实现隔离,不同的Network Namespace有各自的网络设备、协议栈、路由表、防火墙规则等,反之,同一Network Namespace下的进程共享同一网络视图。通过对Network Namespace的灵活操纵,Docker提供了五种容器网络模式。

none

不为容器配置任何网络功能。
在该模式下,需要以-–net=none参数启动容器

$ docker run --net=none -ti ubuntu:latest ip addr show

使用-–net=none启动容器之后,仍然可以手动为容器配置网络。

container

与另一个运行中的容器共享Network Namespace,共享相同的网络视图。
举个例子,首先以默认网络配置(bridge模式)启动一个容器,设置hostnamedockerNetdns8.8.4.4

$ docker run -h dockerNet --dns 8.8.4.4 -tid ubuntu:latest bash
964286222ab53c67b2d6fb1882b2364c745be718a4a13530b016fe51b4968054

然后以–-net=container:96428方式启动另一个容器

$ docker run --net=container:96428 -ti ubuntu:latest bash

进入容器,通过ip addr show命令可以发现两个容器的IP地址、DNS、hostname都是相同的。实质上两个容器是共享同一个Network Namespace的,网络配置自然也是完全相同的。

host

与主机共享Root Network Namespace,容器有完整的权限可以操纵主机的协议栈、路由表和防火墙等,所以被认为是不安全的。
相应的,host模式启动时需要指定-–net=host参数。举个例子

$ docker run -ti --net=host ubuntu:latest bash

host模式下,容器可以操纵主机的网络配置,这是危险的,除非万不得已,应该尽可能避免使用host模式。

bridge

Docker设计的NAT网络模型。
Docker daemon启动时会在主机创建一个Linux网桥(默认为docker0,可通过-b参数手动指定)。容器启动时,Docker会创建一对veth pair(虚拟网络接口)设备,veth设备的特点是成对存在,从一端进入的数据会同时出现在另一端。Docker会将一端挂载到docker0网桥上,另一端放入容器的Network Namespace内,从而实现容器与主机通信的目的。bridge模式下的网络拓扑图如图docker-network02所示:

在桥接模式下,Docker容器与Internet的通信,以及不同容器之间的通信,都是通过iptables规则控制的。总之,Docker网络的初始化动作包括:创建docker0网桥、为docker0网桥新建子网及路由、创建相应的iptables规则等。Bridge模式是Docker默认的容器运行模式,以bridge模式启动的容器,默认会从172.17.42.1/16子网内分配IP。

overlay

Docker原生的跨主机多子网模型。
overlay网络模型比较复杂,底层需要类似consul或etcd的KV存储系统进行消息同步,核心是通过Linux网桥与vxlan隧道实现跨主机划分子网。如图Docker-network03所示,每创建一个网络,Docker会在主机上创建一个多带带的沙盒,沙盒的实现实质上是一个Network Namespace。在沙盒中,Docker会创建名为br0的网桥,并在网桥上增加一个vxlan接口,每个网络占用一个vxlan ID,当前Docker创建vxlan隧道的ID范围为256~1000,因而最多可以创建745个网络。当添加一个容器到某一个网络上时,Docker会创建一对veth网卡设备,一端连接到此网络相关沙盒内的br0网桥上,另一端放入容器的沙盒内,并设置br0的IP地址作为容器内路由默认的网关地址,从而实现容器加入网络的目的。

以图Docker-network03为例,容器1和容器4同属一个网络,容器1需要通过256号vxlan隧道访问另一台主机的容器4。Docker通过vxlan和Linux网桥实现了跨主机的虚拟子网功能。
使用shell命令查看overlay网络拓扑

# 创建网络
$ docker network create -d overlay dev
# 显示网络列表
$ docker network ls
9101d162c6db bridge bridge
fcd0327f5104 dev overlay
f5f9c8723777 none null
eb81445767e1 host host
# fcd0327f5104实质上是dev网络的网络ID,创建软链接的目的是为了能够使用ip命令操纵名字空间。
# ln -s /var/run/docker/netns/fcd0327f5104 /var/run/netns/fcd0327f5104
# 查看端口详细信息
$ ip netns exec fcd0327f5104 ip addr show
# 查看网桥信息
$ ip netns exec fcd0327f5104 brctl show
# 查看vxlan详细信息
$ ip netns exec fcd0327f5104 ip -d link show vxlan1

综上所述,Docker的整个网络模型,是建立在Network Namespace、Linux网桥、vxlan隧道、iptables规则之上的,也正是由于过于依赖网桥与iptables,导致Docker的网络效率不高。

Docker网络相关参数

关于Docker网络相关参数请参考“Docker(1.11.1)命令”。

待续···

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26627.html

相关文章

  • Docker网络解读

    libnetwork docker在1.9版本之后,引入了一套docker network子命令来管理docker网络。这允许用户可以根据他们应用的拓扑结构创建虚拟网络并将容器接入其所对应的网络。 具体来说,docker网络是通过一个叫libnetwork的东西来进行管理...

    Drummor 评论0 收藏0
  • [译] Docker如何使用Linux iptables 和 Interfaces管理容器网络

    我使用docker至今已有一段时间了,与绝大部分的人一样,我被docker强大的功能和易用性深深的折服。简单方便是docker的核心之一,它强大的功能被抽象成了非常简单的命令。当我在使用和学习docker的时候,我很想知道docker在...

    Prasanta 评论0 收藏0
  • Docker 快速上手指南

    以下记录 Docker 中的常用操作、指令,使得大家能够快速地使用 Docker。 为什使用 Docker? 为什么要使用 Docker?就个人而言,Docker 能提供的最大便利在于这种技术面对程序环境迁移时所表现的卓越性。 这种性能使得我们不必...

    derek_334892 评论0 收藏0
  • 02-Docker新手入门网络

    ...Step1:网络容器 1.部署一个默认网络容器 查看网络列表 #docker network ls 我们看到我们有3个network,bridge是一个特殊的网络docker默认的在这个网络中启动我们的容器。 Step1:创建一个后台运行的容器,如果您不了解这些命令那么...

    王笑朝 评论0 收藏0
  • Docker Swarm介绍

    前言本篇是Docker第十三篇,Docker的使用至此就介绍完成,接下来继续Kubernetes。Docker系列文章:为什么要学习DockerDocker基本概念Docker镜像基本原理Docker容器数据卷DockerfileDocker单机网络Docker单机网络Docker单机网络实战Docker隔离技...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

Euphoria

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<