Доступ до бази даних хоста з контейнера докера


131

Якщо у мене є база даних mysql, яка працює на якійсь хост-машині, і цей хост також працює контейнером докера: Як я отримаю доступ до бази даних mysql з контейнера докера, який працює на хості ?.

Наприклад, чи є спосіб опублікувати порт-хост до контейнера (обернено те, що робить докер run -p)?


1
Якщо сервер MySQL прослуховує порт, чи не міг контейнер просто підключитися до хоста на цьому порту, як будь-яке інше з'єднання з Інтернетом?
jwodder

Відповіді:


87

Існує кілька давніх дискусій про те, як це зробити послідовно, добре зрозумілим та портативним способом. Немає повної резолюції, але я зв’яжу вас із обговореннями нижче.

У будь-якому випадку вам багато хто хоче спробувати скористатися параметром --add-host для докерного запуску, щоб додати ip адресу хоста у файл / etc / host контейнера. Звідти тривіально підключатися до хоста на будь-якому необхідному порту:

Додавання записів у файл хостів контейнера

Ви можете додати інших хостів у файл / etc / hosts файлу контейнера, використовуючи один або більше --add-хостів-прапорців. Цей приклад додає статичну адресу для хоста з ім'ям docker:

 $ docker run --add-host=docker:10.180.0.1 --rm -it debian
    $$ ping docker
    PING docker (10.180.0.1): 48 data bytes
    56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms
    56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms
    ^C--- docker ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms

Примітка: Іноді потрібно підключитися до хоста Docker, що означає отримати IP-адресу хоста. Для спрощення цього процесу можна використовувати наступні команди оболонки:

 $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'"
 $ docker run  --add-host=docker:$(hostip) --rm -it debian

Документація:

https://docs.docker.com/engine/reference/commandline/run/

Обговорення доступу до хоста з контейнера:

https://github.com/docker/docker/isissue/1143

https://github.com/docker/docker/isissue/10023


Чи він також буде працювати за зворотним проксі NGINX ??
kta

89

З 18.03 документа:

Я хочу підключитися з контейнера до послуги на хості

У хоста є IP-адреса, що змінюється (або її немає, якщо у вас немає доступу до мережі). Починаючи з 18.03, наша рекомендація полягає у підключенні до спеціального імені DNS host.docker.internal, яке відповідає внутрішній IP-адресі, що використовується хостом.

Шлюз також доступний як gateway.docker.internal.

ПРИКЛАД: Ось що я використовую для моєї рядка з'єднання MySQL всередині мого контейнера для доступу до екземпляра MySQL на моєму хості:

mysql://host.docker.internal:3306/my_awesome_database

31
Як натяк: поки що це працює лише для Mac і Win
flp

ти врятував мій день :)
amjad

4
Оновлення Не лише через відповідь, а тому, що вам слід ЯК використовувати його на прикладі.
granadaCoder

Я майже витратив 2 години на досягнення цього, велике спасибі.
Ashish Bainade

Досі немає підтримки Linux, як писав @flp, для тих, хто цікавиться. Ось випуск github .
GAltelino

34

Починаючи з Docker 17.06, спеціальне DNS-ім'я лише для Mac доступне в контейнерах докера, що відповідає IP-адресі хоста. Це є:

docker.for.mac.localhost

Документація тут: https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support


3
docker.for.mac.host.internalвід Docker 17.12.0 ceроку. docs.docker.com/docker-for-mac/release-notes/…
Zangetsu

docker.for.mac.localhost працює над18.03.1-ce-mac65
cdignam

24

Використовуйте host.docker.internal з Docker 18.03 і далі.


2
як? чи можете ви навести приклад, як ним користуватися?
danfromisrael

Чому б не запустити докерізований mysql?
Ігор Де Олівейра Sá

не працює для менеDocker version 18.03.0-ce, build 0520e24
scythargon

@ IgorDeOliveiraSá уявіть собі наступний сценарій, у середовищі розробників у вас є база даних, яка слухає 127.0.0.1:3306 на виробництві env, у вас є база даних прослуховування 127.0.0.1:3306, локально це локальний db, виробництво це проксі до хмари, ви повинні або dockerise mysql локально, і для виробництва знайдіть інше рішення, або ви можете просто підключитись із докера до порту, він буде працювати в обох випадках
Drachenfels

1
docker.for.mac.localhost працює для мене на18.03.1-ce-mac65
cdignam

21

Інші відповіді мені не спрацювали добре. Мій контейнер не зміг вирішити ip хоста за допомогою host.docker.internal . Є два способи

  1. Спільна мережа хоста --net = хост:

    docker run -it --net=host  myimage
    
  2. Використання ip-адреси docker , яка зазвичай становить 172.17.0.1 . Ви можете перевірити це, зателефонувавши команді ifconfig та захопивши inet addr інтерфейсу докера

    user@ubuntu:~$ ifconfig
    docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

Коли у вас є ця ip-адреса, ви можете передавати її як аргумент докерному запуску, а потім додатку або як я це роблю, картографуйте розташування jdbc.properties через об'єм в каталог на хост-машині, щоб ви могли керувати файлом зовні .

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

ПРИМІТКА. Ваша база даних може не дозволяти зовнішніх з'єднань. У разі postgresql вам потрібно відредагувати 2 файли, як описано тут і тут :

  1. Відредагуйте postgresql.conf, щоб прослухати всі адреси. За замовчуванням він вказуватиме на localhost.

    listen_addresses = '*'
    
  2. Відредагуйте pg_hba.conf, щоб дозволити з'єднання з усіх адрес. Додати в останньому рядку:

    host     all             all             0.0.0.0/0               md5
    

ВАЖЛИВО: Останнє оновлення доступу до бази даних не рекомендується використовувати для виробництва, якщо ви не впевнені, що робите.


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