2016-04-27 3 views
12

У меня есть контейнер докеров, который подключен к двум сетям, мосту по умолчанию и настраиваемому мосту. По умолчанию он связан с другим контейнером только в сети по умолчанию и с помощью настраиваемого моста получает IP-адрес в локальной сети.Изменить маршрут по умолчанию в контейнере докера

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": {}}] 

и мост:

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": {} 
}] 

Это работает очень хорошо из внутренней сети, однако, у меня есть проблема маршрутизации:

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 

Как я могу изменить маршрут по умолчанию 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 route add default via 192.168.130.3 

но ушел после перезагрузки. Как я могу это изменить?

Обновление: По-видимому, the lexicographical order of the networks также может быть частью проблемы. Я проверю его, когда у меня появится шанс.

ответ

12

Если я понимаю вопрос, возникает проблема: при перезапуске контейнера, подключенного к нескольким мостам, как выбрать мост для использования по умолчанию?

Я искал доступные параметры и провел несколько тестов, я не нашел опции командной строки докеры, чтобы указать маршрут по умолчанию или предпочесть мост по умолчанию, когда контейнер подключен к нескольким мостам. Когда я перезапускаю контейнер, подключенный к мосту по умолчанию (bridge) и настраиваемый мост (ваш homenet), по умолчанию маршрут автоматически устанавливается на использование моста по умолчанию (шлюз 172.17.0.1). Это соответствует описанному вами поведению.

Решение 1: Задайте сценарий запуска в команде запуска, который отвечает за изменения маршрута по умолчанию и запустить службу (ы), контейнер должен работать:

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 

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 

Этот сценарий должен быть доступен внутри контейнера, он может быть в общей папке (-v опция) или загруженным в здании изображения с Dockerfile.

Примечание: перед подключением контейнера к пользовательскому мосту (docker network connect homenet container1), your_start_script.sh потерпит крах, поскольку маршрут по умолчанию не соответствует какой-либо доступной сети.

Я протестировал, чтобы зарегистрировать вывод ip route внутри container1 с --restart always, после подключения его к пользовательскому мосту у него есть желаемый маршрут по умолчанию.

Решение 2: Установите контейнер по умолчанию маршрут от хоста на контейнере запуска события

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

Где route_setting.sh содержит ваши инструкции по изменению маршрута по умолчанию контейнера:

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 

Это решение позволяет избежать предоставления специального разрешений к контейнеру и передает маршрут, изменяющий ответственность хозяину.

+0

Спасибо , это хороший nswer. Однако мне не нравится, что мне нужно предоставить специальные возможности контейнера. Можете ли вы как-то отказаться от них после выполнения команды? Для бонусных очков есть ли способ автоматически автоматически запускать правильный скрипт/программу (чтобы я не мог корректировать ваш скрипт, если изменяется имя сценария в контейнере докера)? – martin

+0

Мне нравится намек на то, что сценарий может находиться в томе, я забыл об этом, но это избавляет меня от некоторых головных болей. – martin

+0

Я обновил свой андер, чтобы добавить второе решение, которое должно избежать проблем, которые вы описываете. – Silicium14

0

с вариантом например:

dockerd --bip 10.1.0.1/24 

если вы используете убунту 14,04, изменить

/etc/default/docker 

если вы используете убунту 16,04, изменить

/lib/systemd/system/docker 
+0

Я не понимаю, что вы здесь делаете. '--bip' изменяет CIDR моста докере по умолчанию. Вопрос OP более специфичен для маршрута по умолчанию для отдельного контейнера. Может быть, если вы можете объяснить немного больше, а не просто давать команды для выполнения? – tudor

Смежные вопросы