Призначте статичний IP для контейнера Docker


205

Зараз я намагаюся призначити статичний IP 172.17.0.1 при запуску контейнера Docker.

Я використовую порт 2122 як порт ssh цього контейнера, так що я дозволяю цьому контейнеру прослуховувати порт 2122.

sudo docker run -i -t -p 2122:2122 ubuntu

Ця команда запустить контейнер Docker з випадковим IP, наприклад 172.17.0.5, але мені потрібно призначити конкретний IP-адресу контейнеру.

Наступний скрипт оболонки - це те, на що я посилаюся на документацію Docker у розширених мережевих налаштуваннях.

pid=$(sudo docker inspect -f '{{.State.Pid}}' <container_name> 2>/dev/null)
sudo rm -rf /var/run/netns/*
sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
sudo ip link add A type veth peer name B
sudo brctl addif docker0 A
sudo ip link set A up
sudo ip link set B netns $pid
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link delete eth0
sudo ip netns exec $pid ip link set dev B name eth0
sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link set eth0 up
sudo ip netns exec $pid ip addr add 172.17.0.1/16 dev eth0
sudo ip netns exec $pid ip route add default via 172.17.42.1

Цей скрипт оболонки призначить статичний IP 172.17.0.1 і посилається на світовий штраф. Але кожного разу, коли я намагаюся перенести цей контейнер у свій локальний, це не вийшло. Яка проблема, можливо, я зустрів?


Я боюся , що це не проста відповідь на це питання, см github.com/docker/docker/issues/6743 і github.com/docker/docker/issues/1179 , і читати github.com/jpetazzo/pipework
user2915097

@larrylo Ви можете підтвердити, що ви запустили sshd всередині контейнера?
Браян

5
Ви скасовуєте всю маршрутизацію, яку робить докерський демон для вас. Контейнери - це не автомашини.
користувач2105103

Так, я підтверджую, що можу запустити sshd всередині контейнера
LarryLo

Відповіді:


291

Легко з Docker версії 1.10.1, збірка 9e83765.

Спочатку потрібно створити власну докерську мережу (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

ніж просто запустити зображення (я візьму ubuntu як приклад)

docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash

потім в оболонці ubuntu

ip addr

Додатково ви можете використовувати

  • --hostname щоб вказати ім'я хоста
  • --add-host щоб додати більше записів до / etc / hosts

Документи (і чому вам потрібно створити мережу) за адресою https://docs.docker.com/engine/reference/commandline/network_create/


1
Великий відповідь - Просто додавши деяку додаткову інформацію: blog.jessfraz.com/post/ips-for-all-the-things
Ole

@cantSleepNow мені чомусь потрібно просто використовувати власний створений за замовчуванням міст br0, який створюється у файлі інтерфейсів під час завантаження системи (тому НЕ створюється за допомогою створення мережі докер), чи можете ви підказати мені, як я можу отримати той же ефект - -ip параметр (отримати фіксовану IP-адресу для контейнера), не створюючи мій міст за допомогою докера?
Мухаммед Нурелдін

@MohammedNoureldin Я не повністю розумію - також звучить як нове запитання, я думаю, вам слід його задати як таке.
cantSleepNow

@cantSleepNow Я маю на увазі, що мені потрібно виправити IP-адресу контейнера, хоча я НЕ використовую користувальницький міст (тому параметр --ip не можна використовувати), ви пропонуєте який-небудь спосіб отримати це?
Мухаммед Нурелдін

@MohammedNoureldin Я не впевнений. Як я вже говорив, розміщуйте своє питання як питання, а не як коментар - можливо, хтось знає відповідь.
cantSleepNow

89

Для docker-composeви можете використовувати наступнеdocker-compose.yml

version: '2'
services:
  nginx:
    image: nginx
    container_name: nginx-container
    networks:
      static-network:
        ipv4_address: 172.20.128.2
networks:
  static-network:
    ipam:
      config:
        - subnet: 172.20.0.0/16
          #docker-compose v3+ do not use ip_range
          ip_range: 172.28.5.0/24

від хоста, який ви можете протестувати, використовуючи:

docker-compose up -d
curl 172.20.128.2

Модерн docker-composeне часто змінює ip-адресу.

Щоб знайти ips усіх контейнерів у вашому docker-composeодному рядку, використовуйте:

for s in `docker-compose ps -q`; do echo ip of `docker inspect -f "{{.Name}}" $s` is `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $s`; done

Якщо ви хочете автоматизувати, ви можете використовувати щось на зразок цього прикладу


2
Схоже, це буде працювати лише у сумісній сумісності docker-compose v2, v3.
Анджей Реманн

4
Під час використання docker-compose v3 + removeip_range
Анджей Реманн

Я не отримую ip_range, однак. це не підпадає підмережу? У будь-якому випадку, дякую! Це вирішило моє "я мушу знову шукати ip свого контейнера mongo" - випуск
Бен

1
чи є спосіб вказати ip-адресу у складеній версії 3?
ealeon

2
Рішення для мене чудово працює ip_range . Я використовую версію: '3.4'.
Михайло Морфіков

24

Не пряма відповідь, але це могло б допомогти.

Я запускаю більшість моїх докерізованих служб, прив'язаних до власних статичних ips, використовуючи наступний підхід:

  1. Я створюю ip псевдоніми для всіх служб хоста докера
  2. Потім я запускаю кожну службу переадресації портів з цього ip в контейнер, щоб у кожної служби був власний статичний ip, який можна було б використовувати зовнішнім користувачам та іншим контейнерам.

Зразок:

docker run --name dns --restart=always -d -p 172.16.177.20:53:53/udp dns
docker run --name registry --restart=always -d -p 172.16.177.12:80:5000 registry
docker run --name cache --restart=always -d -p 172.16.177.13:80:3142 -v /data/cache:/var/cache/apt-cacher-ng cache
docker run --name mirror --restart=always -d -p 172.16.177.19:80:80 -v /data/mirror:/usr/share/nginx/html:ro mirror
...

Спасибі ~ Я це знаю. Так само, як це роблять github.com/brandon-rhodes/fopnp/tree/m/playground . Я спробую.
LarryLo

1
Це дуже хороше рішення, я би просто долучив це посилання для нових користувачів, щоб дізнатися про псевдонім cyberciti.biz/faq/…
Мохаммед Нурелдін

Дякую за приємне рішення.
RavinderSingh13

4

Це працює для мене.

Створіть мережу за допомогою docker network create --subnet=172.17.0.0/16 selnet

Запустити зображення докера docker run --net selnet --ip 172.18.0.2 hub

Спочатку я дістав

docker: Error response from daemon: Invalid address 172.17.0.2: It does not belong to any of this network's subnets.
ERRO[0000] error waiting for container: context canceled

Рішення: Збільшено 2-ту четверту ІР [.18. замість .17.]


3
Там в 2 роки старший схожий / ідентичний відповідь в іншому місці на цій сторінці: stackoverflow.com/a/35359185/694469
KajMagnus

2

Я натрапив на цю проблему під час спроби докерізувати Avahi, який повинен бути обізнаний про свій публічний IP, щоб правильно функціонувати. Призначення статичного IP до контейнера складне через відсутність підтримки для статичного призначення IP в Docker.

Ця стаття описує техніку, як призначити статичний IP контейнеру на Debian :

  1. Почати службу докера слід DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Я припускаю, що br0міст вже налаштований.

  2. Контейнер слід починати з --cap-add=NET_ADMIN --net=bridge

  3. Всередині контейнера pre-up ip addr flush dev eth0в /etc/network/interfacesможна використовувати для відхилення IP-адреси, призначеної Docker, як у наступному прикладі:


auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    pre-up ip addr flush dev eth0
    address 192.168.0.249
    netmask 255.255.255.0
    gateway 192.168.0.1
  1. Сценарій введення контейнера повинен починатися з /etc/init.d/networking start. Сценарій вступу також повинен відредагувати або заповнити /etc/hostsфайл, щоб видалити посилання на призначений Docker IP.

2

Ви можете встановити IP під час його запуску.

docker run --cap-add=NET_ADMIN -dit imagename /bin/sh -c "/sbin/ip addr add 172.17.0.12 dev eth0; bash"

Дивіться мій приклад на https://github.com/RvdGijp/mariadb-10.1-galera


на жаль, це додає ще одну IP-адресу, якщо IP-адреса була призначена в процесі раніше, це призводить до наявності двох IP-адрес
Davey

1

Ви можете отримати доступ до служби інших контейнерів за їх назвою ( ping apacheотримаєте ip або отримаєте curl http://apacheдоступ до сервісу http) І це може бути альтернативою статичному ip.


3
У докерній версії 1.8 це працює безпосередньо. У новій версії ви повинні кулачно зв’язати ці контейнери.
Guisong He

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.