前言

前面的文章主要聚焦于单机网络上,对于生产环境而言,单机环境不满足高可用的特点,所以是不具备上生产的条件,因此在开始Docker Swarm篇的时候我们先来聊聊多机网络之间Docker的通信如何做,厦门主要介绍三种跨主机通信的方式。

Docker系列文章:
  1. 为什么要学习Docker
  2. Docker基本概念
  3. Docker镜像基本原理
  4. Docker容器数据卷
  5. Dockerfile
  6. Docker单机网络上
  7. Docker单机网络下
  8. Docker单机网络实战
  9. Docker隔离技术
  10. Docker限制
  11. Docker Compose

Host


image.png

Host模式容器之间可以通过宿主机的IP+端口的形式进行访问,这种方式很直接,该网络模式就和我们在虚拟机的时候两台机器之间通信的方案是一样的。这种通常依靠路由器。

overlay


img

overlay被称为隧道网络,它是基于 VxLAN 协议来将二层数据包封装到 UDP 中进行传输的,目的是扩展二层网段,因为 VLAN 使用 12bit 标记 VLAN ID,最多支持 4094 个 VLAN,这对于大型云网络会成为瓶颈,而 VxLAN ID 使用 24bit 来标记,支持多达 16777216 个二层网段,所以 VxLAN 是扩展了 VLAN,也叫做大二层网络。

overlay 网络需要注册中心来记录网络中的信息,比如主机地址、子网等,需要向注册中心注册必要的信息,然后它就会自动去收集、同步网络的信息,同时,还需要维护一个 IP 地址池,给主机中的的容器分配IP。 这里我们采用Consul来做注册中心。

实战

搭建的环境如上图,实验前准备在阿里云购买了三台机器2C2G的机器IP分别为172.21.122.237、172.21.122.238、172.21.122.239,分别安装完成Docker,可以参考该文章

  1. 在172.21.122.237通过docker搭建Consul单节点的服务;
#-h:表示consul的主机名;--name consul 表示为该容器名;--restart=always 表示可以随着docker服务的启动而启动;
#运行consul容器,该服务的默认端口是8500,-p:表示将容器的8500端口映射到宿主机的8500端口
#-serve -bootstarp:表示当在群集中,加上这两个选项可以使其以master的身份出现
docker run -d -p 8500:8500 -h consul --name consul --restart=always progrium/consul -server -bootstrap 
  1. 验证Consul服务是否正常,如果是阿里云的话需要通过外网访问,设置8500端口开放外网,访问外网IP+8500,出现下图情况如下:

image.png
  1. 修改172.21.122.238和172.21.122.239两台机器的docker服务配置文件;
#编辑docker.service文件
vim /usr/lib/systemd/system/docker.service
#找到ExecStart替换
#/var/run/docker.sock:Docker的一个编程接口
#-H tcp://0.0.0.0:2376:使用本机的tcp2376端口;
#--cluster-store=consul:指定运行着Consul服务的第一台docker服务器IP及端口;
#--cluster-advertise:告知Consul自己的连接地址;
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://172.21.122.237:8500 --cluster-advertise=172.21.122.238:2376
#重启docker
systemctl daemon-reload
systemctl restart docker
  1. 访问Consul服务器,如下图,当出现如下情况说明注册成功;

image.png

image.png

image.png
  1. 在172.21.122.238创建overlay网络,我们会发现在172.21.122.239上也会同步该网络,这是因为创建 238_overlay 时候 172.21.122.238 会将 overlay 网络信息存入了 Consul, 172.21.122.239会 从 Consul 读取到了新网络的数据。之后 238_overlay 的任何变化都会同步到 172.21.122.238和 172.21.122.239;
#在172.21.122.238创建overlay网络,网路地址10.0.2.1/24
docker network create -d overlay --subnet=10.0.2.1/24 238_overlay 
#172.21.122.239验证是否同步该网络
docker network ls

image.png

image.png
  1. 在172.21.122.238创建app238容器并连接到238_overlay网络;
docker run -d -it --name app238 --network 238_overlay busybox
  1. 查看容器app238的网络情况,app238除了本地回环地址外,还有有两个网口 eth0 和 eth1,eth0 IP为10.0.2.2,连接的是238_overlay的网络, eth1 IP为172.18.0.2,连接的是docker默认网络;
#查看容器内部的网络情况
docker exec app238 ip a

image.png
  1. 查看172.21.122.238宿主机docker的网络情况,我们可以看到容器默认创建了一个docker_gwbridge的网络,该网络为所有连接到 overlay 网络的容器提供访问外网的能力,我们可以进入到容器内部访问下外网,我们会发现该网络是通畅的;查看docker_gwbridge网络的集体情况,我们发现该ip地址的范围为172.18.0.0/16, 说明容器app238默认的网络就是docker_gwbridge,我们也可以看到宿主机上也挂载了该网络;
#查看容器情况
docker network ls
#进入容器内部
docker exec -it app238 /bin/sh
#查看docker_gwbridge网络的具体情况
docker network inspect docker_gwbridge
#查看宿主机网络
ip addr

