gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 31 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章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 通信!关于这个问题的解决方案我们下一节再讨论.

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

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

2.简单介绍manual的流程 。

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

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

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

我们用一个 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 后的样子:

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

4.实验环境 。

  。

docker01 docker02
192.168.1.11 192.168.1.13

  。

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

 
?
1
 
2
3
4
5
6
7
8
9
10
[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的单网络通信 。

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

1) 打开网卡的混杂模式 。

 
?
1
 
2
3
4
// 需要在docker01和docker02_上都进行操作。
 
[root@docker01 ~] # ip link show ens33
// 查看网卡模式

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

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

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

2)在docker01.上创建macvlan网络 。

 
?
1
 
2
3
4
5
[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
// 查看网卡信息

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

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

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

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

 
?
1
 
2
3
[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

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

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

 
?
1
 
2
3
4
5
6
[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的主机

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

4.2macvlan的多网络通信 。

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

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

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

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

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

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

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

修改ens33网卡配置文件 。

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

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

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

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
[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支持模式.

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

 
?
1
 
2
3
4
5
6
7
8
9
10
11
[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上的操作,启用创建的虚拟网卡

 
?
1
 
2
3
4
[root@docker01 network-scripts] # ifup ifcfg-ens33.10
[root@docker01 network-scripts] # ifup ifcfg-ens33.20
[root@docker01 network-scripts] # ifconfig
// 查看ip

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

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

修改ens33网卡配置文件 。

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

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

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

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
[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支持模式.

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

 
?
1
 
2
3
4
5
6
7
8
9
10
11
[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上的操作,启用创建的虚拟网卡

 
?
1
 
2
3
4
5
[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

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

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

 
?
1
 
2
3
4
[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 。

 
?
1
 
2
3
4
5
6
7
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

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

 
?
1
 
2
3
4
5
6
7
8
9
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 。

 
?
1
 
2
3
4
5
6
7
8
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 。

 
?
1
 
2
3
[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**
 
?
1
 
2
[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的网络模式设置为桥接模式 。

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

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

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

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

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

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

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地址,这是什么技术?

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

原文链接:https://blog.51cto.com/14320361/2459313 。

最后此篇关于Docker跨主机网络(manual)的实现的文章就讲到这里了,如果你想了解更多关于Docker跨主机网络(manual)的实现的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com