Прямой ответ
Контейнер работает в отдельном сетевом пространстве имён, поэтому диагностика выполняется внутри него: собственные интерфейсы, маршруты и параметры разрешения имён.
# Диагностика внутри пространства имён контейнера
docker exec -it app sh -c 'ip addr; ip route; cat /etc/resolv.conf'
# Проверка связности с целевым сервисом
kubectl exec deploy/app -- sh -c 'nc -zv db 5432; getent hosts db'
# Запуск диагностического контейнера в той же сети
kubectl run nettest --rm -it --image=nicolaka/netshoot -- bash
| Что проверяется | Признак проблемы |
|---|---|
| Наличие интерфейса и адреса | Адрес не назначен, поэтому обмен невозможен |
| Маршрут по умолчанию | Маршрут отсутствует, поэтому внешний адрес недоступен |
| Конфигурация разрешения имён | Сервер разрешения недоступен либо имя не разрешается |
| Связность с целевым портом | Соединение не устанавливается, поэтому сервис недоступен |
Диагностический контейнер запускается в той же сети, поэтому проверка выполняется в условиях целевого контейнера без изменения его образа. Об отладке подов — в статье про отладку подов.
Типовые причины отказа и порядок проверки
Отказ сетевого обмена в контейнере определяется последовательной проверкой слоёв, поскольку причина локализуется на одном из них.
Отсутствие адреса либо маршрута. Контейнер не получает адрес либо маршрут по умолчанию, поэтому обмен за пределами сети невозможен.
Отказ разрешения имени. Сервер разрешения недоступен либо запись отсутствует, поэтому подключение по имени завершается ошибкой. Проверка по адресу отличает отказ разрешения от отказа связности.
Ограничение сетевого правила. Правило изоляции запрещает обмен с целевым сервисом, поэтому соединение не устанавливается, при этом связность с другими сервисами сохраняется. О правилах — в статье про network policy.
Практическое следствие: проверка выполняется от адреса и маршрута к разрешению имени и связности с портом, поскольку каждый этап исключает часть причин.
Отдельный аспект — отсутствие инструментов в образе. Минимальный образ может не содержать утилит диагностики, поэтому проверка выполняется из отдельного контейнера в той же сети.
Три признака, определяющие направление диагностики.
Имя не разрешается, адрес доступен. Отказ связан с разрешением имён, а не со связностью.
Связность с одним сервисом есть, с другим — нет. Правило изоляции ограничивает обмен с целевым сервисом.
Внешний адрес недоступен, внутренний доступен. Маршрут по умолчанию отсутствует либо выход за пределы сети запрещён.
О сетях между контейнерами — в статье про сети Docker.
Диагностика после перезапуска контейнера
Перезапуск контейнера изменяет сетевое состояние, поэтому проверка выполняется после перезапуска, а не до него.
Новый адрес при перезапуске. Контейнер получает адрес заново, поэтому прежний адрес не используется. Обращение по прежнему адресу завершается ошибкой.
Сброс соединения при перезапуске. Соединения, установленные до перезапуска, прерываются, поэтому клиент выполняет повторное подключение.
Обновление записи разрешения имени. Запись, соответствующая контейнеру, обновляется после перезапуска, поэтому кэш разрешения может удерживать прежний адрес.
Практическое следствие: диагностика выполняется после завершения перезапуска, поскольку промежуточное состояние не отражает рабочее состояние сети.
Практика: диагностика сети контейнера
1. Проверьте адрес и маршрут внутри контейнера. Отсутствие адреса либо маршрута делает обмен невозможным.
2. Проверьте конфигурацию разрешения имён. Сервер разрешения указывается в конфигурации контейнера, поэтому его доступность проверяется.
3. Отличите отказ разрешения от отказа связности. Подключение по адресу при неработающем разрешении имени указывает на источник отказа.
4. Проверьте связность с целевым портом. Соединение устанавливается либо отклоняется, поэтому доступность сервиса определяется.
5. Используйте диагностический контейнер при отсутствии утилит. Минимальный образ не содержит инструментов, поэтому проверка выполняется из отдельного контейнера.
6. Проверьте сетевые правила. Ограничение изоляции запрещает обмен с целевым сервисом.
7. Фиксируйте результат проверки по слоям. Локализация причины на определённом слое сокращает время поиска.
Рекомендации:
- Различайте отказ разрешения и отказ связности. Проверка по адресу отличает источник отказа, поэтому направление диагностики определяется сразу.
- Учитываем отсутствие утилит в минимальном образе. Диагностический контейнер в той же сети обеспечивает проверку без изменения образа.
- Проверяйте правила изоляции. Запрет обмена с целевым сервисом выглядит как недоступность, при этом связность с другими сервисами сохраняется.
- Фиксируйте последовательность проверки. Проверка от адреса к порту исключает часть причин на каждом этапе.
- Пересматривайте при изменении сетевой конфигурации. Изменение сети либо правил изменяет результат проверки.
Практический сценарий: сервис в контейнере не подключался к базе
Контекст: приложение в контейнере завершалось с ошибкой подключения к базе данных, при этом база была доступна с других узлов.
- Диагностика. Проверка внутри контейнера показала, что имя базы не разрешается, при этом подключение по адресу выполнялось успешно. Конфигурация разрешения имён указывала сервер, недоступный из сетевого пространства контейнера.
- Причина. Сервер разрешения имён, указанный в конфигурации, был недоступен из сети контейнера. Разрешение завершалось ошибкой, поэтому подключение по имени не выполнялось.
- Действия. (а) Проверили адрес, маршрут и конфигурацию разрешения внутри контейнера; (б) отличили отказ разрешения от отказа связности подключением по адресу; (в) исправили конфигурацию разрешения имён, указав доступный сервер; (г) проверили разрешение имени и подключение после изменения; (д) добавили проверку доступности базы при запуске контейнера.
- Результат. Имя базы разрешается, подключение выполняется, поскольку конфигурация разрешения указывает доступный сервер.
Вывод: отказ сетевого обмена в контейнере локализуется последовательной проверкой слоёв. Отличие отказа разрешения от отказа связности определяет направление поиска, поэтому проверка по адресу выполняется до проверки правил и маршрутов.
FAQ
Почему диагностика выполняется внутри контейнера? Контейнер работает в отдельном сетевом пространстве имён, поэтому интерфейсы, маршруты и конфигурация разрешения собственные. Проверка с узла не отражает условия контейнера.
Как проверить сеть, если в образе нет утилит? Запуском диагностического контейнера в той же сети, поэтому проверка выполняется в условиях целевого контейнера без изменения образа.
Как отличить отказ разрешения от отказа связности? Подключением по адресу. Если подключение по адресу выполняется, а по имени — нет, отказ связан с разрешением имён.
Что указывает на ограничение сетевого правила? Отсутствие связности с целевым сервисом при сохранённой связности с другими. Правило изоляции запрещает обмен с конкретным назначением.
Источники: ip-netns, Kubernetes debug cluster, Docker network — ссылки в шапке.