热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Docker跨主机网络(manual)的实现

这篇文章主要介绍了Docker跨主机网络(manual)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. Macvlan 简介

在 Macvlan 出现之前,我们只能为一块以太网卡添加多个 IP 地址,却不能添加多个 MAC 地址,因为 MAC 地址正是通过其全球唯一性来标识一块以太网卡的,即便你使用了创建 ethx:y 这样的方式,你会发现所有这些“网卡”的 MAC 地址和 ethx 都是一样的,本质上,它们还是一块网卡,这将限制你做很多二层的操作。有了 Macvlan 技术,你可以这么做了。

Macvlan 允许你在主机的一个网络接口上配置多个虚拟的网络接口,这些网络 interface 有自己独立的 MAC 地址,也可以配置上 IP 地址进行通信。Macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。Macvlan 和 Bridge 比较相似,但因为它省去了 Bridge 的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,Macvlan 自身也完美支持 VLAN。

同一 VLAN 间数据传输是通过二层互访,即 MAC 地址实现的,不需要使用路由。不同 VLAN 的用户单播默认不能直接通信,如果想要通信,还需要三层设备做路由,Macvlan 也是如此。用 Macvlan 技术虚拟出来的虚拟网卡,在逻辑上和物理网卡是对等的。物理网卡也就相当于一个交换机,记录着对应的虚拟网卡和 MAC 地址,当物理网卡收到数据包后,会根据目的 MAC 地址判断这个包属于哪一个虚拟网卡。这也就意味着,只要是从 Macvlan 子接口发来的数据包(或者是发往 Macvlan 子接口的数据包),物理网卡只接收数据包,不处理数据包,所以这就引出了一个问题:本机 Macvlan 网卡上面的 IP 无法和物理网卡上面的 IP 通信!关于这个问题的解决方案我们下一节再讨论。


简单来说,Macvlan 虚拟网卡设备是寄生在物理网卡设备上的。发包时调用自己的发包函数,查找到寄生的物理设备,然后通过物理设备发包。收包时,通过注册寄生的物理设备的 rx_handler 回调函数,处理数据包。

2.简单介绍manual的流程

macvlan 就如它的名字一样,是一种网卡虚拟化技术,它能够将一个物理网卡虚拟出多个接口,每个接口都可以配置 MAC 地址,同样每个接口也可以配自己的 IP,每个接口就像交换机的端口一样,可以为它划分 VLAN。

macvlan 的做法其实就是将这些虚拟出来的接口与 Docker 容器直连来达到通信的目的。一个 macvlan 网络对应一个接口,不同的 macvlan 网络分配不同的子网,因此,相同的 macvlan 之间可以互相通信,不同的 macvlan 网络之间在二层上不能通信,需要借助三层的路由器才能完成通信,如下,显示的就是两个不同的 macvlan 网络之间的通信流程。


我们用一个 Linux 主机,通过配置其路由表和 iptables,将其配成一个路由器(当然是虚拟的),就可以完成不同 macvlan 网络之间的数据交换,当然用物理路由器也是没毛病的。

3.Macvlan 的特点:

1.可让使用者在同一张实体网卡上设定多个 MAC 地址。
2.承上,带有上述设定的 MAC 地址的网卡称为子接口(sub interface);而实体网卡则称为父接口(parent interface)。
3.parent interface 可以是一个物理接口(eth0),可以是一个 802.1q 的子接口(eth0.10),也可以是 bonding 接口。
4.可在 parent/sub interface 上设定的不只是 MAC 地址,IP 地址同样也可以被设定。
5.sub interface 无法直接与 parent interface 通讯 (带有 sub interface 的 VM 或容器无法与 host 直接通讯)。
承上,若 VM 或容器需要与 host 通讯,那就必须额外建立一个 sub 6.interface 给 host 用。
7.sub interface 通常以 mac0@eth0 的形式来命名以方便区別。
用张图来解释一下设定 Macvlan 后的样子:

4.实验环境

