доступ до контейнера докера з іншого контейнера


92

я створив два контейнери докерів на основі двох різних зображень. один з db, а інший для веб-сервера. обидва контейнери працюють на моєму mac osx.

я можу отримати доступ до контейнера db з хост-машини, так само як і до веб-сервера з хост-машини.

однак, як мені отримати доступ до з'єднання db з веб-сервера?

те, як я запустив db контейнер

docker run --name oracle-db -p 1521:1521 -p 5501:5500 oracle/database:12.1.0.2-ee

Я запустив wls контейнер як

docker run --name oracle-wls -p 7001:7001 wls-image:latest

Я можу отримати доступ до db на хості, підключившись до

sqlplus scott/welcome1@//localhost:1521/ORCLCDB

Я можу отримати доступ до wls на хості як

http://localhost:7001/console

Отже, і веб-контейнер, і контейнер db знаходяться на хост-машині? Якщо так, то яку версію докера ви використовуєте? Оскільки старіші версії docker мали один спосіб зробити це, тоді як нові версії мають інший спосіб. Ви також можете використовувати docker-compose? Що полегшить, але я не хочу давати відповідь методом, яким ви не можете скористатися.
Капернеоаніс

ця відповідь може допомогти, як отримати доступ до localhost із контейнера в mac os
Chaojun Zhong

Для зовнішніх мереж, це рішення працює для мене stackoverflow.com/a/38089080/1770571
Сальма Гома

Відповіді:


51

Найпростіший спосіб - використовувати --link, однак новіші версії docker відходять від цього, і насправді цей перемикач буде скоро видалено.

Посилання нижче пропонує приємні способи підключення двох контейнерів. Ви можете пропустити частину вкладення, оскільки це лише корисний спосіб додавання елементів до зображень.

https://deis.com/blog/2016/connecting-docker-containers-1/

Частина, яка вас цікавить, - це зв’язок між двома контейнерами. Найпростіший спосіб - це звернутися до контейнера БД за іменем із контейнера веб-сервера.

Приклад:

Ви назвали контейнер db db1та контейнер веб-сервера web0. Обидва контейнери повинні знаходитися в мостовій мережі, що означає, що веб-контейнер повинен мати можливість підключатися до контейнера БД, посилаючись на його ім'я.

Отже, якщо у вас є веб-файл конфігурації для вашої програми, тоді для хосту БД ви будете використовувати це ім’я db1.

якщо ви використовуєте стару версію docker, то слід використовувати --link.

Приклад:

Крок 1: docker run --name db1 oracle/database:12.1.0.2-ee

то при запуску веб-програми. використання:

Крок 2: docker run --name web0 --link db1 webapp/webapp:3.0

і веб-програма буде пов'язана з БД. Однак, як я вже сказав, перемикач --link скоро буде видалено.

Натомість я використав docker compose, який створить для вас мережу. Однак; вам потрібно буде завантажити docker compose для вашої системи. https://docs.docker.com/compose/install/#prerequisites

приклад налаштування такий:

ім'я файлу base.yml

version: "2"
services:
  webserver:
    image: "moodlehq/moodle-php-apache:7.1
    depends_on:
      - db
    volumes:
      - "/var/www/html:/var/www/html"
      - "/home/some_user/web/apache2_faildumps.conf:/etc/apache2/conf-enabled/apache2_faildumps.conf"
    environment:
      MOODLE_DOCKER_DBTYPE: pgsql
      MOODLE_DOCKER_DBNAME: moodle
      MOODLE_DOCKER_DBUSER: moodle
      MOODLE_DOCKER_DBPASS: "m@0dl3ing"
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"
  db:
    image: postgres:9
    environment:
      POSTGRES_USER: moodle
      POSTGRES_PASSWORD: "m@0dl3ing"
      POSTGRES_DB: moodle
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"

це буде називати мережу загальним іменем, я не можу згадати, що це за ім'я, якщо ви не використовуєте перемикач --name.

IE docker-compose --name setup1 up base.yml

ПРИМІТКА: якщо ви використовуєте перемикач --name, вам потрібно буде використовувати його при будь-якому виклику docker compose, тож docker-compose --name setup1 downце так, щоб ви могли мати більше одного екземпляра веб-сервера та db, і в цьому випадку docker compose знає, який екземпляр ви хочете запускати команди проти; а також, щоб ви могли одночасно запускати більше одного. Чудово підходить для CI / CD, якщо ви паралельно запускаєте тест на одному сервері.

