更改docker容器中的默认路由 [英] Change default route in docker container

查看:3011
本文介绍了更改docker容器中的默认路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个docker容器连接到两个网络,默认网桥和一个自定义网桥。通过默认值,它仅在默认网络中链接到另一个容器,并通过自定义桥接器获取本地网络中的IP地址。

  LAN  -  [homenet]  -  container1  -  [bridge]  -  container2 

sudo docker network inspect homenet
[{Name:homenet,
Scope:local,
Driver:bridge,
EnableIPv6:false,
IPAM:{
Driver默认,
选项:{},
配置:[{子网:192.168.130.0/24,
网关:192.168.130.8
AuxiliaryAddresses:{DefaultGatewayIPv4:192.168.130.3}}]
},
内部:false,
容器:{
$ cid1:{Name:container,
EndpointID:$ eid1_1,
MacAddress:$ mac1_1,
IPv4Address:192.168 .130.38 / 24,}
},
选项:{com.docker.network.br idge.name:br-homenet},
标签:{}}]

和桥梁:

  sudo docker网络检查桥

[{
名称:bridge,
Scope:local,
Driver:bridge,
EnableIPv6:false,
IPAM
Driver:default,
Options:null,
Config:[{Subnet:172.17.0.0/16}]
} ,
Internal:false,
Containers:{
$ cid2:{
Name:container2,
EndpointID $ eid2,
MacAddress:$ mac2,
IPv4Address:172.17.0.2/16,
IPv6Address:},
$ cid1:{
Name:container1,
EndpointID:$ eid1_2,
MacAddress:$ mac1_2,
IPv4Address :172.17.0.3/16,
IPv6Address:}
},
选项:{
c om.docker.network.bridge.default_bridge:true,
com.docker.network.bridge.enable_icc:true,
com.docker.network.bridge.enable_ip_masquerade :true,
com.docker.network.bridge.host_binding_ipv4:0.0.0.0,
com.docker.network.bridge.name:docker0,
com.docker.network.driver.mtu:1500
},
标签:{}
}]
/ pre>

从内部网络运行得很好,但是我有路由问题:

  sudo docker exec -it container1 route -n 

内核IP路由表
目标网关Genmask标志度量标准参考使用Iface
0.0.0.0 172.17。 0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
192.168.130.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1

怎么可能我将默认路由更改为192.169.130.3,以使其重新启动?



我可以更改它,而container1正在运行

  pid = $(sudo docker inspect -f'{{.State.Pid}}'container1)
sudo mkdir -p / var / run / netns
sudo ln -s / proc / $ pid / ns / net / var / run / netns / $ pid
sudo ip netns exec $ pid ip route del default
sudo ip netns exec $ pid ip路由添加默认通过192.168.130.3

但重新启动后不见了。如何更改?



更新:显然,网络的字典顺序也可能成为问题的一部分。

解决方案

如果我明白这个问题,问题是:重新启动时一个连接到多个网桥的容器,如何选择一个桥接器用于默认路由?



我搜索了可用的选项并进行了一些测试,我没有找到任何docker命令行选项用于指定默认路由,或者当容器连接到多个网桥时,将桥作为默认路由。当我重新启动连接到默认网桥( bridge )的容器和一个自定义网桥(您的 homenet )时,默认路由自动设置为使用默认网桥(网关 172.17.0.1 )。这对应于您描述的行为。



解决方案1:在运行命令中指定启动脚本,负责更改默认路由并启动服务(s)你容器必须运行

  docker run \ 
--cap-add NET_ADMIN \#允许更改容器内的网络设置
--name container1 \
--restart always \#restart policy
your_image \
/path/to/your_start_script.sh

your_start_script.sh

  ip route del default 
ip route add default via 192.168.130.3

#这里是你的容器应该运行的指令/服务

这个脚本有在容器中可用,它可以在共享文件夹( -v 选项)上,或者在使用Dockerfile的图像构建中加载。



N ote:在将容器连接到您的自定义桥( docker network connect homenet container1 )之前, your_start_script.sh 将崩溃,因为默认路由不对应任何可用的网络。



我测试了记录 ip route code> container1 运行 - 始终重新启动,将其连接到自定义网桥后,它具有所需的默认路由。



解决方案2:从容器开始事件的主机设置容器默认路由

  docker events --filtercontainer = container1| \ 
awk'/ container start / {system(/ path / to / route_setting.sh) $'

其中 route_setting.sh 包含您的更改容器默认路由的说明:

  pid = $(sudo docker inspect -f' {.STA te.Pid}}'container1)
