将 LAN IP 地址分配给与主机 IP 地址不同的 Docker 容器
Assign LAN IP address to Docker container different from host's IP address
我不太熟悉 Unix 网络、添加虚拟接口等,现在正在尝试学习。我们正在尝试 docker 化我们的应用程序。
我的要求是:将 ip 分配给可从外部 application/browser 访问的 docker 容器。
容器 ip 应该可以从同一网络中的不同计算机 ping basically.I 不想使用端口转发。
我想访问一个 docker 容器,就像我们使用 ip 访问 VM 一样
address.[ 没有端口映射,-p 标志。如果我 运行 任何服务器,如 Apache 或 Tomcat
在容器内部,应该可以使用容器 ip 和
港口。例如:http://container_ip:8443]
这在 docker 中可能吗?
运行 我的 Unix 机器 (RHEL 7.1) 上的 ifconfig 显示 docker0、ens、lo 和 veth 接口。没有eth0。对此有点困惑。
我努力获得该功能,我将分享我的经验以及我为获得您所需要的东西所做的工作。
简短回答:
您需要创建您自己的网桥,将您主机的物理网络接口连接到该网桥,并连接您希望表现得像普通容器一样的每个容器的虚拟接口在您的网络中桥接虚拟机,然后让容器在启动时选择自己的 IP 地址。
详细答案:
创建持久性网桥
Bridge
是一个设备(在我们的例子中是虚拟设备),其行为类似于网络交换机(主要在网络第 2 层运行),即它可以连接两个或多个网络接口 在同一个局域网 (LAN) 上,如果它们具有相同的子网。
您将创建新的持久性桥 br0
(它将在系统启动时自动启动),将您的物理网络接口添加到其中(在我的例子中是 eth0
)。请注意,将接口添加到网桥后,接口不再需要 IP 地址,因为网桥将获得 IP 地址并可以代替您的接口使用,即,您可以 使用网桥进行通信 就好像它是您的物理接口一样,它会将 in/out 数据包转发到正确的目的地。您不需要为网桥分配任何硬件(MAC地址),它会自动占用第一个添加接口的MAC。
Warning: It is highly recommended not to do these steps remotely except you have a physical access to your server! You may lose your connection to your server if you were not careful.
安装网桥管理实用程序:
sudo apt install bridge-utils
The system will not be able to create the bridge without bridge-utils
package.
要创建持久性桥,编辑 interfaces
文件:
sudo vim /etc/network/interfaces
将以下配置添加到文件末尾(根据您的需要调整它们):
auto br0
iface br0 inet static
bridge_ports eth0
address 192.168.1.10
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.1
现在删除 Docker 的默认网桥 docker0,因为我们不需要它:
sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0
编辑 Docker 的服务启动脚本以使用您的网桥 (br0) 而不是 Docker 的默认网桥 (docker0),并传递一些重要的网桥参数:
Ubuntu:
sudo vim /etc/systemd/multi-user.target.wants/docker.service
将文件调整为如下所示:
[Service]
ExecStart=/usr/bin/dockerd -H fd:// --bridge=br0 --fixed-cidr=192.168.1.32/27 --default-gateway=192.168.1.1
现在告诉系统关于该文件的更改:
sudo systemctl daemon-reload
重启系统:
sudo reboot
现在检查你的桥,它应该在那里!
ip addr
现在像下面这样创建你的容器,这将为你的容器提供一个固定 IP:
docker run --name myContainer \
-it --restart always --memory 100M \
--network bridge --cap-add NET_ADMIN \
--hostname client1.noureldin.local \
--add-host "client1.noureldin.local client1":192.168.1.123 \
mnoureldin/general-purpose:latest /bin/bash -c " \
ip addr flush dev eth0; \
ip addr add 192.168.1.123/24 brd + dev eth0; \
ip route add default via 192.168.1.1 dev eth0; \
/bin/bash"
与您的网络要求相关的重要部分是:
--network bridge --cap-add NET_ADMIN \
ip addr flush dev eth0; \
ip addr add 192.168.1.123/24 brd + dev eth0; \
ip route add default via 192.168.1.1 dev eth0; \
当然要确保你在你的容器中安装了 iproute2 net-tools iputils-ping
包,以便能够执行常见的网络命令(通过 ip
命令提供固定的 ip)。
第一次使用 运行 容器,您可能不会注意到 IP 地址有任何变化,因为您的容器可能没有 iproute2
包(即没有不是 ip
命令),只需安装提到的包,然后重新启动容器,一切都应该完全如您所愿!
希望对您有所帮助。
我目前的首选方法是使用 macvlan 或 ipvlan Docker 网络驱动程序。我更喜欢 macvlan,因为每个容器都可以有自己的 MAC 地址,但像 VMware 之类的东西不喜欢单个虚拟化网卡有多个 Mac 地址,并且无法正确路由流量。
设置非常简单。首先你需要确定一些事情。
- 您的主网络的子网。本例使用 10.0.0.0/24
- 您网络的网关。示例使用 10.0.0.1
- 用于分配 ips 的 IP 范围(如果需要,您可以在执行 Docker 运行 时静态分配此范围之外的 ips)。对于此示例,我将使用 10.0.0.128/25。您将需要大量 ips 来让 Docker 管理,因此您需要确保这些 ips 未在您的网络上使用。
- 您要用于流量的设备的名称。例如,我将使用 eth0
- 您要创建的新 Docker 网络的名称。以“我的网”为例。
接下来您要像这样创建一个新的 Docker 网络:
docker network create -d macvlan —-subnet 10.0.0.0/24 --ip-range 10.0.0.128/25 —-gateway 10.0.0.1 -o parent=eth0 mynet
现在启动容器时使用
docker run —-network mynet .....
有关详细信息,请参阅 docker 文档:https://docs.docker.com/engine/userguide/networking/get-started-macvlan
这种方法的一个警告是 macvlan/ipvlan 似乎不能很好地与 Docker 一起用于 Mac。它创建的 HyperKit vm 有点像黑盒子。 macvlan/ipvlan 方法需要一个更受控制的网络,Docker for Mac 无法提供。如果你想用 Docker 为 Mac 做这个,那么我建议设置一个 Docker Machine。有关如何执行此操作的文档位于:https://docs.docker.com/machine/get-started/.
在这种情况下,除非您喜欢在 Mac 上设置路由规则,否则您应该让 docker 机器使用桥接接口,然后可以连接 macvlan/ipvlan 网络到。根据我的经验,不需要通过 MacOS 主机进行 NAT 的第二个 NIC,但您可能会发现其他情况。
我不太熟悉 Unix 网络、添加虚拟接口等,现在正在尝试学习。我们正在尝试 docker 化我们的应用程序。
我的要求是:将 ip 分配给可从外部 application/browser 访问的 docker 容器。
容器 ip 应该可以从同一网络中的不同计算机 ping basically.I 不想使用端口转发。
我想访问一个 docker 容器,就像我们使用 ip 访问 VM 一样 address.[ 没有端口映射,-p 标志。如果我 运行 任何服务器,如 Apache 或 Tomcat 在容器内部,应该可以使用容器 ip 和 港口。例如:http://container_ip:8443]
这在 docker 中可能吗?运行 我的 Unix 机器 (RHEL 7.1) 上的 ifconfig 显示 docker0、ens、lo 和 veth 接口。没有eth0。对此有点困惑。
我努力获得该功能,我将分享我的经验以及我为获得您所需要的东西所做的工作。
简短回答:
您需要创建您自己的网桥,将您主机的物理网络接口连接到该网桥,并连接您希望表现得像普通容器一样的每个容器的虚拟接口在您的网络中桥接虚拟机,然后让容器在启动时选择自己的 IP 地址。
详细答案:
创建持久性网桥Bridge
是一个设备(在我们的例子中是虚拟设备),其行为类似于网络交换机(主要在网络第 2 层运行),即它可以连接两个或多个网络接口 在同一个局域网 (LAN) 上,如果它们具有相同的子网。
您将创建新的持久性桥 br0
(它将在系统启动时自动启动),将您的物理网络接口添加到其中(在我的例子中是 eth0
)。请注意,将接口添加到网桥后,接口不再需要 IP 地址,因为网桥将获得 IP 地址并可以代替您的接口使用,即,您可以 使用网桥进行通信 就好像它是您的物理接口一样,它会将 in/out 数据包转发到正确的目的地。您不需要为网桥分配任何硬件(MAC地址),它会自动占用第一个添加接口的MAC。
Warning: It is highly recommended not to do these steps remotely except you have a physical access to your server! You may lose your connection to your server if you were not careful.
安装网桥管理实用程序:
sudo apt install bridge-utils
The system will not be able to create the bridge without
bridge-utils
package.
要创建持久性桥,编辑 interfaces
文件:
sudo vim /etc/network/interfaces
将以下配置添加到文件末尾(根据您的需要调整它们):
auto br0
iface br0 inet static
bridge_ports eth0
address 192.168.1.10
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.1
现在删除 Docker 的默认网桥 docker0,因为我们不需要它:
sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0
编辑 Docker 的服务启动脚本以使用您的网桥 (br0) 而不是 Docker 的默认网桥 (docker0),并传递一些重要的网桥参数:
Ubuntu:
sudo vim /etc/systemd/multi-user.target.wants/docker.service
将文件调整为如下所示:
[Service]
ExecStart=/usr/bin/dockerd -H fd:// --bridge=br0 --fixed-cidr=192.168.1.32/27 --default-gateway=192.168.1.1
现在告诉系统关于该文件的更改:
sudo systemctl daemon-reload
重启系统:
sudo reboot
现在检查你的桥,它应该在那里!
ip addr
现在像下面这样创建你的容器,这将为你的容器提供一个固定 IP:
docker run --name myContainer \
-it --restart always --memory 100M \
--network bridge --cap-add NET_ADMIN \
--hostname client1.noureldin.local \
--add-host "client1.noureldin.local client1":192.168.1.123 \
mnoureldin/general-purpose:latest /bin/bash -c " \
ip addr flush dev eth0; \
ip addr add 192.168.1.123/24 brd + dev eth0; \
ip route add default via 192.168.1.1 dev eth0; \
/bin/bash"
与您的网络要求相关的重要部分是:
--network bridge --cap-add NET_ADMIN \
ip addr flush dev eth0; \
ip addr add 192.168.1.123/24 brd + dev eth0; \
ip route add default via 192.168.1.1 dev eth0; \
当然要确保你在你的容器中安装了 iproute2 net-tools iputils-ping
包,以便能够执行常见的网络命令(通过 ip
命令提供固定的 ip)。
第一次使用 运行 容器,您可能不会注意到 IP 地址有任何变化,因为您的容器可能没有 iproute2
包(即没有不是 ip
命令),只需安装提到的包,然后重新启动容器,一切都应该完全如您所愿!
希望对您有所帮助。
我目前的首选方法是使用 macvlan 或 ipvlan Docker 网络驱动程序。我更喜欢 macvlan,因为每个容器都可以有自己的 MAC 地址,但像 VMware 之类的东西不喜欢单个虚拟化网卡有多个 Mac 地址,并且无法正确路由流量。
设置非常简单。首先你需要确定一些事情。
- 您的主网络的子网。本例使用 10.0.0.0/24
- 您网络的网关。示例使用 10.0.0.1
- 用于分配 ips 的 IP 范围(如果需要,您可以在执行 Docker 运行 时静态分配此范围之外的 ips)。对于此示例,我将使用 10.0.0.128/25。您将需要大量 ips 来让 Docker 管理,因此您需要确保这些 ips 未在您的网络上使用。
- 您要用于流量的设备的名称。例如,我将使用 eth0
- 您要创建的新 Docker 网络的名称。以“我的网”为例。
接下来您要像这样创建一个新的 Docker 网络:
docker network create -d macvlan —-subnet 10.0.0.0/24 --ip-range 10.0.0.128/25 —-gateway 10.0.0.1 -o parent=eth0 mynet
现在启动容器时使用
docker run —-network mynet .....
有关详细信息,请参阅 docker 文档:https://docs.docker.com/engine/userguide/networking/get-started-macvlan
这种方法的一个警告是 macvlan/ipvlan 似乎不能很好地与 Docker 一起用于 Mac。它创建的 HyperKit vm 有点像黑盒子。 macvlan/ipvlan 方法需要一个更受控制的网络,Docker for Mac 无法提供。如果你想用 Docker 为 Mac 做这个,那么我建议设置一个 Docker Machine。有关如何执行此操作的文档位于:https://docs.docker.com/machine/get-started/.
在这种情况下,除非您喜欢在 Mac 上设置路由规则,否则您应该让 docker 机器使用桥接接口,然后可以连接 macvlan/ipvlan 网络到。根据我的经验,不需要通过 MacOS 主机进行 NAT 的第二个 NIC,但您可能会发现其他情况。