Как узнать открытые порты контейнера Docker

DockerBeginner
Практиковаться сейчас

Введение

Docker – это широко используемая технология контейнеризации, которая произвела революцию в способах разработки, упаковки и развертывания приложений. Понимание экспортированных портов (exposed ports) контейнера Docker является фундаментальным аспектом работы с Docker, поскольку это позволяет вам получать доступ к службам, работающим внутри контейнера, и взаимодействовать с ними. Этот учебник проведет вас через процесс инспектирования экспортированных портов контейнера Docker, что позволит вам лучше управлять и оптимизировать ваши контейнеризированные приложения.

Понимание портов контейнеров Docker

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

Что такое порты контейнеров

В Docker порты позволяют службам, работающим внутри контейнера, взаимодействовать с внешним миром. Думайте о портах как о дверях к вашему контейнеризированному приложению – не открыв эти двери, никто не сможет получить доступ к службам внутри.

Типы конфигураций портов

Docker поддерживает два основных типа конфигураций портов:

  1. Exposed Ports (Экспортированные порты): Порты, которые контейнер делает доступными для потенциальных подключений, но которые не являются автоматически доступными с хоста.

  2. Published Ports (Опубликованные порты): Экспортированные порты, которые отображаются на порт на хосте, обеспечивая внешний доступ к службам контейнера.

Давайте запустим простой контейнер веб-сервера, чтобы лучше это понять:

docker run -d --name web-demo nginx

Выполните эту команду в терминале. Это запустит контейнер веб-сервера Nginx с именем web-demo в detached mode (режиме отсоединения, работающем в фоновом режиме).

Вывод покажет ID контейнера, похожий на:

3a6e8df899a9b723de9e4684542dc9987af26381118fa36496757d17ac952c9f

Этот контейнер Nginx имеет порт 80, экспортированный по умолчанию (как определено в его Dockerfile), но мы еще не опубликовали его на хосте, поэтому мы не можем получить к нему доступ извне.

Изучение конфигурации портов контейнера

Теперь, когда наш контейнер запущен, давайте изучим его конфигурацию портов.

Использование docker ps для просмотра отображений портов

Команда docker ps показывает запущенные контейнеры и их конфигурации портов.

Выполните эту команду в вашем терминале:

docker ps

Вы увидите вывод, похожий на:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
3a6e8df899a9   nginx     "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes    80/tcp    web-demo

Обратите внимание на столбец PORTS. Он показывает 80/tcp, указывая на то, что порт 80 экспортирован, но не опубликован на хосте.

Запуск контейнера с опубликованными портами

Давайте остановим наш первый контейнер и создадим новый с опубликованным портом:

docker stop web-demo
docker rm web-demo

Теперь запустите новый контейнер с отображением портов:

docker run -d --name web-demo -p 8080:80 nginx

Опция -p 8080:80 публикует порт 80 контейнера на порт 8080 на хосте.

Запустите docker ps снова, чтобы увидеть разницу:

docker ps

Вывод:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
f7d483e51ef2   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 10 seconds   0.0.0.0:8080->80/tcp   web-demo

Обратите внимание, как столбец PORTS теперь показывает 0.0.0.0:8080->80/tcp, указывая на то, что порт 80 в контейнере отображен на порт 8080 на всех интерфейсах хоста.

Инспектирование деталей портов контейнера

Docker предоставляет несколько команд для детального инспектирования конфигураций портов контейнера. Давайте рассмотрим эти опции.

Использование команды docker port

Команда docker port показывает отображения портов для контейнера:

docker port web-demo

Вывод:

80/tcp -> 0.0.0.0:8080

Это показывает, что порт 80/tcp в контейнере отображен на порт 8080 на всех интерфейсах хоста.

Использование docker inspect для получения подробной информации

Для получения более подробной информации используйте команду docker inspect:

docker inspect web-demo

Эта команда выдает большой объем JSON-вывода с подробной информацией о контейнере. Чтобы отфильтровать только информацию о портах, используйте эту команду:

docker inspect --format='{{json .NetworkSettings.Ports}}' web-demo | jq

Если jq не установлен, вы можете установить его с помощью:

sudo apt-get update && sudo apt-get install -y jq

Вывод отфильтрованной команды inspect будет выглядеть так:

{
  "80/tcp": [
    {
      "HostIp": "0.0.0.0",
      "HostPort": "8080"
    }
  ]
}

