Перейти к основному содержимому

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

· 4 мин. чтения

1. Обзор

В Docker важно знать, какие порты прослушивает контейнерное приложение. Нам также нужен способ доступа к приложению из-за пределов контейнера.

Чтобы решить эти проблемы, Docker позволяет нам открывать и публиковать порты.

В этой статье мы узнаем как об открытии, так и о публикации портов. В качестве примера мы будем использовать простой контейнер веб-сервера Nginx.

2. Открытие портов

Открытый порт — это часть метаданных о контейнерном приложении. В большинстве случаев это показывает, какие порты прослушивает приложение. Сам Docker ничего не делает с открытым портом . Однако когда мы запускаем контейнер, мы можем использовать эти метаданные при публикации порта.

2.1. Разоблачение с помощью Nginx

Давайте воспользуемся веб-сервером Nginx, чтобы попробовать это.

Если мы посмотрим на официальный Dockerfile Nginx , мы увидим, что порт 80 открыт с помощью следующей команды:

EXPOSE 80

Здесь показан порт 80, потому что это порт по умолчанию для протокола http . Давайте запустим контейнер Nginx на нашей локальной машине и посмотрим, сможем ли мы получить к нему доступ через порт 80:

$ docker run -d nginx

Приведенная выше команда будет использовать последний образ Nginx и запускать контейнер. Мы можем перепроверить, что контейнер Nginx работает, с помощью команды:

$ docker container ls

Эта команда выведет некоторую информацию обо всех запущенных контейнерах, включая Nginx:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
cbc2f10f787f nginx "/docker-entrypoint..." 15 seconds ago Up 15 seconds 80/tcp dazzling_mclean

Здесь мы видим 80 под разделом порта. Поскольку порт 80 открыт, мы можем подумать, что доступ к localhost:80 (или просто localhost ) отобразит страницу Nginx по умолчанию, но это не так:

$ curl http://localhost:8080
... no web page appears

Хотя порт открыт, Docker не открыл его для хоста.

2.2. Способы раскрытия портов

Есть два основных способа открыть порты в Docker. Мы можем сделать это в Dockerfile с помощью команды EXPOSE :

EXPOSE 8765

Кроме того, мы также можем открыть порт с параметром –expose при запуске контейнера :

$ docker run --expose 8765 nginx

3. Публикация портов

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

3.1. Публикация с помощью Nginx

Давайте запустим Nginx с маппированным портом:

$ docker run -d -p 8080:80 nginx

Приведенная выше команда сопоставит порт 8080 хоста с портом 80 контейнера. Общий синтаксис опции:

-p <hostport>:<container port>

Если мы перейдем к localhost:8080 , мы должны получить страницу приветствия Nginx по умолчанию:

$ curl http://localhost:8080
StatusCode : 200
StatusDescription : OK
Content : <!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
... more HTML

Перечислим все запущенные контейнеры:

$ docker container ls

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

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
38cfed3c61ea nginx "/docker-entrypoint..." 31 seconds ago Up 30 seconds 0.0.0.0:8080->80/tcp dazzling_kowalevski

В разделе портов у нас есть сопоставление 0.0.0.0:8080->80/tcp .

Docker по умолчанию добавил немаршрутизируемый метаадрес 0.0.0.0 для хоста . Это означает, что сопоставление действительно для всех адресов/интерфейсов хоста.

3.2. Ограничение доступа к контейнеру

Мы можем ограничить доступ к контейнеру на основе IP-адреса хоста. Вместо того, чтобы разрешать доступ к контейнеру со всех интерфейсов (что делает 0.0.0.0 ), мы можем указать IP-адрес хоста в сопоставлении.

Ограничим доступ к контейнеру трафиком только с loopback-адреса 127.0.0.1 :

$ docker run -d -p 127.0.0.1:8081:80 nginx

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

-p <binding address>:<hostport>:<container port>

4. Опубликуйте все открытые порты

Открытые метаданные порта могут быть полезны для запуска контейнера, поскольку Docker дает нам возможность публиковать все открытые порты:

$ docker run -d --publish-all nginx

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

Давайте посмотрим на контейнеры, которые запускает эта команда:

$ docker container ls

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a23e78732ce nginx "/docker-entrypoint..." 6 minutes ago Up 6 minutes 0.0.0.0:32768->80/tcp pedantic_curran

Как мы и ожидали, Docker выбрал случайный порт (в данном случае 32768) с хоста и сопоставил его с открытым портом .

5. Вывод

В этой статье мы узнали об открытии и публикации портов в Docker.

Мы также обсудили, что открытый порт — это метаданные о контейнерном приложении, тогда как публикация порта — это способ доступа к приложению с хоста.