В чем разница между «разоблачением» и «публикацией» в Docker?



Answers

Короткий ответ:

  • EXPOSE - это способ документирования
  • --publish - способ сопоставления порта хоста порта контейнера

Обратите внимание, что соединения между:

  • EXPOSE и Dockerfile
  • --publish и время выполнения ( docker run ... )

Экспозиция и публикация портов

В сети Docker существуют два разных механизма, которые непосредственно связаны с сетевыми портами: выставлять и публиковать порты. Это относится к сети моста по умолчанию и определяемым пользователем мостовым сетям.

  • Вы открываете порты, используя ключевое слово EXPOSE в файле Docker, или флаг --expose для запуска --expose . Экспозиция портов - это способ документировать, какие порты используются, но фактически не отображает и не открывает какие-либо порты. Экспозиция портов является необязательной .

  • Вы публикуете порты, используя --publish или --publish-all для docker run --publish-all . Это сообщает Docker, какие порты открываются на сетевом интерфейсе контейнера. Когда порт опубликован, он отображается на доступный порт высокого порядка (более 30000 ) на хост-машине, если вы не укажете порт для сопоставления на главной машине во время выполнения. Вы не можете указать порт для сопоставления на хост-машине при создании образа (в файле Docker), потому что нет способа гарантировать, что порт будет доступен на главной машине, где вы запускаете изображение .

из: Контейнерные сети Docker

Также,

ПОДВЕРГАТЬ

... инструкция EXPOSE фактически не публикует порт. Он функционирует как тип документации между человеком, который создает изображение, и человеком, который запускает контейнер, о том, какие порты должны быть опубликованы .

от: documentation

Сервисный доступ, когда EXPOSE / --publish не определен:

В говорится, что ::

«Если вы не укажете ни одно из них, служба в контейнере не будет доступна нигде, кроме как внутри самого контейнера» .

Возможно, так было в тот момент, когда был написан ответ, но теперь кажется, что даже если вы не используете EXPOSE или --publish , host и другие containers одной и той же сети смогут получить доступ к службе, которую вы можете запустить внутри этот контейнер .

Для моих тестов я использовал следующий Dockerfile . В принципе, я начинаю с ubuntu и устанавливаю крошечный веб-сервер:

FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd

Я build изображение как «testexpose» и run новый контейнер с:

docker run --rm -it testexpose bash

Внутри контейнера я запускаю несколько экземпляров mini-httpd :

root@fb8f7dd1322d:/# mini_httpd -p 80
root@fb8f7dd1322d:/# mini_httpd -p 8080
root@fb8f7dd1322d:/# mini_httpd -p 8090

Затем я могу использовать curl из хоста или других контейнеров для получения домашней страницы mini-httpd .

Question

Я экспериментирую с Dockerfiles, и я думаю, что я понимаю большую часть логики. Тем не менее, я не вижу разницы между «разоблачением» и «публикацией» порта в этом контексте.

Все учебные пособия, которые я видел сначала, включают команду EXPOSE в файле Docker:

...
EXPOSE 8080
...

Затем они создают изображение из этого файла Docker:

$ docker build -t an_image - < Dockerfile

Затем опубликуйте тот же порт, что и при запуске образа:

$ docker run -d -p 8080 an_image

или публиковать все порты, используя

$ docker run -d -P an_image

Какой смысл выставлять порт в файле Docker, если он будет опубликован в любом случае? Может ли когда-нибудь возникнуть необходимость открыть порт первым, а не опубликовать его позже? Фактически, я хотел бы указать все порты, которые я буду использовать в Dockerfile при создании изображения, а затем не беспокоюсь о них снова, запуская их просто с помощью:

$ docker run -d an_image

Это возможно?




Большинство людей используют докер в сетях. В documentation указано:

Сетевая функция Docker поддерживает создание сетей без необходимости раскрывать порты в сети, подробную информацию см. В обзоре этой функции).

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




Related



Tags

docker docker