sudo mkdir -p / var / run / netns
sudo ln -s / proc / $ pid / ns / net / var / run / netns / $ pid
sudo ip netns exec $ pid ip route del default
sudo ip netns exec $ pid ip route添加默认值通过192.168.130.3

此解决方案避免给容器提供特殊权限,并将路由更改责任转移给主机。


I have a docker container that is connected to two networks, the default bridge and a custom bridge. Via the default, it is linked to another container only in the default network and via the custom bridge, it gets an IP address in local network.

LAN -- [homenet] -- container1 -- [bridge] -- container2

sudo docker network inspect homenet
[{  "Name": "homenet",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
        "Driver": "default",
        "Options": {},
        "Config": [{ "Subnet": "192.168.130.0/24",
                     "Gateway": "192.168.130.8",
                     "AuxiliaryAddresses": { "DefaultGatewayIPv4": "192.168.130.3" }}]
    },
    "Internal": false,
    "Containers": {
        "$cid1": { "Name": "container",
                   "EndpointID": "$eid1_1",
                   "MacAddress": "$mac1_1",
                   "IPv4Address": "192.168.130.38/24", }
    },
    "Options": { "com.docker.network.bridge.name": "br-homenet" },
    "Labels": {}}]

and bridge:

sudo docker network inspect bridge

[{
    "Name": "bridge",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
        "Driver": "default",
        "Options": null,
        "Config": [{ "Subnet": "172.17.0.0/16" }]
    },
    "Internal": false,
    "Containers": { 
      "$cid2": {
            "Name": "container2",
            "EndpointID": "$eid2",
            "MacAddress": "$mac2",
            "IPv4Address": "172.17.0.2/16",
            "IPv6Address": "" }, 
      "$cid1": {
            "Name": "container1",
            "EndpointID": "$eid1_2",
            "MacAddress": "$mac1_2",
            "IPv4Address": "172.17.0.3/16",
            "IPv6Address": "" }
    },
    "Options": {
        "com.docker.network.bridge.default_bridge": "true",
        "com.docker.network.bridge.enable_icc": "true",
        "com.docker.network.bridge.enable_ip_masquerade": "true",
        "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
        "com.docker.network.bridge.name": "docker0",
        "com.docker.network.driver.mtu": "1500"
    },
    "Labels": {}
}]

This works pretty well from the internal network, however, I have a routing problem:

sudo  docker exec -it container1 route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0
192.168.130.0   0.0.0.0         255.255.255.0   U     0      0        0 eth1

How can I change the default route to 192.169.130.3 such that it persists a restart?

I can change it while container1 is running with

 pid=$(sudo docker inspect -f '{{.State.Pid}}' container1)
 sudo mkdir -p /var/run/netns
 sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
 sudo ip netns exec $pid ip route del default 
 sudo ip netns exec $pid ip route add default via 192.168.130.3

but that is gone after a restart. How can I change that?

Update: Apparently, the lexicographical order of the networks could also be part of the issue. I will test it when I get a chance.

解决方案

If I understand the question, the problem is : when restarting a container connected to multiple bridges, how to prefer a bridge to use for default route ?

I searched available options and made some tests, I did not found any docker command line option to specify a default route or to prefer a bridge as default when the container is connected to multiple bridges. When I restart a container connected to the default bridge (bridge) and a custom bridge (your homenet), the default route is automatically set to use the default bridge (gateway 172.17.0.1). This corresponds to the behavior you describe.

Solution 1: Specify a start script in the run command that is in charge to change the default route and start the service(s) you container has to run:

docker run \
  --cap-add NET_ADMIN \ # to allow changing net settings inside the container 
  --name container1 \
  --restart always \ # restart policy
  your_image \
  /path/to/your_start_script.sh

The your_start_script.sh:

ip route del default 
ip route add default via 192.168.130.3

# here goes instructions/services your container is supposed to run

This script has to be available inside the container, it can be on a shared folder (-v option) or loaded at image building with a Dockerfile.

Note: before connecting the container to your custom bridge (docker network connect homenet container1), your_start_script.sh will crash because the default route does not correspond to any available network.

I tested to log the output of ip route inside container1 run with --restart always, after connecting it to the custom bridge it has the wanted default route.

Solution 2: Set container default route from host on container start events

docker events --filter "container=container1" |\
  awk '/container start/ { system("/path/to/route_setting.sh") }'

Where route_setting.sh contains your instructions for changing the container's default route:

pid=$(sudo docker inspect -f '{{.State.Pid}}' container1)
sudo mkdir -p /var/run/netns
sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
sudo ip netns exec $pid ip route del default 
sudo ip netns exec $pid ip route add default via 192.168.130.3

This solution avoids giving special permissions to the container and transfers the route changing responsibility to the host.

这篇关于更改docker容器中的默认路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