Docker 1.10 容器在局域网中的 IP

Posted

技术标签:

【中文标题】Docker 1.10 容器在局域网中的 IP【英文标题】:Docker 1.10 container's IP in LAN 【发布时间】:2016-06-15 01:05:24 【问题描述】:

从 Docker 1.10(和 libnetwork 更新)开始,我们可以手动为用户定义网络中的容器分配 IP,这很酷!

我想在我的 LAN 中为容器提供一个 IP 地址(就像我们可以在“桥接”模式下使用虚拟机一样)。我的局域网是 192.168.1.0/24,我所有的电脑里面都有 IP 地址。而且我希望我的容器具有此范围内的 IP,以便从我的 LAN 中的任何地方访问它们(没有 NAT/PAT/等...)。

我显然读过 Jessie Frazelle 的 blog post 和许多其他人在这里和各处发帖,例如:

How to set a docker container's iP? How to assign specific IP to container and make that accessible outside of VM host?

还有很多,但什么也没出来;我的容器仍然在我的 docker 主机“内部”有 IP 地址,并且我的 LAN 上的其他计算机无法访问。

阅读 Jessie Frazelle 的博文,我想(因为她使用公共 IP)我们可以做我想做的事?

编辑:确实,如果我这样做:

network create --subnet 192.168.1.0/24 --gateway 192.168.1.1 homenet
docker run --rm -it --net homenet --ip 192.168.1.100 nginx

docker 主机 (br-[a-z0-9]+) 上的新接口采用“--gateway”IP,这是我的路由器 IP。并且在网络上的两台计算机上使用相同的 IP ... BOOM

提前致谢。

【问题讨论】:

您是在 Linux 上,还是通过 boot2docker 虚拟机使用 docker? 真是个傻瓜!我忘了最重要的!我在 Linux (Debian 8) 上。 感谢您发布此内容,在过去的几周里,我遇到了很多与此相关的复杂问题。专门从子网外部到达容器。由于我的问题,我已经放弃了这个,但我很高兴这个帖子存在,以防我需要再次这样做。 【参考方案1】:

编辑:这个解决方案现在没用了。从 1.12 版本开始,Docker 提供了两个网络驱动程序:macvlan 和 ipvlan。它们允许从 LAN 网络分配静态 IP。请参阅answer below。


在寻找people who have the same problem 之后,我们找到了解决方法:

总结:

(V)LAN 为 192.168.1.0/24 默认网关(= 路由器)是 192.168.1.1 多个 Docker 主机 注意:我们有两个 NIC:eth0 和 eth1(专用于 Docker)

我们想要什么:

我们希望在没有任何 NAT/PAT/translation/port-forwarding/etc 的 192.168.1.0/24 网络中拥有 ip 容器(如计算机)...

问题

当这样做时:

network create --subnet 192.168.1.0/24 --gateway 192.168.1.1 homenet

我们能够为容器提供我们想要的 IP,但是由 docker (br-[a-z0-9]+) 创建的网桥将拥有 IP 192.168.1.1,这是我们的路由器。

解决方案

1。设置 Docker 网络

使用DefaultGatewayIPv4 参数:

docker network create --subnet 192.168.1.0/24 --aux-address "DefaultGatewayIPv4=192.168.1.1" homenet

默认情况下,Docker 会给桥接接口 (br-[a-z0-9]+) 第一个 IP,该 IP 可能已经被另一台机器占用。解决方案是使用--gateway参数告诉docker分配一个任意IP(可用):

docker network create --subnet 192.168.1.0/24 --aux-address "DefaultGatewayIPv4=192.168.1.1" --gateway=192.168.1.200 homenet

我们可以通过在前面的命令中添加-o com.docker.network.bridge.name=br-home-net来指定网桥名称。

2。架起桥梁!

现在我们有了一个由 Docker 创建的桥 (br-[a-z0-9]+)。我们需要将它桥接到物理接口(在我的情况下,我必须连接到 NIC,所以我使用 eth1):

brctl addif br-home-net eth1

3。删除网桥IP

我们现在可以从网桥中删除 IP 地址,因为我们不需要:

ip a del 192.168.1.200/24 dev br-home-net

IP192.168.1.200 可以用作多个 docker 主机上的桥接器,因为我们不使用它,因此我们将其删除。

【讨论】:

我怎样才能反转brctl addif br-home-net eth1?将自己锁定在 SSH 之外,需要请人进行修复:) @Duplexia :你可以做一个brctl delif br-home-net eth1 谢谢你,这非常有用,我只想指出,如果你失去了互联网连接,你必须手动将你的默认网关添加到你的路由表中:sudo route add default gw 1​​92.168.1.1 有没有办法通过 DHCP 实现这一点?我正在尝试为容器分配 ISP 的 DHCP IP 地址。 从 Docker 1.12 开始,有 macvlan 和 ipvlan 驱动。他们使这个解决方案毫无用处。从 Docker 17.06 开始,我认为您可以使用 macvlan 驱动程序从 DHCP 池中分配 IP 地址。【参考方案2】:

Docker 现在支持 MacvlanIPvlan 网络驱动程序。可以在here 找到这两个网络驱动程序的 Docker 文档。

使用这两个驱动程序,您可以实现所需的场景(将容器配置为像桥接模式下的虚拟机一样):

Macvlan:允许单个物理网络接口(主设备)拥有任意数量的从设备,每个设备都有自己的 MAC 地址。

需要 Linux 内核 v3.9–3.19 或 4.0+。

IPvlan:允许您为您的主设备创建任意数量的从设备,它们都共享相同的 MAC 地址。

需要 Linux 内核 v4.2+(对早期内核的支持存在但有缺陷)。

有关详细信息,请参阅kernel.org IPVLAN Driver HOWTO。

