概念
使用macvlan
网络模式的Docker容器,可以看作是局域网内的一个独立设备,它会有一个独立的内网IP。每个macvlan
下的Docker容器,都有自己一套完整的端口可用,不会互相冲突。
macvlan
最大的优点就是可以和宿主机配置为不同网关,方便网络分流。
创建
前置配置
# 开启网卡混杂模式
ip link set ens192 promisc on
IPv4
docker network create -d macvlan --subnet=10.0.0.0/24 --gateway=10.0.0.1 -o parent=ens192 mac_net
IPv4 & IPv6 双栈
docker network create -d macvlan --subnet=10.0.0.0/24 --gateway=10.0.0.1 --ipv6 --subnet=fd00::/60 --gateway=fd00::1 -o parent=ens192 mac_net
docker network create -d macvlan
:指定创建的网络类型是macvlan
--subnet=10.0.0.0/24
:macvlan
的IPv4网段
--gateway=10.0.0.1
:macvlan
的IPv4网关
--ipv6
:启用IPv6支持
--subnet=fd00::/60
:macvlan
的IPv6前缀
--gateway=fd00::1
:macvlan
的IPv6网关
-o parent=ens192
:桥接网络走的接口名称
mac_net
:需要创建的macvlan
网络名称
问题
macvlan
网络下不能与宿主机通讯问题
原因
一般在macvlan
模式下同网段的其他机器可以和容器互通,但宿主不能和容器互通,这是在macvlan
模式设计的时候为了安全而禁止了宿主机和容器直接通信。
如果想要实现互通,有个曲线救国的方法,就是macvlan
与macvlan
之间可以互通,只需要在宿主机再创建一个macvlan
网络,然后修改路由,让数据经过这个macvlan
达到互通的目的。
实现
假设当前网段为10.0.0.0/24
名字 | IP | 接口 |
---|---|---|
宿主机 | 10.0.0.10 | ens192 |
macvlan容器 | 10.0.0.11 | mac_net |
输入以下命令,在宿主机上新建一个macvlan
虚拟接口
# 创建一个名为macvlan_host的macvlan虚拟接口,并桥接到ens192物理接口上
ip link add macvlan_host link ens192 type macvlan mode bridge
# 为macvlan_host接口添加一个10.0.0.15的IP
ip addr add 10.0.0.15 dev macvlan_host
# 开启macvlan_host接口
ip link set macvlan_host up
# 新增路由,使到macvlan容器的数据包由macvlan_host发出
ip route add 10.0.0.11 dev macvlan_host
macvlan容器与宿主机在同一网段的情况下,
macvlan_host
不需要配置IP
验证
宿主机通过10.0.0.11
访问macvlan容器
macvlan容器通过10.0.0.15
访问宿主机
总结
mavlan
虚拟出来的网口不能和父网口直通,但是可以和同一子网的其他网口互通(包括其他虚拟出来的网口)。
通过在宿主机上用macvlan
添加一个虚拟网口macvlan_host
,并在宿主机上配置路由『到容器的数据包由macvlan_host
发出』,就架起了宿主机与容器的通信桥梁。
宿主机发往容器的数据包,由macvlan_host
发给容器;容器发往宿主机的数据包先发给macvlan_host
,再由macvlan_host
转交给 ens192(宿主机)。