Перезапуск именованного контейнера назначает другой IP

Я пытаюсь развернуть мое приложение с помощью Docker и столкнулся с проблемой, при которой перезапуск именованных контейнеров назначает другой IP-адрес контейнеру. Возможно объяснение того, что я делаю, лучше объяснит проблему:

  • Postgres работает внутри отдельного контейнера с именем "postgres"
    $ PG_ID=$(docker run --name postgres postgres/image)
  • Мой контейнер веб-приложения ссылается на контейнер Postgres
    $ APP_ID=$(docker run --link postgres:postgres webapp/image)

Связывание изображения контейнера postgres с контейнером webapp вставляет в контейнер webapp запись файла hosts с IP-адресом контейнера postgres. Это позволяет мне указывать на postgres db в моем веб-приложении, используя postgres:5432 (Я использую Django, кстати). Это все работает хорошо, за исключением случаев, когда по какой-то причине происходит сбой postgres.

Прежде чем вручную остановить процесс postgres для имитации сбоя процесса postgres, я проверяю IP контейнера postgres:

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.73

Теперь, чтобы симулировать сбой, я остановлю контейнер postgres:

$ docker stop $PG_ID

Если сейчас я перезапустить Postgres с помощью

$ docker start $PG_ID

ip контейнера меняется:

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.74

Поэтому IP-адрес, который указывает на контейнер postgres в контейнере webapp, больше не является правильным. Хотя я и назвал контейнер, докер присваивает ему имя с конкретными настройками, чтобы вы могли надежно связывать контейнеры (как сетевые, так и томовые). Если IP-адрес меняется, это, кажется, побеждает цель.

Если мне приходится перезапускать свой процесс веб-приложения каждый раз, когда я перезапускаю postgres, это выглядит не лучше, чем просто использование одного контейнера для запуска обоих процессов. Тогда я могу использовать супервизор или что-то подобное, чтобы оба они работали и использовали localhost связать между процессами.

Я все еще новичок в Docker, так что я делаю что-то не так или это ошибка в Docker?

3 ответа

2-е ОБНОВЛЕНИЕ: возможно, вы уже обнаружили это, но в качестве обходного пути я планирую сопоставить службу для совместного использования базы данных с интерфейсом хоста (ej: с -p 5432:5432) и подключить веб-приложения к IP-адресу хоста (IP-адресу интерфейс docker0: в моем Ubuntu и CentOS IP-адрес 172.17.42.1). Если вы перезапустите контейнер postgres, IP-адрес участника изменится, но я буду доступен, используя 172.17.42.1:5432. Недостатком является то, что вы открываете этот порт для всех контейнеров и теряете мелкозернистое отображение, которое дает вам --link.

--- Старые обновления:

ИСПРАВЛЕНИЕ: Docker отобразит postgres на IP-адрес контейнера в файлах /etc/hosts в контейнере webapp. Таким образом, в контейнере веб-приложения вы можете пропинговать "postgres", и он будет привязан к IP-адресу.

1-е ОБНОВЛЕНИЕ: я видел, что Docker генерирует и монтирует /etc/hosts, /etc/resolv.conf и т. Д., Чтобы всегда иметь правильную информацию, но это не применяется, когда связанный контейнер перезапускается. Итак, я предположил (ошибочно), что Docker обновит файлы hosts.

- ОРИГИНАЛЬНЫЙ (неправильный) ответ:

Добавьте --hostname=postgres-db (вы можете использовать что угодно, я использую что-то отличное от 'postgres', чтобы избежать путаницы с именем контейнера):

$ docker run --name postgres --hostname postgres-db postgres/image

Docker сопоставит postgres-db с IP-адресом контейнера (проверьте содержимое /etc/hosts в контейнере webapp).

Это позволит вам запустить ping postgres-db из контейнера веб-приложения. Если IP-адрес изменится, докеры обновят /etc/hosts для вас.

В приложении Django используйте "postgres-db" вместо IP (или что-либо, что вы используете для --hostname контейнера с PostgreSql).

До свидания! Орасио

Согласно https://docs.docker.com/engine/reference/commandline/run/, должна быть возможность назначить статический IP для вашего контейнера - во время создания контейнера - используя --ip опция:

Пример:

docker run -itd --ip 172.30.100.104 --name postgres postgres/image

.... где 172.30.100.104 - это бесплатный IP-адрес в пользовательской сети моста / оверлея.

Затем он должен сохранить тот же IP-адрес, даже если контейнер postgres аварийно завершает работу / перезапускается.

Похоже, что это было выпущено в Docker Engine v 1.10 или более поздней версии, поэтому, если у вас более низкая версия, вы должны сначала выполнить обновление.

Начиная с Docker 1.0 они реализовали более сильное чувство связанных контейнеров. Теперь вы можете использовать имя экземпляра контейнера, как если бы оно было именем хоста.

Вот ссылка

Я нашел ссылку, которая лучше описывает вашу проблему. И хотя на этот вопрос был дан ответ, я задаюсь вопросом, может ли этот образец посла решить проблему... это предполагает, что посол более надежен, чем службы, которые связывают.

Другие вопросы по тегам