Предоставление порта в реальном контейнере Docker



6 Answers

Вот что я сделал бы:

  • Зафиксируйте живой контейнер.
  • Запустите контейнер снова с новым изображением, с открытыми портами (я бы рекомендовал монтировать общий том и открыть порт ssh)
sudo docker ps 
sudo docker commit <containerid> <foo/live>
sudo docker run -i -p 22 -p 8000:80 -m /data:/data -t <foo/live> /bin/bash
docker

Я пытаюсь создать контейнер Docker, который действует как полнофункциональная виртуальная машина. Я знаю, что я могу использовать инструкцию EXPOSE внутри файла Docker, чтобы открыть порт, и я могу использовать флаг -p с docker run для назначения портов, но как только контейнер фактически запущен, есть команда открывать / отображать дополнительные порты в реальном времени ?

Например, допустим, у меня есть контейнер Docker, который запускает sshd. Кто-то еще использует контейнер ssh и устанавливает httpd. Есть ли способ открыть порт 80 на контейнере и отобразить его на порт 8080 на хосте, чтобы пользователи могли посещать веб-сервер, работающий в контейнере, без перезапуска?




Пакеты IPtables не работают, по крайней мере, на Docker 1.4.1.

Лучшим способом было бы запустить другой контейнер с открытым портом и реле с помощью socat. Это то, что я сделал (временно) для подключения к базе данных с помощью SQLPlus:

docker run -d --name sqlplus --link db:db -p 1521:1521 sqlplus

Dockerfile:

FROM debian:7

RUN apt-get update && \
    apt-get -y install socat && \
    apt-get clean

USER nobody

CMD socat -dddd TCP-LISTEN:1521,reuseaddr,fork TCP:db:1521



Я должен был решить эту проблему и смог ее решить, не останавливая ни один из моих запущенных контейнеров. Это решение обновлено по состоянию на февраль 2016 года, используя Docker 1.9.1. В любом случае, этот ответ представляет собой подробную версию ответа @ ricardo-branco, но более подробно для новых пользователей.

В моем сценарии я хотел временно подключиться к MySQL, работающему в контейнере, и поскольку к нему привязаны другие контейнеры приложений, остановка, реконфигурация и повторный запуск контейнера базы данных была не стартером.

Поскольку я хотел бы получить доступ к базе данных MySQL извне (из Sequel Pro через SSH-туннелирование), я собираюсь использовать порт 33306 на главной машине. (Не 3306 , на случай, если работает внешний экземпляр MySQL).

Примерно за час чистки iptables оказалось бесплодным, хотя:

Шаг за шагом, вот что я сделал:

mkdir db-expose-33306
cd db-expose-33306
vim Dockerfile

Измените dockerfile , разместив его внутри:

# Exposes port 3306 on linked "db" container, to be accessible at host:33306
FROM ubuntu:latest # (Recommended to use the same base as the DB container)

RUN apt-get update && \
    apt-get -y install socat && \
    apt-get clean

USER nobody
EXPOSE 33306

CMD socat -dddd TCP-LISTEN:33306,reuseaddr,fork TCP:db:3306

Затем создайте изображение:

docker build -t your-namespace/db-expose-33306 .

Затем запустите его, привязав к вашему запущенному контейнеру. (Используйте -d вместо -rm чтобы сохранить его в фоновом режиме, пока явным образом не остановится и не удаляется. В этом случае я хочу, чтобы он выполнялся временно).

docker run -it --rm --name=db-33306 --link the_live_db_container:db -p 33306:33306  your-namespace/db-expose-33306



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

Вы можете сделать это в обоих направлениях: от контейнера до хоста и от хоста к контейнеру. Но вам нужен SSH-инструмент, такой как OpenSSH, как (клиент на одном, так и сервер в другом).

Например, в контейнере вы можете сделать

$ yum install -y openssh openssh-server.x86_64
service sshd restart
Stopping sshd:                                             [FAILED]
Generating SSH2 RSA host key:                              [  OK  ]
Generating SSH1 RSA host key:                              [  OK  ]
Generating SSH2 DSA host key:                              [  OK  ]
Starting sshd:                                             [  OK  ]
$ passwd # You need to set a root password..

IP-адрес контейнера можно найти в этой строке (в контейнере):

$ ifconfig eth0 | grep "inet addr" | sed 's/^[^:]*:\([^ ]*\).*/\1/g'
172.17.0.2

Затем в хосте вы можете просто сделать:

sudo ssh -NfL 80:0.0.0.0:80 root@172.17.0.2



Существует удобная оболочка HAProxy.

docker run -it -p LOCALPORT:PROXYPORT --rm --link TARGET_CONTAINER:EZNAME -e "BACKEND_HOST=EZNAME" -e "BACKEND_PORT=PROXYPORT" demandbase/docker-tcp-proxy

Это создает HAProxy для целевого контейнера. очень просто.




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

Интерфейсы Macvlan

Теперь Docker включает сетевой драйвер Macvlan . Это придает сети Docker интерфейс «реального мира» и позволяет назначать адреса сетей непосредственно в контейнере (например, в режиме мостов с виртуальными машинами).

docker network create \
    -d macvlan \
    --subnet=172.16.86.0/24 \
    --gateway=172.16.86.1  \
    -o parent=eth0 pub_net

pipework также может отображать реальный интерфейс в контейнер или настраивать дополнительный интерфейс в более старых версиях Docker.

Маршрутизация IP-адресов

Если у вас есть контроль над сетью, вы можете перенаправить дополнительные сети на хост Docker для использования в контейнерах.

Затем вы назначаете эту сеть контейнерам и настраиваете хост Docker для маршрутизации пакетов через сеть докеров.

Общий интерфейс хоста

Параметр --net host позволяет --net host -интерфейсом в контейнере, но это, вероятно, не очень хорошая настройка для запуска нескольких контейнеров на одном хосте из-за общей природы.




Related


Tags

docker