image.png

image.png

image.png

image.png
  1. 检查网络的互通性,我们在宿主机172.21.122.239创建app239容器并使用238_overlay网络,检查app238与app239容器之间网络的是否连通,经过试验我们会发现该网络是连通的,说了overlay网络容器可以互相通信,并且也可以通过容器名称进行访问,也就是实现DNS服务;
#在宿主机172.21.122.239创建app239容器使用238_overlay网络
docker run -d -it --name app239 --network 238_overlay busybox
#从容器app238 ping 容器app239 我们会发现该网络是通畅的
docker exec app238 ping app239
#从容器app239 ping 容器app238 我们会发现该网络是通畅的
docker exec app239 ping app238

image.png

image.png
  1. 原理再探,在172.21.122.238和172.21.122.239两台机器上查看 overlay网络的 namespace,我们可以发现两台机器上出现相同的命名空间信息,1-57a6c0273a就是238_overlay 的namespace,接下来可以查看namespace中的网桥上的设备,我们会发现在br0网桥上挂载了veth0和vxlan0两个设备,至此就完成我们对overlay网络的验证;
#先执行
ln -s /var/run/docker/netns /var/run/netns
#查看命名空间
ip netns
#安装bridge-utils
yum install -y bridge-utils
#查看namespace中的网桥上的设备
ip netns exec 1-57a6c0273a brctl show

总结

在相同overlay 网络中,不同主机之间的容器是相互连通的,不同 overlay 网络之间是隔离,这点我就不进行验证了,有兴趣大家可以自己验证一下。

macvlan

macvlan是一种网卡虚拟化技术,它能够将一个物理网卡虚拟出多个接口,每个接口都可以配置 MAC 地址,同样每个接口也可以配自己的 IP。macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。macvlan 和 bridge 比较相似,但因为它省去了 bridge 的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,macvlan 自身也完美支持 VLAN。

macvlan 的做法其实就是将这些虚拟出来的接口与 Docker 容器直连来达到通信的目的。一个 macvlan 网络对应一个接口,不同的 macvlan 网络分配不同的子网,因此,相同的 macvlan 之间可以互相通信,不同的 macvlan 网络之间在二层上不能通信,需要借助三层的路由器才能完成通信。用 Macvlan 技术虚拟出来的虚拟网卡,在逻辑上和物理网卡是对等的。物理网卡也就相当于一个交换机,记录着对应的虚拟网卡和 MAC 地址,当物理网卡收到数据包后,会根据目的 MAC 地址判断这个包属于哪一个虚拟网卡。

四种模式

private mode

img

过滤掉所有来自其他 macvlan 接口的报文,因此不同 macvlan 接口之间无法互相通信。

vepa(Virtual Ethernet Port Aggregator) mode

img

需要主接口连接的交换机支持 VEPA/802.1Qbg 特性。所有发送出去的报文都会经过交换机,交换机作为再发送到对应的目标地址(即使目标地址就是主机上的其他 macvlan 接口),也就是 hairpin mode 模式,这个模式用在交互机上需要做过滤、统计等功能的场景。

bridge mode

img

此种模式类似 Linux 的 Bridge,拥有相同父接口的两块 Macvlan 虚拟网卡是可以直接通讯的,不需要把流量通过父网卡发送到外部网络,广播帧将会被泛洪到连接在"网桥"上的所有其他子接口和物理接口。这个模式下,主机外是看不到主机上 macvlan interface 之间通信的报文的。这比较适用于让共享同一个父接口的 Macvlan 网卡进行直接通讯的场景。

passthru mode

img

此种模式会直接把父接口和相应的MacVLAN接口捆绑在一起,这种模式每个父接口只能和一个 Macvlan 虚拟网卡接口进行捆绑,并且 Macvlan 虚拟网卡接口继承父接口的 MAC 地址。

实战
  1. 网卡设置为混杂模式,ens33就该宿主机的网卡设备;
#设置为混杂模式
ip link set ens33  promisc on
#查看是否设置为混杂
ifconfig ens33

image.png
  1. 创建macvlan网络,在两台主机上eth0网卡创建一个10.200.1.0网段的macvlan网络,名字为macnet,指定对应的网关10.200.1.1;
#--subnet 指定macvlan网络所在的网络
#--gateway 指定网关
#-o parent 指定用来分配macvlan网络的网卡
docker network create -d macvlan --subnet=10.200.1.0/24 --gateway=10.200.1.1 -o parent=ens33 -o macvlan_mode=bridge macnet

image.png
  1. 在两台宿主机上分别创建容器test1和容器test2;
docker run -it -d --name test1 --ip=10.200.1.2 --network macnet busybox
docker run -it -d --name test2 --ip=10.200.1.3 --network macnet busybox
  1. 验证网络的联通性,必须两台机器混杂模式都开启才可以保证联通;
docker exec test2 ping 10.200.1.2

image.png

结束

欢迎大家点点关注,点点赞!

