项目上部署的Docker集群创建的容器网络遇到问题,借机会学习了一下docker的网络模式,其他类型我们用的不多,这里只列举我们常用的bridge和macvlan两种,下面的描述和截图有一些是直接从网上下载的。

Bridge模式 

Bridge模式是Docker默认的网络模式,当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,用来连接宿主机和容器,此主机上的Docker容器都会连接到这个虚拟网桥上,虚拟网桥的工作方式和物理交换机类似,这样所有容器就通过交换机连在了一个二层网络中。

Docker利用 veth pair技术,在宿主机上创建了两个虚拟网络接口 veth0 和 veth1(veth pair技术的特性可以保证无论哪一个veth 接收到网络报文,都会无条件地传输给另一方),Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡,从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看,这样容器和网桥就可以相互通信了。网络结构如下图:

容器与宿主机通信 : 在桥接模式下,Docker Daemon将veth0附加到docker0网桥上,保证宿主机的报文有能力发往veth0。再将veth1 添加到Docker 容器所属的网络命名空间,保证宿主机的网络报文若发往 veth0 可以立即被 veth1 收到。

容器与外界通信 : 容器如果需要联网,则需要采用 NAT(是一种在 ip 数据包通过路由器或防火墙时,重写来源 ip 地址或目的 ip 地址的技术) 方式。准确的说,是 NATP (网络地址端口转换) 方式。NATP 包含两种转换方式:SNAT 和 DNAT 。

  • 宿主机外访问容器时(修改数据包的目的地址):

由于容器的 IP 与端口对外都是不可见的,所以数据包的目的地址为宿主机的 ip 和端口,为 192.168.1.10:24 。

数据包经过路由器发给宿主机 eth0,再经 eth0 转发给 docker0 网桥。由于存在 DNAT 规则,会将数据包的目的地址转换为容器的 ip 端口,为 172.17.0.n:24 。

宿主机上的 docker0 网桥识别到容器 ip 和端口,于是将数据包发送附加到 docker0 网桥上的 veth0 接口,veth0 接口再将数据包发送给容器内部的 veth1 接口,容器接收数据包并作出响应。

整个过程如下图:

  • 容器访问宿主机之外时(修改数据包的源地址)

此时数据包的源地址为容器 ip 和端口,为 172.17.0.n:24,容器内部的 veth1 接口将数据包发往 veth0 接口,到达 docker0 网桥。

宿主机上的 docker0 网桥发现数据包的目的地址为外界的 IP 和端口,便会将数据包转发给 eth0 ,并从 eth0 发出去。由于存在 SNAT 规则,会将数据包的源地址转换为宿主机的 ip 端口,为 192.168.1.10:24 。

由于路由器可以识别到宿主机的 ip 地址,所以再将数据包转发给外界,外界接受数据包并作出响应。这时候,在外界看来,这个数据包就是从 192.168.1.10:24 上发出来的,Docker 容器对外是不可见的。

整个过程如下图:

macvlan模式 

macvlan本身是linxu kernel的模块,本质上是一种网卡虚拟化技术。其功能是允许在同一个物理网卡上虚拟出多个网卡,通过不同的MAC地址在数据链路层进行网络数据的转发,一块网卡上配置多个 MAC 地址(即多个 interface),每个interface可以配置自己的IP,Docker的macvlan网络实际上就是使用了Linux提供的macvlan驱动

因为多个MAC地址的网络数据包都是从同一块网卡上传输,所以需要打开网卡的混杂模式ip link set eth0 promisc on;

创建macvlan网络不同于桥接模式,需要指定网段和网关,并且都得是真实存在的,例如docker network create -d macvlan --subnet=10.9.8.0/24 --gateway=10.9.8.254 -o parent=eth0 macvlan-test

macvlan模式不依赖网桥,所以brctl show查看并没有创建新的bridge,但是查看容器的网络,会看到虚拟网卡对应了一个interface是2

查看宿主机的网络,2正是虚机的网卡

可见,容器的 eth0 就是宿主机的eth0通过macvlan虚拟出来的interface。容器的interface直接与主机的网卡连接,这种方案使得容器无需通过NAT和端口映射就能与外网直接通信(只要有网关),在网络上看起来与其他独立主机没有区别。当前网络结构如图所示:

macvlan会独占主机的网卡,也就是说一个网卡只能创建一个macvlan 网络,否则会报错,为了能支持更多的macvlan网络,macvlan不仅可以连接到interface(如eth0),也可以连接到网卡的子接口sub-interface(如eth0.xxx)。