Docker compose також має ті самі команди, що і docker so docker-compose --name setup1 exec webserver do_some_command

найкраща частина - якщо ви хочете змінити db або щось подібне для модульного тесту, ви можете включити додатковий файл .yml до команди up, і він буде перезаписувати будь-які елементи з подібними іменами, я вважаю це заміною ключа => значення .

Приклад:

db.yml

version: "2"
services:
  webserver:
    environment:
      MOODLE_DOCKER_DBTYPE: oci
      MOODLE_DOCKER_DBNAME: XE
  db:
    image: moodlehq/moodle-db-oracle

Тоді телефонуйте docker-compose --name setup1 up base.yml db.yml

Це перезапише db. з іншим налаштуванням. Коли потрібно підключатись до цих служб з кожного контейнера, ви використовуєте ім’я, встановлене під службою, в даному випадку веб-сервер та db.

Я думаю, що це може бути більш корисним налаштуванням у вашому випадку. Оскільки ви можете встановити всі необхідні змінні у файлах yml і просто запустити команду для docker compose, коли вони вам потрібні. Тож більше запускайте це і забудьте про налаштування.

ПРИМІТКА: Я не використовував --portкоманда, оскільки оголення портів не потрібне для зв'язку контейнер-> контейнер. Це потрібно лише в тому випадку, якщо ви хочете, щоб хост підключився до контейнера або програми поза хостом. Якщо ви виставите порт, порт буде відкритий для всіх зв’язків, дозволених хостом. Отже, оголення веб-сторінок через порт 80 - це те саме, що запуск веб-сервера на фізичному хості і дозволить зовнішні підключення, якщо хост це дозволяє. Крім того, якщо ви хочете запустити більше однієї веб-програми з будь-якої причини, тоді викриття порту 80 завадить вам запустити додаткові веб-додатки, якщо ви спробуєте експонувати на цьому порту. Отже, для CI / CD найкраще взагалі не виставляти порти, і якщо ви використовуєте docker compose з перемикачем --name, всі контейнери будуть у своїй мережі, тому вони не зіткнуться. Таким чином, ви майже отримаєте контейнер з контейнерами.

ОНОВЛЕННЯ: Після подальшого використання функцій та перегляду того, як це робили інші для програм CICD, таких як Дженкінс. Мережа також є життєздатним рішенням.

Приклад:

docker network create test_network

Вищенаведена команда створить "test_network", до якої ви також можете підключити інші контейнери. Що легко зробити за допомогою --networkоператора комутатора.

Приклад:

docker run \
    --detach \
    --name db1 \
    --network test_network \
    -e MYSQL_ROOT_PASSWORD="${DBPASS}" \
    -e MYSQL_DATABASE="${DBNAME}" \
    -e MYSQL_USER="${DBUSER}" \
    -e MYSQL_PASSWORD="${DBPASS}" \
    --tmpfs /var/lib/mysql:rw \
    mysql:5

Звичайно, якщо у вас є налаштування проксі-мережі, ви все одно повинні передавати їх у контейнери, використовуючи оператори перемикання "-e" або "--env-file". Таким чином контейнер може спілкуватися з Інтернетом. Docker каже, що налаштування проксі повинні бути поглинені контейнером у нових версіях docker; однак, я все ще передаю їх як звичку. Це заміна комутатора "--link", який відключається. Після того, як контейнери приєднані до створеної вами мережі, ви все ще можете посилатися на ці контейнери з інших контейнерів, використовуючи "ім'я" контейнера. За наведеним вище прикладом це було б db1. Вам просто потрібно переконатися, що всі контейнери підключені до однієї мережі, і ви готові до роботи.

Детальний приклад використання мережі в конвеєрі cicd можна знайти за цим посиланням: https://git.in.moodle.com/integration/nightlyscripts/blob/master/runner/master/run.sh

Це сценарій, який запускається в Jenkins для величезних тестів інтеграції Moodle, але ідею / приклад можна використовувати де завгодно. Сподіваюся, це допомагає іншим.


1
Якщо перше посилання не працює, ви можете використовувати це. linode.com/docs/applications/containers/…
Caperneoignis