docker01 docker02
192.168.1.11 192.168.1.13

关闭防火墙和禁用selinux,更改主机名

[root@localhost ~]# hostnamectl set-hostname docker01
[root@localhost ~]# su -
上一次登录:二 12月 17 08:20:36 CST 2019从 192.168.1.1pts/0 上
[root@docker01 ~]# systemctl stop firealld
Failed to stop firealld.service: Unit firealld.service not loaded.
[root@docker01 ~]# setenforce 0
setenforce: SELinux is disabled
[root@docker01 ~]# systemctl daemon-reload 
[root@docker01 ~]# systemctl restart docker
4.1 macvlan的单网络通信

4.1 macvlan的单网络通信


1) 打开网卡的混杂模式

//需要在docker01和docker02_上都进行操作。

[root@docker01 ~]# ip link show ens33
//查看网卡模式

[root@docker01 ~]# ip link set ens33 promisc on
//创建网卡模式为混杂模式
[root@docker01 ~]# ip link show ens33
//查看网卡模式


2)在docker01.上创建macvlan网络

[root@docker01 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1
// 创建一个macvlan模式的网络
-o parent=绑定在哪张网卡之上
[root@docker01 ~]# docker network ls
//查看网卡信息

3)基于创建的macvlan网络运行一个容器

[root@docker01 ~]# docker run -itd --name bbox1 --ip 172.22.16.10 --network mac_net1 busybox

4)在docker02.上创建macvlan网络(要和docker01的macvlan一模一样)

[root@docker02 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1

[root@docker02 ~]# docker network ls

5)在docker02. 上,基于创建的macvlan网络运行一个容器,验证与docker01.上容器的通信。

[root@docker02 ~]# docker run -itd --name bbox2 --network mac_net1 --ip 172.22.16.20 busybox
//基于busybox创建一个容器
[root@docker02 ~]# docker exec -it bbox2 /bin/sh
//进入bbox2容器
/ # ping 172.22.16.10
//ping一下docker01的主机

4.2macvlan的多网络通信

1) docker01和docker02验证内核模块8021q封装

macvlan需要解决的问题:基于真实的ens33网卡,生产新的虚拟网卡。

[root@docker01 ~]# modinfo 8021q
//验证内核模块8021q封装

[root@docker01 ~]# modprobe 8021q
//如果内核模块没有开启,运行上边的命令导入一下

2)docker01基于ens33创建虚拟网卡

修改ens33网卡配置文件

[root@docker01 ~]# cd /etc/sysconfig/network-scripts/
[root@docker01 network-scripts]# vim ifcfg-ens33 


手动添加虚拟网卡配置文件

[root@docker01 ~]# cd /etc/sysconfig/network-scripts/
[root@docker01 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10
//-p保留源文件或目录的属性
[root@docker01 network-scripts]# vim ifcfg-ens33.10
//修改ens33.10网卡配置文件
BOOTPROTO=none
NAME=ens33.10
DEVICE=ens33.10
OnBOOT=yes
IPADDR=192.168.10.10
PREFIX=24
GATEWAY=192.168.10.2
VLAN=yes

这里注意,IP要和ens33网段做一个区分, 保证网关和网段IP的一致性,设备名称和配置文件的-致性,并且打开VLAN支持模式。

创建第二个虚拟网卡配置文件

[root@docker01 network-scripts]# cp -p ifcfg-ens33.10 ifcfg-ens33.20
[root@docker01 network-scripts]# vim ifcfg-ens33.20
//修改ens33.20网卡配置文件
BOOTPROTO=none
NAME=ens33.20
DEVICE=ens33.20
OnBOOT=yes
IPADDR=192.168.20.20
PREFIX=24
GATEWAY=192.168.20.2
VLAN=yes

docker01上的操作,启用创建的虚拟网卡:

[root@docker01 network-scripts]# ifup ifcfg-ens33.10 
[root@docker01 network-scripts]# ifup ifcfg-ens33.20
[root@docker01 network-scripts]# ifconfig
//查看IP

3)docker02基于ens33创建虚拟网卡

