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





hub docker-compose (5)


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

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

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

Я экспериментирую с 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

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




В принципе, у вас есть три варианта:

  1. Не указывать EXPOSE и -p
  2. EXPOSE только EXPOSE
  3. Укажите EXPOSE и -p

1) Если вы не укажете ни EXPOSE ни -p , сервис в контейнере будет доступен только из самого контейнера.

2) Если вы EXPOSE порта, служба в контейнере недоступна из-за пределов Docker, но из других контейнеров Docker. Так что это хорошо для межконтейнерной связи.

3) Если вы EXPOSE и -p порт, услуга в контейнере доступна из любого места, даже вне Docker.

Причина, по которой обе они разделены, - ИМХО, потому что:

  • выбор хост-порта зависит от хоста и, следовательно, не принадлежит файлу Docker (иначе он будет зависеть от хоста),
  • и часто этого достаточно, если услуга в контейнере доступна из других контейнеров.

В documentation явно указано:

Команда EXPOSE предоставляет порты для использования внутри ссылок.

Он также указывает на то, как связывать контейнеры , в основном это межконтейнерная связь, о которой я говорил.

PS: Если вы делаете -p , но не EXPOSE , Docker выполняет неявное EXPOSE . Это связано с тем, что если порт открыт для публики, он автоматически также открыт для других контейнеров Docker. Следовательно, -p включает EXPOSE . Вот почему я не перечислил его выше как четвертый случай.




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

Источник: github commit




EXPOSE позволяет вам определять частные (контейнерные) и общедоступные (хост-порты) порты для отображения при времени сборки изображения для того, когда контейнер запущен. Общий порт не является обязательным, если не указывается публичный порт, случайный порт будет выбран на хосте докере, чтобы открыть указанный контейнерный порт в файле Docker.

Хорошая оценка - это не указать публичный порт, поскольку он ограничивает только один контейнер на хост (второй контейнер будет использовать порт, который уже используется).

Вы можете использовать -p в docker run чтобы контролировать, какой публичный порт могут быть подключены открытые порты контейнера.

В любом случае, если вы не используете EXPOSE или -p , порты не будут отображаться.

Если вы всегда используете -p при docker run вам не нужно EXPOSE но если вы используете EXPOSE ваша команда docker run может быть более простой, EXPOSE может быть полезна, если вам все равно, какой порт будет отображаться на хосте, или если вы обязательно загрузится только один контейнер.




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

CMD указывает аргументы, которые будут переданы в ENTRYPOINT .

Если вы хотите сделать изображение, посвященное определенной команде, вы будете использовать ENTRYPOINT ["/path/dedicated_command"]

В противном случае, если вы хотите сделать изображение для общего назначения, вы можете оставить ENTRYPOINT неуказанным и использовать CMD ["/path/dedicated_command"] поскольку вы сможете переопределить этот параметр, предоставив аргументы для docker run .

Например, если ваш файл Dockerfile:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

Запуск изображения без каких-либо аргументов будет пинговать localhost:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

Теперь, запуская образ с аргументом, будет пинговать аргумент:

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

Для сравнения, если ваш файл Dockerfile:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

Запуск изображения без каких-либо аргументов будет пинговать localhost:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

Но при запуске образа с аргументом будет выполняться аргумент:

docker run -it test bash
[email protected]:/#

См. Эту статью от Брайана ДеХамера для получения более подробной информации: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/





docker