Docker多机网络的更多相关文章

  1. 跨 Docker 宿主机网络 overlay 类型

    跨 Docker 宿主机网络 overlay 类型 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 三台 CentOS 7.0 虚拟机 (Vmware Workstation 1 ...

  2. docker 访问宿主机网络

    使用宿主机IP 在安装Docker的时候,会在宿主机安装一个虚拟网关docker0,我们可以使用宿主机在docker0上的IP地址来代替localhost. 首先,使用如下命令查询宿主机IP地址: i ...

  3. 宿主机网络中其它机器与Docker容器网络互通配置

    前言 目前项目采用微服务架构进行开发,Nacos和其它服务部署到Docker中,Docker中容器采用的网络默认是桥接模式(Bridge),默认的子网码是172.17.0.1/16:宿主机是192.1 ...

  4. 在docker里部署网络服务

    之前试着玩玩docker有一阵子了,今天算是头一回正式在docker里部署网络服务. 本来想和lxc差不多的东西那自然是手到擒来,没想到还是改了很多. 第一个遇到的问题是,远程连到docker宿主机干 ...

  5. 理解Docker单机容器网络

    在” 理解Docker单机容器网络 “一文中,还有一个Docker容器网络的功能尚未提及,那就是Docker容器的端口映射.即将容器的服务端口P’ 绑定到宿主机的端口P上,最终达到一种效果:外部程序通 ...

  6. docker 配置桥接网络

    2.5 docker配置桥接网络(上): 为了使本地网络中的机器和Docker 容器更方便的通信,我们经常会有将Docker容器 配置到和主机同一网段的需求. 这个需求其实很容器实现, 我们只需要将D ...

  7. Docker 单主机网络

    PS:欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 当容器逐步向容器集群,容器云技术演进的时候,一个不得不面对的问题就是各 ...

  8. docker简单介绍---网络端口管理

    一.查看docker支持的网络类型 docker network ls bridge:容器使用虚拟交换机的进行通信 host:使用宿主机的网络 none:只给容器分配一个lo的网卡,无法和外界进行通信 ...

  9. docker使用flannel网络

    基础环境我们使用了两台centos 7系统 基础配置为: 两台机器IP为 172.17.3.10 172.17.3.62 hosts文件配置为 172.17.3.10 node1 172.17.3.6 ...

随机推荐

  1. 自学 Java开发(Java后台开发|Java后端开发)的书籍推荐

    java编程思想java并发编程实战深入理解java虚拟机函数式编程思维tcp/ip详解鸟哥的linux私房菜spring mvc +mybatis开发从入门到精通spring技术内幕elastics ...

  2. kubelet源码分析——kubelet简介与启动

    kubelet是k8s集群中一个组件,其作为一个agent的角色分布在各个节点上,无论是master还是worker,功能繁多,逻辑复杂.主要功能有 节点状态同步:kublet给api-server同 ...

  3. 关于mysql基础

    早就想把自己的数据库基础巩固一下,然而一直没有时间,今天终于抽出时间对mysql数据库基础进行了学习与扩展. mysql与其他数据库的区别 Sqlite: 开源免费,体积小,单文件,没有进程.磁盘读性 ...

  4. 洛谷4219 BJOI2014大融合(LCT维护子树信息)

    QWQ 这个题目是LCT维护子树信息的经典应用 根据题目信息来看,对于一个这条边的两个端点各自的\(size\)乘起来,不过这个应该算呢? 我们可以考虑在LCT上多维护一个\(xv[i]\)表示\(i ...

  5. xshell连接VMware中的Linux

    [前言]最近想压测一下ITOO的考试系统,所以想在自己电脑上安装一下linux,然后安装一下jmeter进行压测一下. 不过为什么要连接xshell呢,因为在虚拟机上总是会和主机切换鼠标,而且也不能粘 ...

  6. final和static的区别

    static作用于成员变量用来表示只保存一份副本 final的作用是用来保证变量不可变.下面代码验证一下 public class FinalTest { public static void mai ...

  7. Oracle12C安装教程

    准备工作 网盘链接: https://pan.baidu.com/s/1gffHbOjImk1SfezdWO2Bpw 提取码: imft Oracle12C的安装 1.分别解压"winx64 ...

  8. 使用Servlet前Tomcat介绍

    虚拟目录的映射方式:让tomcat服务器自动映射tomcat服务器会自动管理webapps目录下的所有web应用,并把它映射成虚似目录.换句话说,tomcat服务器webapps目录中的web应用,外 ...

  9. [对对子队]Scrum Meeting 博客汇总

    对对子队 博客目录 一.Scrum Meeting 1. Alpha Scrum Meeting 1(会议记录4.10) Scrum Meeting 2(会议记录4.11) Scrum Meeting ...

  10. [对对子队]会议记录5.25(Scrum Meeting11)

    今天已完成的工作 吴桐雨 ​ 工作内容:设计第10.11关 ​ 相关issue:设计额外关卡 ​ 相关签入:level10 level11 吴昭邦 ​ 工作内容:写测试代码 ​ 相关issue:测试初 ...