1
Для веб-сервера Doing Docker, який створює або робить мережу, як веб-сервер посилається на БД? Чи буде воно використовувати назву контейнера? Це виглядає як у другому посиланні, що має місце: Отже, якщо ви визначаєте БД і додаток, програма повинна мати посилання в цьому випадку: psql -U {USER} -h database -p 5432 {DATABASE}зсередини контейнера, якби я потрапив у нього,
Fallenreaper

1
@Fallenreaper, якщо ви перебуваєте в контейнері і створили докер, ви б використовували ім'я, яке використовується під "services:", якщо ви явно не вказали йому ім'я. Отже, у прикладі ви б використовували "веб-сервер", якщо намагалися підключитися з контейнера "db" в оболонці. Подивіться на приклад для db.yml, в якому ви б використовували імена веб-сервер та db. Вибачте за затримку, пройшов сторонній шлях і забув повідомлення.
Капернеоаніс

51

Це легко. Якщо у вас є два або більше запущених контейнерів, виконайте наступні кроки:

docker network create myNetwork
docker network connect myNetwork web1
docker network connect myNetwork web2

Тепер ви підключаєтеся від web1 до контейнера web2 або навпаки.

Використовуйте IP-адреси внутрішньої мережі, які ви можете знайти, запустивши:

docker network inspect myNetwork

Зверніть увагу, що для контейнерів, з'єднаних мережевим мостом, доступні лише внутрішні IP-адреси та порти.

Так, наприклад, якщо припустити, що контейнер web1 був запущений з: docker run -p 80:8888 web1(це означає, що його сервер працює внутрішньо на порту 8888), а перевірка myNetworkпоказує, що IP-адреса web1 становить 172.0.0.2, ви можете підключитися з web2 до web1 за допомогою curl 172.0.0.2:8888).


1
Привіт, і як мені підключитися з web1 на web2? за ip, ім'я хоста? де взяти цю інформацію?
Генрі Авіла

У файлі docker-compose.yml створюйте мережі: myNetwork.
MxWild

14
@ HenryÁvila Ви просто використовуєте ім'я контейнера (наприклад web1) як ім'я хосту.
Паскаль

19

Вам доведеться отримати доступ до db через ip хост-машини, або якщо ви хочете отримати до нього доступ через localhost: 1521, то запустіть веб-сервер, як -

docker run --net=host --name oracle-wls wls-image:latest

Дивіться тут


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

1
Це дійсно, лише якщо машина має статичний ip або DNS, інакше використовуйте другий підхід.
xitter

у мене, здається, проблема з цим. моя точна команда запуску: docker run --name ora-tools-wls -it -p 7001: 7001 orawls, це працює, і дозвольте мені отримати доступ до мого сервера, що працює на цьому контейнері, як localhost: 7001 / console Однак доступ до баз даних із сервера потрібно точний ip, щоб дістатись до іншого контейнера, на якому запущена БД. Якщо я використовую запуск докера --name ora-tools-wls -it -p 7001: 7001 --network = "host" orawls, тоді сервер може отримати доступ до db з localhost як ip, як ви вже згадали, але отримати доступ до сервера в браузері хост-машини не вдається.
Вік

3
Вам не потрібно визначати -p 7001:7001, оскільки весь контейнер використовує сам мережевий стек хоста.
xitter

@Vik, у мене були ті самі проблеми, і я виявив, що це не підтримується в mac. можливо, це те, що ти теж робиш. > Мережевий драйвер хосту працює лише на хостах Linux і не підтримується Docker Desktop для Mac, Docker Desktop для Windows або Docker EE для Windows Server. docs.docker.com/network/host
Брент Фішер

9

Використовуючи docker-compose, служби за замовчуванням піддаються одне одному за іменами. Документи .
Ви також можете вказати псевдонім типу;

version: '2.1'
services:
  mongo:
    image: mongo:3.2.11
  redis:
    image: redis:3.2.10
  api:
    image: some-image
    depends_on:
      - mongo
      - solr
    links:
      - "mongo:mongo.openconceptlab.org"
      - "solr:solr.openconceptlab.org"
      - "some-service:some-alias"

А потім отримати доступ до сервісу з допомогою зазначеного псевдоніма в якості імені хоста, наприклад , mongo.openconceptlab.orgдля mongoцього випадку.

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