docker - 通过特定物理接口的 docker 网络
问题描述
所以我正在尝试创建一个网络 ( docker network create
),以便其流量将通过特定的物理网络接口 (NIC);我有两个:(<iface1>
内部)和<iface2>
(外部)。
我需要将两个 NIC 的流量进行物理分离。
方法一:
我认为macvlan
是驱动程序应该用来创建这样的网络。对于我在互联网上找到的大部分内容,解决方案是指 Pipework(现已弃用)和临时 docker-plugins(也已弃用)。最能帮助我的是这个1
docker network create -d macvlan \
--subnet 192.168.0.0/16 \
--ip-range 192.168.2.0/24 \
-o parent=wlp8s0.1 \
-o macvlan_mode=bridge \
macvlan0
然后,为了使容器从主机可见,我需要在主机中执行此操作:
sudo ip link add macvlan0 link wlp8s0.1 type macvlan mode bridge
sudo ip addr add 192.168.2.10/16 dev macvlan0
sudo ifconfig macvlan0 up
现在容器和主机互相看到了:) 但是容器无法访问本地网络。这个想法是容器可以访问互联网。
方法二:
正如我将<iface2>
手动使用的那样,如果默认情况下流量通过<iface1>
. 但无论我以哪种顺序启动 NIC(我也尝试<iface2>
暂时移除 LKM);整个流量总是被外部网卡所取代<iface2>
。我发现它发生是因为路由表会在某个“随机”时间自动更新。为了强制流量通过<iface1>
,我必须(在主机中):
sudo route del -net <net> gw 0.0.0.0 netmask 255.0.0.0 dev <iface2>
sudo route del default <iface2>
现在,我可以(通过多种方式)验证流量是否刚刚通过<iface1>
。但是在路由表更新(自动)的那一刻,所有流量都移动到<iface2>
. 该死!我确信有一种方法可以使路由表“静态”或“持久”。
编辑(2018 年 7 月 18 日): 主要思想是能够仅使用两个可用物理网络接口之一通过 docker 容器访问互联网。
解决方案
我的环境:
在为 vm virbr0 桥创建的主机上,其 IP 地址为 192.168.122.1,并在 vm 实例上创建,接口为 ens3,IP 地址为 192.168.122.152。
192.168.122.1 - 是 192.168.122.0/24 网络的网关。
进入虚拟机:
创建网络:
# docker network create --subnet 192.168.122.0/24 --gateway 192.168.122.1 --driver macvlan -o parent=ens3 vmnet
创建 docker 容器:
# docker run -ti --network vmnet alpine ash
查看:
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
12: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:c0:a8:7a:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.2/24 brd 192.168.122.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping 192.168.122.152
PING 192.168.122.152 (192.168.122.152): 56 data bytes
^C
--- 192.168.122.152 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
/ # ping 192.168.122.1
PING 192.168.122.1 (192.168.122.1): 56 data bytes
64 bytes from 192.168.122.1: seq=0 ttl=64 time=0.471 ms
^C
--- 192.168.122.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.471/0.471/0.471 ms
好的,我启动了另一个 ip 地址为 192.168.122.73 的虚拟机并从 docker 检查:
/ # ping 192.168.122.73 -c2
PING 192.168.122.73 (192.168.122.73): 56 data bytes
64 bytes from 192.168.122.73: seq=0 ttl=64 time=1.630 ms
64 bytes from 192.168.122.73: seq=1 ttl=64 time=0.984 ms
--- 192.168.122.73 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.984/1.307/1.630 ms
从 docker 实例我无法 ping vm 上的接口,但我可以访问本地网络。
/ # ip n|grep 192.168.122.152
192.168.122.152 dev eth0 used 0/0/0 probes 6 FAILED
在 vm 上,我添加 macvlan0 nic:
# ip link add macvlan0 link ens3 type macvlan mode bridge
# ip addr add 192.168.122.100/24 dev macvlan0
# ip l set macvlan0 up
从 docker 我可以 ping 192.168.122.100:
/ # ping 192.168.122.100 -c2
PING 192.168.122.100 (192.168.122.100): 56 data bytes
64 bytes from 192.168.122.100: seq=0 ttl=64 time=0.087 ms
64 bytes from 192.168.122.100: seq=1 ttl=64 time=0.132 ms
--- 192.168.122.100 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.087/0.109/0.132 ms
推荐阅读
- javascript - Safari 从 DOM 分离元素后调用事件处理程序
- node.js - 让管理员应用程序使用某些 api 密钥为另一个应用程序中的用户预订服务
- python - Azure 函数 Blob 触发器失败 - Python
- function - 如何在 Vuejs 中创建可重用的函数?
- wkwebview - WKWebView 冻结应用程序 iOS 14,无法显示带有标识符 _UIDatePickerCompactEditor 的配置上下文菜单
- python - Python子模块类实例生成
- flutter - Flutter Visual Studio 模拟器打开后我的程序失败
- spring - 当您将特定的 Spring bean 返回给休息端点的任何消费者时会发生什么
- c# - Ajax 如何将表单数据与 ID 一起发送到控制器
- ssis - 如何将 SQL Server 数据中的值分配给 SSIS 中的变量