修改ens33网卡配置文件

[root@docker02 ~]# cd /etc/sysconfig/network-scripts/
[root@docker02 network-scripts]# vim ifcfg-ens33 


手动添加虚拟网卡配置文件

[root@docker02 ~]# cd /etc/sysconfig/network-scripts/
[root@docker02 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10
//-p保留源文件或目录的属性
[root@docker02 network-scripts]# vim ifcfg-ens33.10
//修改ens33.10网卡配置文件
BOOTPROTO=none
NAME=ens33.10
DEVICE=ens33.10
OnBOOT=yes
IPADDR=192.168.10.11
PREFIX=24
GATEWAY=192.168.10.2
VLAN=yes

这里注意,IP要和ens33网段做一个区分, 保证网关和网段IP的一致性,设备名称和配置文件的-致性,并且打开VLAN支持模式。

创建第二个虚拟网卡配置文件

[root@docker02 network-scripts]# cp -p ifcfg-ens33.10 ifcfg-ens33.20
[root@docker02 network-scripts]# vim ifcfg-ens33.20
//修改ens33.20网卡配置文件
BOOTPROTO=none
NAME=ens33.20
DEVICE=ens33.20
OnBOOT=yes
IPADDR=192.168.20.21
PREFIX=24
GATEWAY=192.168.20.2
VLAN=yes

docker02上的操作,启用创建的虚拟网卡:

[root@docker02 network-scripts]# systemctl restart network
[root@docker02 network-scripts]# ifup ifcfg-ens33.10 
[root@docker02 network-scripts]# ifup ifcfg-ens33.20
[root@docker02 network-scripts]# ifconfig
//查看IP


4)docekr01和docker02基于虚拟网卡,创建macvlan网络

[root@docker02 network-scripts]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10
//创建一个新的网卡基于ens33.10
[root@docker02 network-scripts]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20
//创建一个新的网卡基于ens33.20

5)Docker01部署一个私有仓库
Docker01

docker pull registry
//下载registry镜像
docker run -itd --name registry -p 5000:5000 --restart=always registry:latest 
//基于registry镜像,启动一台容器
docker tag busybox:latest 192.168.1.11:5000/busybox:v1 
//把容器重命名一个标签
docker ps

vim /usr/lib/systemd/system/docker.service #13行修改
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.1.11:5000 

systemctl daemon-reload 
systemctl restart docker.service 
//重启docker
docker push 192.168.1.11:5000/busybox:v1
//上传容器到私有仓库 
 docker images

Docker02

vim /usr/lib/systemd/system/docker.service #13行修改
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.1.11:5000 

systemctl daemon-reload 
systemctl restart docker.service 
//重启docker
docker pull 192.168.1.11/busybox:v1 
//下载刚刚上传的镜像

6)docker01和docker02基于busybox:v1镜像和网卡mac_net10,mac_net20,创建容器。
Docker01

[root@docker01 ~]# docker run -itd --name bbox10 --network mac_net10 --ip 172.16.10.10 192.168.1.11:5000/busybox:v1
[root@docker01 ~]# docker run -itd --name bbox20 --network mac_net20 --ip 172.16.20.20 192.168.1.11:5000/busybox:v1
**Docker02**
[root@docker02 ~]# docker run -itd --name bbox10 --network mac_net10 --ip 172.16.10.10 192.168.1.11:5000/busybox:v1
[root@docker02 ~]# docker run -itd --name bbox20 --network mac_net20 --ip 172.16.20.20 192.168.1.11:5000/busybox:v1

***这里只需注意,我们在这里的操作跟在docker01和上面的操作是一模一样的,操作顺序大致为:
验证8021q内核封装

基于ens33网卡创建新的虚拟网卡,ens33.10和ens33.20 (注意和docker01. 上的ens33.10和ens33.20必须是在同一-网段,且IP不能冲突)基于此网络运行容器。(注意和docker01 上的容器,都是基于刚刚创建的macvlan网络,但IP地址不能冲突)

