基本概念:
Macvlan 工作原理:
Macvlan 是 Linux 内核支持的网络接口. 要求的 Linux 内部版本是 v3.9-3.19 和 4.0+;
通过为物理网卡创建 Macvlan 子接口, 允许一块物理网卡拥有多个独立的 Mac 地址和 IP 地址. 虚拟出来的子接口将直接暴露在相邻物理网络中. 从外部看来, 就像是把网线隔开多股, 分别接受了不同的主机上一样;
物理网卡收到包后, 会根据收到包的目的 Mac 地址判断这个包需要交给其中虚拟网卡.
当容器需要直连入物理网络时, 可以使用 Macvlan.Macvlan 本身不创建网络, 本质上首先使宿主机物理网卡工作在'混杂模式', 这样物理网卡的 Mac 地址将会失效, 所有二层网络中的流量物理网卡都能收到. 接下来就是在这张物理网卡上创建虚拟网卡, 并为虚拟网卡指定 Mac 地址, 实现一卡多用, 在物理网络看来, 每张虚拟网卡都是一个单独的接口.
使用 Macvlan 需要注意以下几点:
容器直接连接物理网络, 由物理网络负责分配 IP 地址, 可能的结果是物理网络 IP 地址被耗尽, 另一个后果是网络性能问题, 物理网络中接入的主机变多, 广播包占比快速升高而引起的网络性能下降问题;
宿主机上的某张网上需要工作在'混乱模式'下;
前面说到, 工作在混乱模式下的物理网卡, 其 Mac 地址会失效, 所以, 此模式中运行的容器并不能与外网进行通信, 但是不会影响宿主机与外网通信;
从长远来看 bridge 网络与 overlay 网络是更好的选择, 原因就是虚拟网络应该与物理网络隔离而不是共享.
项目环境:
两台 docker 主机:(centos7)
- docker01: 172.16.1.30
- docker02: 172.16.1.31
项目操作:
实例一: macvlan 跨主机单网络解决方案:
docker01:
(1) 开启 ens33 网卡的混杂模式, 开启网卡的多个虚拟 interface(接口)
- [[email protected] ~]# ip link set ens33 promisc on
- ## 查看网卡的状态:
- [[email protected] ~]# ip link show ens33
(2) 创建 macvlan 网络:
[[email protected] ~]# docker network create -d macvlan --subnet 172.16.100.0/24 --gateway 172.16.100.1 -o parent=ens33 mac_net1
参数解释:
-o: 绑定在哪张网卡之上 (基于 ens33 网卡)
(3) 基于刚创建的网络运行一个容器:
[[email protected] ~]# docker run -itd --name box1 --ip 172.16.100.10 --network mac_net1 busybox
docker02:(与 docker01 相同操作)
开启混杂模式
- [[email protected] ~]# ip link set ens33 promisc on
- [[email protected] ~]# ip link show ens33
- // 创建 macvlan 网络
- [[email protected] ~]# docker network create -d macvlan --subnet 172.16.100.0/24 --gateway 172.16.100.1 -o parent=ens33 mac_net1
- // 运行一个容器:
- [[email protected] ~]# docker run -itd --name box2 --network mac_net1 --ip 172.16.100.20 busybox
(4) 测试两个主机间的两个容器相互通信:
注意事项:
能 ping 通的原因是两个容器都是基于真实的 ens33 网卡的, 所以宿主机上的 ens33 网卡必须能够相互通信. 这种方式只能够 ping 通 ip 地址, 是无法 ping 通容器名的.
实例二: macvlan 跨主机多网络解决方案:
(1) 首先查看主机内核的 8021q 模块:
[[email protected] ~]# modinfo 8021q
- ## 如果没有查看到该模块, 需要执行以下命令进行加载:
- [[email protected] ~]# modprobe 8021q
开启路由转发:
- [[email protected] ~]# echo "net.ipv4.ip_forward = 1"> /etc/sysctl.conf
- [[email protected] ~]# sysctl -p
- net.ipv4.ip_forward = 1
(2) 修改网络配置信息:
- docker01:
- [[email protected] ~]# cd /etc/sysconfig/network-scripts/
- [[email protected] network-scripts]# ls
[[email protected] network-scripts]# VIM ifcfg-ens33
基于 ens33 网卡进行创建子网卡:
- [[email protected] network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10 #网卡名称自定义
- [[email protected] network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.20
-p: 表示保留原有属性 (权限)
- // 修改 ens33.10 网卡:
- [[email protected] network-scripts]# VIM ifcfg-ens33.10
- ## 只保留以下选项:
- // 修改 ens33.20 网卡:
- [[email protected] network-scripts]# VIM ifcfg-ens33.20
配置与 ens33.10 相同, 只需修改 ip 地址:
(3) 启动子网卡:
- [[email protected] network-scripts]# ifup ifcfg-ens33.10
- [[email protected] network-scripts]# ifup ifcfg-ens33.20
- // 查看网络信息
- [[email protected] network-scripts]# ifconfig
(4) 基于 ens33.10 和 ens33.20 创建 macvlan 网络:
注意: 网段不同, 网络名称不同
- [[email protected] ~]# docker network create -d macvlan --subnet 172.16.200.0/24 --gateway 172.16.200.1 -o parent=ens33.10 mac_net10
- [[email protected] ~]# docker network create -d macvlan --subnet 172.16.210.0/24 --gateway 172.16.210.1 -o parent=ens33.20 mac_net20
(5) 基于以上网络分别运行 2 个容器:
- [[email protected] ~]# docker run -itd --name test1 --ip 172.16.200.10 --network mac_net10 busybox
- [[email protected] ~]# docker run -itd --name test2 --ip 172.16.210.10 --network mac_net20 busybox
部署 docker02:
基本与 docker01 操作相同, 注意网段的相同, 但主机 ip 得不同.
# 以下操作将不做解释:
开启路由转发:
- [[email protected] ~]# echo "net.ipv4.ip_forward = 1"> /etc/sysctl.conf
- [[email protected] ~]# sysctl -p
- net.ipv4.ip_forward = 1
- [[email protected] network-scripts]# pwd
- /etc/sysconfig/network-scripts
- [[email protected] network-scripts]# VIM ifcfg-ens33
- [[email protected] network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10
- [[email protected] network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.20
- [[email protected] network-scripts]# VIM ifcfg-ens33.10
[[email protected] network-scripts]# VIM ifcfg-ens33.20
- [[email protected] network-scripts]# ifup ifcfg-ens33.10
- [[email protected] network-scripts]# ifup ifcfg-ens33.20
- // 创建 macvlan 网络:
- [[email protected] ~]# docker network create -d macvlan --subnet 172.16.200.0/24 --gateway 172.16.200.1 -o parent=ens33.10 mac_net10
- [[email protected] ~]# docker network create -d macvlan --subnet 172.16.210.0/24 --gateway 172.16.210.1 -o parent=ens33.20 mac_net20
- // 运行容器 (ip 地址不同):
- [[email protected] ~]# docker run -itd --name test3 --network mac_net10 --ip 172.16.200.11 busybox
- [[email protected] ~]# docker run -itd --name test4 --network mac_net20 --ip 172.16.210.11 busybox
- // 确保容器正常运行
- :
(6) 测试容器之间能够跨主机通信:(注意: 如果你是 vmware 环境的话, 由于 VMware 虚拟机的原因, 必须将两台主机默认的 NAT 模式修改为桥接模式才能够正常通信)
test3 与 test1 通信 (相同网段):
test4 与 test2 通信 (相同网段):
排错思路: 如果部署完主机间无法通信的话, 首先确认防火墙或 iptables 规则是否关闭或放行, 是否禁用 selinux, 其次排查 ens33 的网卡配置文件及其子网卡内容是否修改错误, 最后排查你创建 macvlan 网络是是否网段定义错误, 或者在运行容器是否 ip 地址指定不正确.
----------------------macvlan 多网络跨主机实现通信部署完毕 ---------------------
扩展知识点:
假设我们运行了一个 t1 容器, 然后 t2 容器使用 t1 容器的网络栈.
- [[email protected] ~]# docker run -itd --name t1 busybox
- [[email protected] ~]# docker exec t1 ip a
[[email protected] ~]# docker run -it --name t2 --network container:t1 busybox
- // 接下来在 t1 容器中操作:
- [[email protected] ~]# docker exec -it t1 bin/sh
然后在 t2 容器中也可以看到此服务:
以上就是部署网络栈的基本内容, 自己也不是经常用到, 就是为了实现其他容器能够共享其中一个容器中的资源.
来源: http://www.bubuko.com/infodetail-3265830.html