Docker: как подключиться к контейнеру Postgresql, не открывая порт

Я настроил приложение Elixir/Phoenix в док-контейнере и отдельный контейнер для сервера Postgresql. Я могу подключиться к серверу Postgresql, только когда открываю порт 5432. Но я не хочу, чтобы порт был общедоступным, так как это довольно небезопасно. Сервер Postgresql должен быть доступен только из контейнера phoenix.

Но если я не открываю порт, я просто получаю сообщение об ошибке «Отказано в соединении» в контейнере phoenix.

app-phoenix-1 | 2016-03-15T11:41:32.701295542Z ** (Mix) The database for App.Repo couldn't be created, reason given: psql: could not connect to server: Connection refused
app-phoenix-1 | 2016-03-15T11:41:32.701369511Z  Is the server running on host "POSTGRES" (10.7.0.7) and accepting
app-phoenix-1 | 2016-03-15T11:41:32.701395350Z  TCP/IP connections on port 5432?

Я подключил сервис и не понимаю, почему он не работает. Postgresql запущен и работает.

В лог-файлах контейнера Postgres ничего нет.

Это результат docker ps на моем узле:

8204a82ca192        myrepo/app       "elixir --erl '-smp d"   37 seconds ago      Up Less than a second   0.0.0.0:80->4000/tcp   app-phoenix-1.585afb94
7a4dded80c36        postgres:latest  "/docker-entrypoint.s"   2 hours ago         Up 10 minutes           5432/tcp               postgres-1.aed0697d

Каким-то образом контейнер Postgres блокирует все соединения из моего контейнера phoenix. Любая подсказка, как это исправить?


person Ole Spaarmann    schedule 15.03.2016    source источник
comment
Как вы запускаете контейнеры. Если вы запускаете с --link, это должно работать. Также вы должны задержать контейнер приложения на несколько секунд, так как postgres может потребоваться время для загрузки.   -  person Xiongbing Jin    schedule 15.03.2016
comment
Postgres работает давно. Я развертываю/запускаю через веб-интерфейс облака докеров, но я связываю службу postgres в контейнере phoenix.   -  person Ole Spaarmann    schedule 15.03.2016
comment
Ограничение трафика из-за пределов хост-компьютера — это работа брандмауэра. В моем случае я использую собственное решение Ubuntu: ufw.   -  person Mark O'Connor    schedule 15.03.2016


Ответы (1)


Я нашел решение: проблема заключалась в настройках iptables. У меня было правило отбрасывать всю переадресацию, если не указано иное:

-A FORWARD -j REJECT

Это правило было в неправильном месте в цепочке фильтров. Правильный способ — поместить его в самый конец цепочки фильтров, после правил, созданных докером. Итак, если у вас такая же проблема, это работает для меня:

Избавьтесь от правила

$ sudo iptables -D FORWARD -j REJECT

Добавьте его снова, чтобы переместить его в конец набора

$ sudo iptables -A FORWARD -j REJECT

Убедитесь, что они в правильном порядке. Таким образом, правило отказа от всего остального должно быть в самом конце.

$ sudo iptables -v -L FORWARD

В Debian вы можете убедиться, что правила по-прежнему применяются при перезапуске сервера:

Когда вы будете довольны, сохраните новые правила в основной файл iptables:

$ iptables-save > /etc/iptables.up.rules

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

$ editor /etc/network/if-pre-up.d/iptables

Добавьте в него эти строки:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.up.rules

Файл должен быть исполняемым, поэтому измените разрешения:

$ sudo chmod +x /etc/network/if-pre-up.d/iptables

Изменить. Простое удаление правила — плохая идея.

person Ole Spaarmann    schedule 15.03.2016