容器连接是通过将其中一个从设备放入要配置的容器的网络命名空间来实现的。主设备保留在主机操作系统上(默认命名空间)。

根据经验,如果连接到外部交换机/路由器的 Linux 主机配置了每个端口只允许一个 MAC 的策略,则应使用 IPvlan 驱动程序。这在 VMWare ESXi 环境中经常出现!

要记住的另一件重要事情(Macvlan 和 IPvlan): 进出主设备的流量不能与从设备之间发送。如果您需要启用主从通信,请参阅“IPVLAN – 开始”论文中的“与主机通信(默认-ns)”部分IPvlan 作者 (Mahesh Bandewar)。

【讨论】:

不错。 +1。我得测试一下。 您能分享一些如何使用 Macvlan 进行配置的教程吗?我很想读一些文章,因为我很难自己配置。使用 Virtualbox 可以很容易地从 WiFi 路由器获取 IP - 虚拟网卡上有配置,所以我可以定义自己的 MAC。我是 Docker 新手,我无法管理它。 请参阅here 了解 Docker 的 Macvlan 文档 @Marecky。 This 部分实际上应该向您展示如何为每个容器分配唯一的 MAC / IP 地址。【参考方案3】:

使用官方的 Docker 驱动:

截至Docker v1.12.0-rc2,新的 MACVLAN 驱动程序现已在官方 Docker 版本中提供:

MacVlan 驱动程序已过期 #23524

这些新驱动程序是well documented by the author(s), with usage examples。

最终,它应该提供类似的功能,更易于设置,并且错误/其他怪癖更少。

在 Docker 主机上查看容器:

对新的官方 macvlan 驱动程序的唯一警告是 docker 主机无法看到/与自己的容器通信。哪个可能是可取的,这取决于您的具体情况。

如果您的 docker 主机上有超过 1 个 NIC,则可以解决此问题。并且两个 NIC 都连接到您的 LAN。然后可以 A) 将 docker 主机的 2 个 nic 中的 1 个专用于 docker。并使用剩余的网卡让主机访问局域网。

或 B) 通过仅将特定路由添加到您需要通过第二个 NIC 访问的那些容器。例如:

sudo route add -host $container_ip gw $lan_router_ip $if_device_nic2

如果您想从 docker 主机访问所有容器并且您有多个硬连线链接,则方法 A) 很有用。

如果您只需要从 docker 主机访问几个特定容器,则方法 B) 非常有用。或者,如果您的第二个 NIC 是 wifi 卡,并且处理所有 LAN 流量会慢得多。例如在笔记本电脑上。

安装:

如果在 ubuntu 16.04 上看不到预发布的 -rc2 候选,暂时将这一行添加或修改到您的 /etc/apt/sources.list 中:

deb https://apt.dockerproject.org/repo ubuntu-xenial testing

而不是main(这是稳定版本)。

【讨论】:

【参考方案4】:

我不再推荐此解决方案。所以它被删除了。是using bridge driver and brctrl 。

现在有一个更好的官方驱动程序。在此页面上查看其他答案:https://***.com/a/36470828/287510

【讨论】:

【参考方案5】:

这是一个使用 macvlan 的例子。它在http://10.0.2.1/ 启动一个网络服务器。

这些命令和 Docker Compose 文件适用于 QNAP 和 QNAP 的 Container Station。请注意,QNAP 的网络接口是qvs0

命令:

Lars Kellogg-Stedman 的博文“Using Docker macvlan networks”[1][2] 解释了这些命令的含义。

docker network create -d macvlan -o parent=qvs0 --subnet 10.0.0.0/8 --gateway 10.0.0.1 --ip-range 10.0.2.0/24 --aux-address "host=10.0.2.254" macvlan0
ip link del macvlan0-shim link qvs0 type macvlan mode bridge
ip link add macvlan0-shim link qvs0 type macvlan mode bridge
ip addr add 10.0.2.254/32 dev macvlan0-shim
ip link set macvlan0-shim up
ip route add 10.0.2.0/24 dev macvlan0-shim

docker run --network="macvlan0" --ip=10.0.2.1 -p 80:80 nginx

Docker 编写

使用版本 2,因为版本 3 不支持其他网络配置,例如 gatewayip_rangeaux_address

version: "2.3"

services:
    HTTPd:
        image: nginx:latest
        ports:
            - "80:80/tcp"
            - "80:80/udp"
        networks:
            macvlan0:
                ipv4_address: "10.0.2.1"

networks:
    macvlan0:
        driver: macvlan
        driver_opts:
            parent: qvs0
        ipam:
            config:
                - subnet: "10.0.0.0/8"
                  gateway: "10.0.0.1"
                  ip_range: "10.0.2.0/24"
                  aux_address: "host=10.0.2.254"

【讨论】:

【参考方案6】:

可以通过pipework 将物理接口映射到容器中。

Connect a container to a local physical interface

pipework eth2 $(docker run -d hipache /usr/sbin/hipache) 50.19.169.157/24
pipework eth3 $(docker run -d hipache /usr/sbin/hipache) 107.22.140.5/24

现在可能有一种本地方式,但我还没有研究过 1.10 版本。

【讨论】:

管道的缺点是:我们看不到同一主机上的容器。因此,本机解决方案可能更可取。 (分配 IP 地址更快/错误更少)。

以上是关于Docker 1.10 容器在局域网中的 IP的主要内容,如果未能解决你的问题,请参考以下文章

Nginx反向代理docker容器局域网

docker容器设置固定IP

创建 docker 机器或容器时如何设置特定的固定 IP 地址?

docker给家庭局域网的设备滤除广告

docker固定IP第三种方法

Docker 1.10 通过主机名访问容器