简体   繁体   English

将LAN IP地址分配给Docker容器,与主机的IP地址不同

[英]Assign LAN IP address to Docker container different from host's IP address

Am not well versed with Unix networking, adding virtual interfaces etc, trying to learn it now. 我不熟悉Unix网络,添加虚拟接口等,现在尝试学习它。 We are trying to dockerize our application. 我们正试图将我们的应用程序停靠。
My requirement is : To assign an ip to a docker container which is accessible from an external application/browser. 我的要求是:将ip分配给可从外部应用程序/浏览器访问的docker容器。

The container ip should be pingable from a different computer in the same network basically.I don't want to use port forwarding. 容器ip应该可以从同一网络中的不同计算机ping通。我不想使用端口转发。

  1. I want to access a docker container just like we access a VM using an ip address.[ Without the port mapping, -p flag. 我想访问一个docker容器,就像我们使用ip地址访问VM一样。[没有端口映射,-p标志。 If i run any server like Apache or Tomcat inside the container, it should be accessible using the container ip and port. 如果我在容器内运行Apache或Tomcat之类的任何服务器,则应使用容器ip和端口访问它。 For example: http://container_ip:8443] 例如: http:// container_ip:8443]
    Is this possible in docker? 在码头工程中这可能吗?

  2. Running ifconfig on my Unix box(RHEL 7.1) shows docker0, ens,lo and veth interfaces. 在我的Unix机器上运行ifconfig(RHEL 7.1)显示docker0,ens,lo和veth接口。 There is no eth0. 没有eth0。 Kind of confused on this. 有点困惑。

I struggled to get that functionality, and I will share my experience and what I did to get exactly what you need. 我努力获得这项功能,我将分享我的经验以及我所做的工作以获得您所需要的。

The short answer: 简短的回答:

You need to create your own bridge , connect your host's physical network interface to that bridge, and as well connect the virtual interfaces of each container you want to behave like a normal bridged vritual machine in your network, and then make the container chooses its own IP address when it starts. 您需要创建自己的网桥 ,将主机的物理网络接口连接到该网桥,并将您想要表现的每个容器的虚拟接口连接到网络中的普通桥接虚拟机,然后让容器选择自己的启动时的IP地址。

The detailed answer: 详细答案:

Creating Persistence Network Bridge 创建持久性网桥

The Bridge , is a device (in our case virtual device), which behaves similar to network swiches (operates mainly on network layer 2), ie, it can connect two or more network interfaces to be on the same local area network (LAN) if they have the same subnet . Bridge是一种设备(在我们的例子中是虚拟设备),其行为类似于网络swiches(主要在网络层2上运行),即,它可以将两个或多个网络接口连接到同一局域网(LAN)上如果他们有相同的子网

You are going to create new persistence bridge br0 (it will get started automatically on system boot), add your physical network interface into it (in my case it is eth0 ). 您将创建新的持久性桥接器br0 (它将在系统引导时自动启动),将您的物理网络接口添加到其中(在我的情况下,它是eth0 )。 Note that after you add your interface to the bridge, the interface doesn't need IP address anymore, because the bridge will get IP address and can be used instead of your interface, ie, you can communicate using the bridge as if it were your physical interface and it will forward the in/out data packets to the correct destination. 请注意,在将接口添加到网桥后,接口不再需要IP地址,因为网桥将获得IP地址,可以代替您的接口使用,也就是说,您可以使用网桥进行通信,就好像它是您的物理接口,它将输入/输出数据包转发到正确的目的地。 You don't need to assign any hardware (MAC address) to the bridge, it will automatically take the MAC of the first added interface. 您不需要将任何硬件(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. 如果您不小心,可能会丢失与服务器的连接。

Install bridges managing utility: 安装桥管理实用程序:

 sudo apt install bridge-utils 

The system will not be able to create the bridge without bridge-utils package. 没有bridge-utils包,系统将无法创建桥。

To create persistence bridge, edit interfaces file: 要创建持久性桥,请编辑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

Add the follwing configuration to the end of the file (adapt them to suit your needs): 将以下配置添加到文件末尾(根据您的需要进行调整):

sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0

Now remove Docker's default bridge docker0, as we don't need it: 现在删除Docker的默认桥接器docker0,因为我们不需要它:

 sudo systemctl stop docker sudo ip link set dev docker0 down sudo brctl delbr docker0 

Edit Docker's service-start script to use your bridge (br0) instead of Docker's default bridge (docker0), and pass some important bridge parameters: 编辑Docker的服务启动脚本以使用您的网桥(br0)而不是Docker的默认网桥(docker0),并传递一些重要的网桥参数:

Ubuntu: Ubuntu的:

[Service]

ExecStart=/usr/bin/dockerd -H fd:// --bridge=br0 --fixed-cidr=192.168.1.32/27 --default-gateway=192.168.1.1

Adapt the file to look like this: 将文件调整为如下所示:

sudo systemctl daemon-reload

Now tell the system about the changes on that file: 现在告诉系统有关该文件的更改:

sudo reboot

Reboot the system: 重启系统:

ip addr

Now check your bridge, it should be there! 现在检查你的桥,它应该在那里!

  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"

Now create your container like bellow, this will lead to give your container a fix IP : 现在创建像bellow一样的容器, 这将导致为您的容器提供修复IP

  --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; \

The important part related to your network requirements is: 与您的网络要求相关的重要部分是:

  --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; \\ 

Of course be sure that you installed iproute2 net-tools iputils-ping packages in your container to be able to execute the common network commands (giving the fixed ip done by ip command). 当然,请确保在容器中安装了iproute2 net-tools iputils-ping软件包,以便能够执行公共网络命令(通过ip命令完成固定IP)。

For the first time you run the container, you may NOT notice any changes in IP address, because your conainer probably doesn't have iproute2 package (ie there is not ip command) , just intall the mentioned packages and then restart the container and everything should be exactly as you want! 第一次运行容器时,您可能不会注意到IP地址的任何更改,因为您的conainer可能没有iproute2包(即没有ip命令) ,只是安装提到的包然后重启容器和一切应该完全按照你的意愿!

Hope that helps. 希望有所帮助。

My current preferred approach with this is to use either the macvlan or ipvlan Docker network driver. 我目前首选的方法是使用macvlan或ipvlan Docker网络驱动程序。 I prefer macvlan as each container can have its own MAC address but some things like VMware don't like having multiple Mac addresses for a single virtualized nic and won't route traffic properly. 我更喜欢macvlan,因为每个容器都有自己的MAC地址,但有些像VMware这样的东西不喜欢为单个虚拟化的nic提供多个Mac地址,并且不会正确路由流量。

Setup is pretty straight forward. 安装非常简单。 First you need to determine a few things. 首先,您需要确定一些事情。

  • Subnet of your main network. 主网络的子网。 Using 10.0.0.0/24 for this example 在此示例中使用10.0.0.0/24
  • Gateway of your network. 您网络的网关。 Using 10.0.0.1 for the example 使用10.0.0.1作为示例
  • IP range to use for allocating the ips from (you can statically assign ips outside this range when doing a Docker run if need be). 用于分配ips的IP范围(如果需要,可以在执行Docker运行时静态分配ips超出此范围)。 For this example I will use 10.0.0.128/25. 对于此示例,我将使用10.0.0.128/25。 You will need a chunk of ips to let Docker manage so you will need to ensure these ips are not in use on your network. 您将需要一大块ips才能让Docker管理,因此您需要确保这些ips未在您的网络上使用。
  • The name of the device you want to use for the traffic. 要用于流量的设备的名称。 For the example I will use eth0 对于示例,我将使用eth0
  • The name of the new Docker network you are going to create. 您要创建的新Docker网络的名称。 Using “my net” for the example. 使用“我的网”作为例子。

Next you create a new Docker network like so: 接下来,您将创建一个新的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

Now when you start containers use 现在当你开始使用容器时

docker run —-network mynet .....

For more information see the docker docs: https://docs.docker.com/engine/userguide/networking/get-started-macvlan 有关更多信息,请参阅docker文档: https//docs.docker.com/engine/userguide/networking/get-started-macvlan

One caveat to this approach is that macvlan/ipvlan dont seem to work very well with Docker for Mac. 这种方法的一个警告是macvlan / ipvlan似乎不适用于Docker for Mac。 The HyperKit vm it creates is a bit of a black box. 它创建的HyperKit vm有点像黑盒子。 The macvlan/ipvlan approach requires a more controlled network that Docker for Mac doesn't give you. macvlan / ipvlan方法需要一个更加可控的网络,Docker for Mac无法为您提供。 If you are trying to do this with Docker for Mac then I would suggest setting up a Docker Machine. 如果您尝试使用Docker for Mac执行此操作,那么我建议您设置Docker Machine。 The docs for how to do that are here: https://docs.docker.com/machine/get-started/ . 有关如何执行此操作的文档,请访问: https//docs.docker.com/machine/get-started/

In this scenario, unless you like setting up routing rules on your Mac, you should have the docker machine use a bridged interface that the macvlan/ipvlan network can then be attached to. 在这种情况下,除非您喜欢在Mac上设置路由规则,否则您应该让docker计算机使用桥接接口,然后可以将macvlan / ipvlan网络连接到该接口。 In my experience the need for a second NIC that is NAT'ed through the MacOS host is unnecessary but you may find something otherwise. 根据我的经验,不需要通过MacOS主机进行NAT的第二个NIC,但你可能会发现其他的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM