Ответ
При отладке сетевой связности между контейнерами или из контейнера во внешний мир я проверяю доступность несколькими способами, в зависимости от протокола и того, что нужно проверить.
1. Базовая проверка TCP-соединения:
Использую nc (netcat) или bash-встроенные возможности, если nc не установлен.
# Проверка доступности порта 5432 на хосте `postgres-db`
nc -zv postgres-db 5432
# Альтернатива с таймаутом, если nc нет
timeout 2 bash -c '</dev/tcp/postgres-db/5432 && echo Port is open' || echo Port is closed
2. Проверка HTTP/HTTPS эндпоинтов:
Для веб-сервисов использую curl с ключами для проверки не только доступности, но и корректности ответа.
# Проверка, что сервис отвечает и возвращает HTTP 200
curl -s -o /dev/null -w "%{http_code}" http://api-service:8080/health
# Проверка с таймаутом и выводом ошибки в случае неудачи
curl -f --max-time 5 http://api-service:8080/health
# Подробный запрос для отладки заголовков
curl -v http://api-service:8080/health
3. Проверка разрешения DNS имен внутри Docker-сети: Часто проблема в DNS. Проверяю так:
# Проверяю, разрешается ли имя сервиса
nslookup api-service
# Или
dig api-service
# Если утилит нет, проверяю через /etc/hosts
cat /etc/hosts
4. Использование специализированных образов для отладки сети: Если в рабочем контейнере нет нужных утилит, запускаю временный отладочный контейнер в той же сети.
docker run -it --rm --network my_app_network appropriate/curl -I http://api-service:8080
5. Практический пример в Docker Compose или Dockerfile:
В docker-compose.yml я часто добавляю команду healthcheck, которая использует curl или nc для проверки зависимых сервисов перед запуском основного приложения.
services:
app:
image: myapp:latest
depends_on:
postgres:
condition: service_healthy
# ...
postgres:
image: postgres:15
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 10s
timeout: 5s
retries: 5
Важные моменты:
- Имена хостов: Внутри Docker-сети (особенно созданной Docker Compose) контейнеры доступны по имени сервиса. Извне или между разными сетями — нужно использовать полное доменное имя или IP.
- Порты: Убедиться, что проверяю правильный порт, который сервис слушает внутри контейнера, а не опубликованный на хост (
container_portvshost_port). - Таймауты: Всегда добавляю таймауты в скрипты проверки, чтобы они не зависали.