VLAN 是现代网络常用的网络虚拟化技术,它可以将物理的二层网络划分成多达 4094 个逻辑网络,这些逻辑网络在二层上是隔离的,每个逻辑网络(即 VLAN)由 VLAN ID 区分,VLAN ID 的取值为 1-4094。Linux 的网卡也能支持 VLAN(apt-get install vlan),同一个 interface可以收发多个VLAN 的数据包,不过前提是要创建 VLAN的 sub-interface。比如希望 eth0同时支持 VLAN10 和 VLAN20,则需创建 sub-interface eth0.10 和 eth0.20。创建的子接口是可以看到的,如下如

在交换机上,如果某个端口只能收发单个VLAN的数据,该port为Access模式,如果支持多个VLAN,则为Trunk模式,要实现多个macvlan,网卡要接在交换机的 trunk口上。

例如给网卡创建了10、20两个子接口后,分别创建容器后的网络结构如下图:

Docker的bridge和macvlan两种网络模式的更多相关文章

  1. [转帖]Docker四种网络模式

    Docker(十四)-Docker四种网络模式 https://www.cnblogs.com/zhuochong/p/10069293.html 计算机网络相关的知识 非常有用.. Docker 安 ...

  2. Docker的4种网络模式

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

  3. Docker 四种网络模式

    原文 https://www.cnblogs.com/gispathfinder/p/5871043.html 我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络 ...

  4. Docker——四种网络模式

    docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式:  bridge模式:使用–net =bridge指定,默认设置:  host模式 ...

  5. Docker学习第四天(Docker四种网络模式)

    Docker四种网络模式 实现原理 Docker使用Linux桥接(参考<Linux虚拟网络技术>),在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根 ...

  6. Docker的4种网络模式详细介绍

    docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式: bridge模式:使用–net =bridge指定: host模式:使用–net = ...

  7. k8s的两种网络方案与多种工作模式[flannel与calico]

    k8s的两种网络方案与多种工作模式 1. Flannel: flannel有三种工作模式: 1. vxlan(隧道方案) 2. host-gw(路由方案) 2. udp(在用户态实现的数据封装解封装, ...

  8. VMware三种网络模式

    VMware网络配置详解一:三种网络模式简介安装好虚拟机以后,在网络连接里面可以看到多了两块网卡: 其中VMnet1是虚拟机Host-only模式的网络接口,VMnet8是NAT模式的网络接口,这些后 ...

  9. vmware虚拟机三种网络模式的区别

    首先安装了VMware,在其中安装了Ubuntu系统,正常启动之后开始考虑怎么才能够让主机和虚拟机实现网络互连并且由主机向虚拟机发送文件,通过在网上查阅相关资料,记录学习笔记如下. 学习参考资料: l ...

随机推荐

  1. Appium移动自动化测试(二)之appuim + 夜神模拟器

    环境搭建起来之后, 就可以开始移动自动化了. 但是使用自带的AVD开启模拟器, 速度实在太慢. 于是用夜神来做替代, 稍微能够有一些提速. 启动appuim 打开Appium,点击右上角Start按钮 ...

  2. 内存数据库:memcached与redis技术的对比试验

    本文以高性能nginx服务器为应用背景,想利用缓存技术来减轻系统负荷,加快响应时间,从而增加web服务器的吞吐量. redis是一种分布式内存数据库,memcached是一种内存缓存技术,它们都采用k ...

  3. SpringBoot解决ajax跨域问题(转载)

    一.第一种方式: 1.编写一个支持跨域请求的 Configuration import org.springframework.context.annotation.Configuration; im ...

  4. (4)rapidxml的详解及使用

        RapidXml是指 XML DOM解析工具包,是一个快速的读写xml文件的库文件(hpp).     (1)创建XML文件 #include <iostream> #includ ...

  5. Java并发编程之程序运行堆栈分析

    Java程序运行的堆栈分析 1.JVM运行时数据区 JVM通过加载class文件的数据来执行程序.JVM在运行时会划分不同的区域以存放数据.如下图所示: 线程共享部分:所有线程都能访问这块内存的数据, ...

  6. C学习笔记-结构体与二进制文件增删改查

    使用结构体整理数据,然后利用二进制存储文件,这样存储的文件类似于数据库,可以实现文件的增删改查 定义结构体 struct student { unsigned int ID; char name[20 ...

  7. jump用户管理命令

    ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa手动拷贝id_rsa.pub的内容到其他机器 或者用 ssh-copy,但你得知道对方root密码 ssh-copy-i ...

  8. Serialize and Deserialize N-ary Tree

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  9. JavaScript中好用的对象数组去重

    对象数组去重 Demo数据如下: var items= [{ "specItems": [{ "id": "966480614728069122&qu ...

  10. 小记---------spark优化之更优分配资源

      spark优化:在一定范围之内,增加资源与性能的提升是成正比的. 因此,       一个cpu core  执行一个task线程. task数: 若有 cpu core 2个.num-execu ...