Как я могу перенаправить порт из одного док-контейнера в другой?

Я часто вижу решения, которые предоставляют хосту порт контейнера докеров.

В моем случае я хочу перенаправить локальный порт из одного контейнера в другой.

Допустим, я запускаю службу в контейнере A, которая имеет жестко закодированную конфигурацию для доступа к базе данных на локальном хосте 3306. Но я хочу запустить сервер базы данных в контейнере B.

Как лучше всего перенаправить порт с A-localhost:3306 на B-IP:3306?


person Marinos An    schedule 07.09.2017    source источник


Ответы (7)


Установите socat в свой контейнер и запустите при запуске

socat TCP-LISTEN:3306,fork TCP:B-IP:3306 &

Это будет прослушивать локально ваш 3306 и передавать любой трафик в обоих направлениях на B-IP:3306. socat доступен в пакете socat. Таким образом, вы запустите любую из приведенных ниже команд, чтобы установить его.

$ yum install -y socat
$ apt install -y socat
$ apk add socat

Редактировать-1

Вы даже можете сделать это, не касаясь оригинального контейнера.

Файл Docker

FROM alpine
RUN apk update && apk add socat

Создайте файл, как показано ниже

docker build -t socat .

Теперь запустите контейнер из того же

docker run --name mysql-bridge-a-to-b --net=container:<containerAid> socat socat TCP-LISTEN:3306,fork TCP:BIP:3306

Это запустит этот контейнер в сети A. Поэтому, когда он прослушивает сеть A, localhost:3306 станет доступным в A, даже если контейнер A не был затронут.

person Tarun Lalwani    schedule 07.09.2017
comment
В Docker Hub есть образ Alpine socat: hub.docker.com/r/alpine/socat. - person Joe Heffer; 25.06.2020
comment
Хотя моя проблема не была связана напрямую с этим, это помогло мне ее решить.! Спасибо и ура :) - person Ajay Tom George; 24.05.2021

Вы можете просто запустить контейнер с сетевым режимом, равным host.

docker run --network=host ...

В этом случае с точки зрения контейнера localhost или 127.0.0.1 будут относиться к хост-компьютеру. Таким образом, если ваша база данных работает в другом контейнере B, который прослушивает 3306, адрес localhost: 3306 в контейнере A попадет в базу данных в контейнере B.

person yamenk    schedule 07.09.2017
comment
Абсолютная легенда f&%$^!g! +1 - person Ash; 11.04.2019
comment
это действительно решило меня. dockerA работает в своей собственной сети (и, возможно, открыт для хоста). докерБ такой же. моя интуиция заключалась в том, что при разоблачении его на docker run -p это прозрачно сделает его хост-сетью - person adonese; 09.04.2020
comment
это поддерживается только в Linux: docs.docker.com/network/host - person TmTron; 08.09.2020

Если вы хотите, чтобы порт контейнера B отображался как порт localhost в контейнере A, вы можете запустить контейнер B с параметром network, установленным в режим container, чтобы запустить контейнер B в сетевом пространстве имен контейнера A.

Пример:

docker run --net=container:A postgres

Где:

  • A — это имя или идентификатор контейнера, в который вы хотите сопоставить.

Это запустит postgres в контейнере в том же сетевом пространстве имен, что и A, поэтому любой порт, открытый в контейнере postgres, будет открыт на том же интерфейсе, что и A, и он должен быть доступен на localhost внутри контейнера A.

person Leigh McCulloch    schedule 14.09.2019
comment
Мне это кажется более подходящим, чем docker run --network=host - person Marinos An; 16.09.2019

Для разработки в Windows мы можем просто использовать host.docker.internal: см. сетевое взаимодействие docker-for-windows

Я ХОЧУ ПОДКЛЮЧИТЬСЯ ИЗ КОНТЕЙНЕРА К СЛУЖБЕ НА ХОТЕ
Мы рекомендуем вам подключаться к специальному DNS-имени host.docker.internal, которое разрешается во внутренний IP-адрес, используемый хостом. Это предназначено для целей разработки и не будет работать в производственной среде за пределами Docker Desktop для Windows.

Итак, в вашем случае:

  • container A публикует порт 3306
    этот порт теперь доступен на хосте
  • container B может просто подключиться к host.docker.internal:3306
person TmTron    schedule 08.09.2020

Это решение является излишним для указанного варианта использования, но в случае, если вы столкнетесь с этим при исследовании более широкой области.

Hashicorp Consul устанавливает агент локального хоста, который проксирует порт локального хоста на IP-адрес и порт службы, зарегистрированной в каталоге. https://www.consul.io/intro

Я не имею никакого отношения к Hashicorp, кроме использования их продуктов в системах, которые я построил.

person Stevko    schedule 10.09.2020

Контейнеры могут получать доступ друг к другу внутри, вам не нужно ничего раскрывать или пересылать.

person ZobairQ    schedule 21.09.2020

Вы можете сделать это с помощью Docker- Написать.

Пример docker-compose.yml:

version: '3'
services:
  web:
    build: .web
    ports:
     - "5000:5000"
  mysql:
    build: .mysql
    ports:
     - "3306:3306"

Здесь у вас есть 2 экземпляра докера: web и mysql, поэтому каждый экземпляр докера может видеть друг друга, используя имена, которые вы определили как сервисы.

Надеюсь это поможет

person Jorge Chavez    schedule 07.09.2017
comment
Я не знаю, почему за это проголосовали без комментариев. Это работает лучше всего для меня, так как мне не нужно возиться с выяснением порта или имени хоста другого контейнера. URI для mysql будет ‹service-name:port› например. MySQL: 3306 - person Stevko; 15.06.2020
comment
@Stevko, потому что доступ к БД жестко запрограммирован на localhost:3306. Невозможно изменить его на ссылку на mysql:3306. - person Julian Pieles; 08.09.2020