Это показывает подробную информацию о отображении портов:

  • Порт контейнера: 80/tcp
  • IP хоста: 0.0.0.0 (все интерфейсы)
  • Порт хоста: 8080

Вывод списка всех портов контейнера

Если у вас несколько контейнеров, вы можете увидеть все отображения портов с помощью:

docker ps --format "{{.Names}}: {{.Ports}}"

Вывод:

web-demo: 0.0.0.0:8080->80/tcp

Это полезно при управлении несколькими контейнерами с разными конфигурациями портов.

Доступ к сервисам через экспортированные порты

Теперь, когда мы понимаем, как инспектировать порты контейнера, давайте получим доступ к веб-серверу, работающему в нашем контейнере.

Тестирование доступности контейнера

Поскольку мы отобразили порт 80 контейнера на порт 8080 на хосте, мы можем получить доступ к веб-серверу Nginx через порт 8080.

Давайте используем команду curl, чтобы сделать запрос к нашему веб-серверу:

curl localhost:8080

Вы должны увидеть HTML приветственной страницы Nginx:

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    <style>
      html {
        color-scheme: light dark;
      }
      body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    <p>
      If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.
    </p>

    <p>
      For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br />
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.
    </p>

    <p><em>Thank you for using nginx.</em></p>
  </body>
</html>

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

Запуск нескольких сервисов

Давайте создадим другой контейнер с другим сервисом и отображением портов:

docker run -d --name redis-demo -p 6379:6379 redis

Эта команда запускает контейнер базы данных Redis и отображает его порт по умолчанию 6379 на тот же порт на хосте.

Проверьте запущенные контейнеры:

docker ps

Вывод:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                    NAMES
a45df67e21b3   redis     "docker-entrypoint.s…"   10 seconds ago   Up 10 seconds   0.0.0.0:6379->6379/tcp   redis-demo
f7d483e51ef2   nginx     "/docker-entrypoint.…"   10 minutes ago   Up 10 minutes   0.0.0.0:8080->80/tcp     web-demo

Теперь у нас есть два контейнера, работающих с разными сервисами, каждый со своим отображением портов.

Управление конфигурациями портов контейнера

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

Общие сценарии управления портами

Вот некоторые распространенные сценарии, с которыми вы можете столкнуться:

1. Изменение отображений портов

Если порт 8080 уже используется на вашем хосте, вы можете отобразить его на другой порт:

docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -p 8081:80 nginx

Теперь контейнер Nginx доступен на порту 8081:

curl localhost:8081

2. Привязка к определенным интерфейсам

Вместо привязки ко всем интерфейсам (0.0.0.0), вы можете привязаться к определенному IP-адресу:

docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -p 127.0.0.1:8080:80 nginx

Это привязывает порт контейнера только к интерфейсу localhost, делая его недоступным извне хоста.

3. Использование случайных портов хоста

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

docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -P nginx

Флаг -P публикует все экспортированные порты на случайные порты на хосте.

Проверьте назначенный порт:

docker port web-demo

Вывод:

80/tcp -> 0.0.0.0:49153

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

Устранение неполадок, связанных с портами

Вот решения распространенных проблем, связанных с портами:

  1. Порт уже используется: Если вы видите ошибку, например, "port is already allocated" (порт уже выделен), выберите другой порт:
docker run -d --name another-web -p 8082:80 nginx
  1. Контейнер не может подключиться к хосту: Если контейнеру необходимо подключиться к сервису на хосте, используйте специальное DNS-имя Docker host.docker.internal вместо localhost:
docker run --rm alpine ping -c 2 host.docker.internal
  1. Проверка, какой процесс использует порт: Если порт уже используется на хосте, найдите процесс:
sudo lsof -i :8080

Очистка

Давайте очистим наши контейнеры:

docker stop web-demo redis-demo
docker rm web-demo redis-demo

Резюме

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

  • Понимание разницы между экспортированными и опубликованными портами
  • Запуск контейнеров с определенными отображениями портов
  • Инспектирование конфигураций портов контейнеров с использованием различных команд Docker
  • Доступ к сервисам, работающим внутри контейнеров, через отображенные порты
  • Управление и устранение неполадок в общих сценариях, связанных с портами

Эти навыки являются основополагающими для работы с контейнерами Docker и необходимы для развертывания контейнеризированных приложений в средах разработки и производства. Обладая этими знаниями, вы теперь можете уверенно настраивать и управлять сетевыми аспектами ваших контейнеров Docker.