Введение
Docker – это широко используемая технология контейнеризации, которая произвела революцию в способах разработки, упаковки и развертывания приложений. Понимание экспортированных портов (exposed ports) контейнера Docker является фундаментальным аспектом работы с Docker, поскольку это позволяет вам получать доступ к службам, работающим внутри контейнера, и взаимодействовать с ними. Этот учебник проведет вас через процесс инспектирования экспортированных портов контейнера Docker, что позволит вам лучше управлять и оптимизировать ваши контейнеризированные приложения.
Понимание портов контейнеров Docker
Прежде чем мы углубимся в инспектирование портов контейнеров, давайте сначала разберемся, что такое порты и почему они важны в контейнерах Docker.
Что такое порты контейнеров
В Docker порты позволяют службам, работающим внутри контейнера, взаимодействовать с внешним миром. Думайте о портах как о дверях к вашему контейнеризированному приложению – не открыв эти двери, никто не сможет получить доступ к службам внутри.
Типы конфигураций портов
Docker поддерживает два основных типа конфигураций портов:
Exposed Ports (Экспортированные порты): Порты, которые контейнер делает доступными для потенциальных подключений, но которые не являются автоматически доступными с хоста.
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.
Устранение неполадок, связанных с портами
Вот решения распространенных проблем, связанных с портами:
- Порт уже используется: Если вы видите ошибку, например, "port is already allocated" (порт уже выделен), выберите другой порт:
docker run -d --name another-web -p 8082:80 nginx
- Контейнер не может подключиться к хосту: Если контейнеру необходимо подключиться к сервису на хосте, используйте специальное DNS-имя Docker
host.docker.internalвместоlocalhost:
docker run --rm alpine ping -c 2 host.docker.internal
- Проверка, какой процесс использует порт: Если порт уже используется на хосте, найдите процесс:
sudo lsof -i :8080
Очистка
Давайте очистим наши контейнеры:
docker stop web-demo redis-demo
docker rm web-demo redis-demo
Резюме
В этой лабораторной работе вы узнали, как работать с портами контейнеров Docker, включая:
- Понимание разницы между экспортированными и опубликованными портами
- Запуск контейнеров с определенными отображениями портов
- Инспектирование конфигураций портов контейнеров с использованием различных команд Docker
- Доступ к сервисам, работающим внутри контейнеров, через отображенные порты
- Управление и устранение неполадок в общих сценариях, связанных с портами
Эти навыки являются основополагающими для работы с контейнерами Docker и необходимы для развертывания контейнеризированных приложений в средах разработки и производства. Обладая этими знаниями, вы теперь можете уверенно настраивать и управлять сетевыми аспектами ваших контейнеров Docker.