7)验证
在docker01.上进入容器bbox10和docker02.上的bbox11进行通信。
在docker01.上进入容器bbox20和docker02.上的bbox21进行通信。
注意: VMware的网络必须设置为Bridge模式。

现在把docker01和docker02的网络模式设置为桥接模式


测试一下相同网卡的主机是否能ping通

[root@docker01 ~]# docker exec -it bbox10 /bin/sh
/ # ping 172.16.20.20

[root@docker02 ~]# docker exec -it bbox20 /bin/sh
/ # ping 172.16.20.20

5.Macvlan 的局限性

Macvlan 是将 VM 或容器通过二层连接到物理网络的近乎理想的方案,但它也有一些局限性:

1.Linux 主机连接的交换机可能会限制同一个物理端口上的 MAC 地址数量。虽然你可以让网络管理员更改这些策略,但有时这种方法是无法实行的(比如你要去给客户做一个快速的 PoC 演示)。
2.许多 NIC 也会对该物理网卡上的 MAC地址数量有限制。超过这个限制就会影响到系统的性能。
3.IEEE 802.11 不喜欢同一个客户端上有多个 MAC 地址,这意味着你的 Macvlan 子接口在无线网卡或 AP 中都无法通信。可以通过复杂的办法来突破这种限制,但还有一种更简单的办法,那就是使用 Ipvlan,感兴趣可以自己查阅相关资料。

6.总结

macvlan是一种网卡虚拟化技术,能够将一张网卡虚拟出多张网卡。

macvlan的特定通信模式,常用模式是bridge。

在Docker中,macvlan只支持bridge模式。

相同的macvlan可以通信,不同的macvlan二层无法通信,可以通过三层路由完成通信。

思考一下:

macvlan bridge和bridge的异同点
还有一种类似的技术,多张虚拟网卡共享相同MAC地址,但有独立的IP地址,这是什么技术?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 本文探讨了容器技术在安全方面面临的挑战,并提出了相应的解决方案。多租户保护、用户访问控制、中毒的镜像、验证和加密、容器守护以及容器监控都是容器技术中需要关注的安全问题。通过在虚拟机中运行容器、限制特权升级、使用受信任的镜像库、进行验证和加密、限制容器守护进程的访问以及监控容器栈,可以提高容器技术的安全性。未来,随着容器技术的发展,还需解决诸如硬件支持、软件定义基础设施集成等挑战。 ... [详细]
  • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
  • (九)Docker常用安装
    一、总体步骤1、搜索镜像2、拉取镜像3、查看镜像4、启动镜像5、停止镜像6、移除镜像二、安装tomcat1、dockerhub上面查找tomcat镜像 dockersearchto ... [详细]
  • 随着我司的应用都开始容器化,相应的ETL流程也需要迁移到容器中。常规的SQL和shell脚本迁移之后执行基本没有问题,主要的问题在于数据接入使用kettle的场景下,kettle启 ... [详细]
  • 本文详细介绍了Vim编辑器中的三种模式(命令模式、末行模式和编辑模式)以及它们之间的操作区别和切换方法。Vim编辑器凭借其多种命令快捷键和高效率的操作方式,得到了广大厂商和用户的认可。对于想要高效操作文本的用户来说,了解这些模式的使用方法是必不可少的。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • 1.脚本功能1)自动替换jar包中的配置文件。2)自动备份老版本的Jar包3)自动判断是初次启动还是更新服务2.脚本准备进入ho ... [详细]
  • DockerDataCenter系列(四)-离线安装UCP和DTR,Go语言社区,Golang程序员人脉社 ... [详细]
  • 在Jenkinsfile中运行映像时如何传递 ... [详细]
  • docker容器的数据管理一:数据卷实现数据的永久化,完全独立于容 ... [详细]
author-avatar
mobiledu2502882721
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有