Яка різниця між портами docker-compose vs expose


Відповіді:


527

Відповідно до довідкової композиції ,

Порти визначаються як:

Викрийте порти . Або вкажіть обидва порти (HOST: CONTAINER), або просто порт контейнера (буде обраний випадковий порт хосту).

  • Порти, згадані в docker-compose.yml, поділяться між різними службами, запущеними docker-compose.
  • Порти будуть піддані хост-машині випадковому порту або даному порту.

Моє docker-compose.ymlвиглядає так:

mysql:
  image: mysql:5.7
  ports:
    - "3306"

Якщо я це зробити docker-compose ps, це буде виглядати так:

  Name                     Command               State            Ports
-------------------------------------------------------------------------------------
  mysql_1       docker-entrypoint.sh mysqld      Up      0.0.0.0:32769->3306/tcp

Експозиція визначається як:

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

Порти не піддаються хост-машинам, а лише іншим службам.

mysql:
  image: mysql:5.7
  expose:
    - "3306"

Якщо я це зробити docker-compose ps, це буде виглядати так:

  Name                  Command             State    Ports
---------------------------------------------------------------
 mysql_1      docker-entrypoint.sh mysqld   Up      3306/tcp

24
Чи можна було б пояснити, які переваги можна вказати exposeу значенні docker-compose? Наскільки я можу сказати, вам не потрібно вказувати експозицію, щоб зробити порти доступними для пов'язаних служб.
Соковитий

3
Чи не слід говорити про те, що відкриті порти будуть доступні лише для служб у тій же докерській мережі (зв’язок замінюється на більшість частин) ?.
мяу

8
@Juicy Я думаю, це схоже на exposeDockerfiles: "Інструкція EXPOSE фактично не публікує порт. Він функціонує як тип документації ..." docs.docker.com/engine/reference/builder/#expose
tsauerwein

1
Чи змінюють порти якісь параметри на рівні брандмауера? Щойно я помітив, що не відкривав порти для mysql на брандмауері, але вони були доступні віддалено. У мене було встановлено "Порти" на "3306: 3306", а не виставляти.
TekiusFanatikus

3
І пам'ятайте, якщо ви використовуєте docker-compose run, визначення порту в docker-compose.ymlце ігнорується за замовчуванням. Будь ласка, використовуйте docker-compose upабо надайте параметр--service-ports
Juha Untinen

177

порти :

  1. Активує контейнер для прослуховування вказаних портів із світу поза докером (це може бути та сама хост-машина чи інша машина) І також доступний світ всередині докера.
  2. Можна вказати більше одного порту (саме тому порти не портують)

введіть тут опис зображення

викрити :

  1. Активує контейнер для прослуховування конкретного порту тільки зі світу всередині докера І недоступного світу поза докера.
  2. Можна вказати більше одного порту

введіть тут опис зображення


3
Зауважте, що експонація дозволяє кілька портів - docs.docker.com/compose/compose-file/#expose - однак ви надаєте лише внутрішній порт, а не внутрішній + зовнішній
Стюарт Мур

Але що робити, якщо я хочу отримати доступ до зовнішнього світу зі свого контейнера? stackoverflow.com/questions/61322256 / ...
gstackoverflow

25

Порти Цей розділ використовується для визначення відображення між хост-сервером та контейнером Docker.

ports:
   - 10005:80

Це означає, що програма, запущена всередині контейнера, відкрита на порту 80. Але зовнішня система / сутність не може отримати доступ до неї, тому її потрібно відобразити на порт хост-сервера.

Примітка: вам потрібно відкрити хост-порт 10005 та змінити правила брандмауера, щоб дозволити зовнішнім особам отримати доступ до програми.

Вони можуть використовувати

http: // {хост IP}: 10005

щось на зразок цього

ЕКСПОЗИЦІЯ Використовується виключно для визначення порту, на якому працює програма всередині контейнера докера.

Ви також можете визначити його в dockerfile. Як правило, для визначення EXPOSE всередині dockerfile є хорошою та широко застосовуваною практикою, оскільки дуже рідко хтось запускає їх на інший порт, ніж 80 порт за замовчуванням.


19

Порти

У portsрозділі публікуються порти на хості. Docker встановить перехід для конкретного порту з хост-мережі в контейнер. За замовчуванням це реалізується з процесом проксі-сервера користувача ( docker-proxy), який прослуховує на першому порту, і пересилає в контейнер, який потрібно слухати у другому пункті. Якщо контейнер не прослуховує порт порту, ви все одно побачите щось прослуховування на хості, але отримаєте з'єднання відмовлено, якщо ви спробуєте підключитися до цього хост-порту, від невдалого переходу в ваш контейнер.

Зауважте, контейнер повинен слухати на всіх мережевих інтерфейсах, оскільки цей проксі не працює в мережевому просторі імен контейнера і не може досягти 127.0.0.1 всередині контейнера. Метод IPv4 для цього полягає в налаштуванні програми на прослуховування 0.0.0.0.

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

Викрийте

Експозиція - це документація. Він встановлює метадані на зображення, а під час запуску - і на контейнер. Зазвичай ви налаштовуєте це в Dockerfile з EXPOSEінструкцією, і він слугує документацією для користувачів, які керують вашим зображенням, щоб вони знали, на яких портах за замовчуванням ваша програма прослуховуватиме. У налаштуваннях із композиційним файлом ці метадані встановлюються лише на контейнері. Ви можете побачити відкриті порти під час запуску а docker inspectна зображенні чи контейнері.

Є кілька інструментів, які покладаються на відкриті порти. У docker -Pпрапор публікує всі відкриті порти на ефемерних портах хоста. Існують також різні зворотні проксі-сервери, які за замовчуванням використовують відкритий порт під час надсилання трафіку у вашу програму, якщо ви явно не встановите порт контейнера.

Окрім цих зовнішніх інструментів, експозиція взагалі не впливає на мережу між контейнерами. Вам потрібна лише загальна мережа докерів та підключення до порту контейнера, щоб отримати доступ до одного контейнера з іншого. Якщо ця мережа створена користувачем (наприклад, не названа мостова мережа за замовчуванням bridge), ви можете використовувати DNS для підключення до інших контейнерів.


3

Я повністю згоден з відповідями раніше. Мені просто хочеться зазначити, що різниця між експонацією та портами є частиною концепції безпеки в docker. Це йде рука об руку з мережею докера. Наприклад:

Уявіть програму з веб-інтернетом та базою даних бази даних. Зовнішній світ потребує доступу до веб-інтерфейсу (можливо, до порту 80), але лише сам бек-енд потребує доступу до хоста бази даних та порту. Використовуючи визначений користувачем міст, потрібно відкривати лише веб-порт, а додатку бази даних не потрібно відкривати жодні порти, оскільки веб-фронт може дістатись до нього через визначений користувачем міст.

Це звичайний випадок використання під час налаштування мережевої архітектури в docker. Так, наприклад, у мостовій мережі за замовчуванням не доступні порти із зовнішнього світу. Для цього ви можете відкрити точку вступу за допомогою "портів". Використовуючи "експонувати", ви визначаєте зв'язок всередині мережі. Якщо ви хочете відкрити порти за замовчуванням, вам не потрібно визначати "expose" у вашому файлі docker-compose.

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