The Jerusalem PostNetanyahu's inner circle is now almost entirely religious, cabinet secretary saysPunchPSG’s Kvaratskhelia to undergo surgery after ACL rupture – OfficialDaily MaverickTIME TO REFOCUS: SA’s URC teams face northern examination as club season ramps upBollywood HungamaEXCLUSIVE: Gulshan Devaiah DEBUNKS Wikipedia's claim that he made his debut in Salman Khan's Dil Ne Jise Apna Kahaa: “Even I have seen it and I laugh at it!”InquirerMarcos, Angara roll out Yakap health caravan in SuluSouth China Morning PostAttitudes shifting in Hong Kong’s favour as city reaps Apec benefits: Paul ChanRTL BoulevardAbdi A., verdachte dood Hajar, werd opgepakt bij pleegvader in SpierdijkZDF heuteAktuelle Pressemitteilungen des ZDFCNN بالعربيةتحليل.. من "الأسطول المظلم" إلى الديزل الروسي.. لا "حلول سحرية" لخفض أسعار الوقود بأمريكاVanguardNigeria’s 11m-tonne cold storage gap exposes food supply weakness7sur7L’horreur à Toulouse: un homme aurait tué trois membres de sa famille avant de se suiciderCapital FMSix oil tankers among 51 ships expected at Mombasa, Lamu ports
The Daily Newsstand · Free, Always
Wednesday, October 21, 2026

Как работают сетевые неймспейсы внутри Docker‑контейнера

Translate

Привет! Я Лев, системный администратор технической поддержки в Selectel.

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

Что такое сетевые неймспейсы и зачем они контейнерам

Откроем контейнер и заглянем в его сеть. До появления неймспейсов вся сеть в Linux была глобальной и плоской. Она содержала единственный набор сетевых интерфейсов,одну таблицу маршрутизации на весь сервер, один экземпляр файрвола, а все процессы делили единственный пул портов.

Если два процесса хотели слушать один и тот же порт, например 80, они конфликтовали. Если одно приложение меняло маршруты или правила файрвола, это влияло на всех. Изоляции не было: процессы «видели» всю сеть хоста и друг друга.

Сетевой неймспейс — это изолированный экземпляр сетевого стека внутри ядра Linux. Группа процессов, скажем, контейнер, получает свою собственную копию сетевого окружения: интерфейсы, в том числе, loopback, IP-адреса, таблицу маршрутизации, ARP/ND‑кэши и правила межсетевых экранов.

Снаружи этот мир невидим для хоста и других неймспейсов, а внутри все выглядит как полноценная сеть.

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

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

  1. Loopback (lo, localhost) — обеспечивает передачу трафика внутри самого устройства. Этот базовый интерфейс незаменим для внутреннего взаимодействия микросервисов и проведения тестов, не требующих выхода во внешнюю сеть. Он всегда доступен по адресам с 127.0.0.1 по 127.255.255.255.

  2. veth (Virtual Ethernet) — пара виртуальных интерфейсов, соединенных «внутренним кабелем». Все, что отправляется на один конец, немедленно получает и второй. Применяется она для связи между изолированными частями системы.

  3. Bridge (мост) — действует как программный коммутатор, который объединяет несколько интерфейсов друг с другом, позволяя им работать как единая сеть.

Хотя в официальной документации Docker и в ядре Linux этот тип сети называется bridge, далее в статье будет использоваться термин «коммутатор».

Технически виртуальный мост в Linux работает именно как многопортовый коммутатор (свитч). Он объединяет множество виртуальных кабелей (veth-пар) от разных контейнеров в единую сеть. Такая физическая аналогия гораздо точнее отражает суть технологии и проще для понимания.

Юмористический мем Рик и Морти о главном предназначении робота — запуске Docker-контейнеров

Источник.

Как Docker создает сетевые неймспейсы

Что же происходит в самом контейнере ?

Docker не создает сетевые неймспейсы самостоятельно — он задействует механизмы ядра Linux. Процесс настройки сети для нового контейнера можно разделить на четыре основных шага.

  1. Docker передает команду среде выполнения (рантайму) контейнера, и уже она запрашивает у ядра создание нового сетевого неймспейса для изолированного процесса.

  2. Создается пара виртуальных интерфейсов (veth-пара). Один из них помещается внутрь изолированного неймспейса контейнера, а второй остается в сетевом пространстве хоста.

  3. Docker настраивает интерфейс внутри контейнера (как правило, eth0) — задает IP-адрес, маршрут по умолчанию, DNS‑серверы и включает loopback-интерфейс.

  4. Хостовая сторона veth подключается к виртуальному коммутатору или к другой выбранной схеме маршрутизации и трансляции адресов (NAT). Контейнер получает возможность обмениваться сетевым трафиком с внешним миром и соседними узлами.

Схема создания сетевых неймспейсов в Docker: связь контейнеров через veth-интерфейсы и виртуальный коммутатор Bridge.

Источник.

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

Связь между хостом и контейнером: veth-пары и коммутатор

Bridge — стандартный сетевой драйвер Docker, который включается по умолчанию, когда контейнер запускается без явного указания флага --network. В этом режиме Docker создает на хосте программный коммутатор (по умолчанию docker0) и подключает к нему каждый контейнер через veth-пару. 

Каждый из них получает внутренние IP-адреса из подсети моста (обычно 172.17.0.0/16) и может взаимодействовать с другими контейнерами на канальном уровне через этот виртуальный свитч. Для выхода во внешнюю сеть хост автоматически настраивает NAT (маскарадинг) и DNAT для проброшенных портов.

Режим коммутатора выполняет главную практическую задачу — обеспечивает изолированным контейнерам полноценную связь друг с другом и внешним миром. Благодаря такой архитектуре на его примере удобнее всего разбирать работу veth-пар, сетевых неймспейсов и трансляции адресов.

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

Пакеты в такой схеме идут по следующему маршруту. 

  1. Приложение в контейнере отправляет трафик на eth0 — интерфейс, который существует внутри собственного сетевого неймспейса контейнера (его изолированного сетевого стека). 

  2. Далее пакет попадает на эндпойнт veth‑пары и проходит на ее вторую сторону, которая принадлежит уже сетевому неймспейсу хоста, и оказывается перед виртуальным коммутатором. 

  3. Коммутатор, работающий на канальном уровне L2, пересылает Ethernet-кадры между своими портами: либо на veth‑интерфейс другого контейнера, либо в сторону внешнего сетевого интерфейса хоста. При этом IP-адреса внутри кадра остаются неизменными.

Сравнение работы виртуального коммутатора bridge на канальном уровне L2 и маршрутизатора на уровне L3 в сетях Docker.

Источник.

Если говорить проще, veth — это виртуальный кабель, bridge — виртуальный коммутатор, а Docker собирает их в рабочую сеть для контейнеров.

Бесплатный курс «Системный администратор Linux с нуля»

Освойте администрирование Linux на SelectOS и станьте востребованным специалистом.

Зарегистрироваться →

Другие режимы сетей

Host

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

Такой режим означает, что:

  • внутри контейнера нет veth-пары и собственного коммутатора;

  • запускается он с флагом --network=host и получает сетевой неймспейс хоста;

  • все порты, которые прослушивают приложение в контейнере, сразу доступны на хосте (без ручного проброса параметрами -p/--publish).

Архитектура сетевого режима Host в Docker: прямое использование контейнером сетевого пространства и интерфейсов хоста.

Источник.

Обычно такой режим применяется в высоконагруженных сетевых приложениях, где важна каждая микросекунда, а администратор готов управлять портами вручную. Примером могут послужить: nginx или HAProxy в host-режиме, когда нужен доступ к реальному IP‑адресу клиента без подмены.

Macvlan

В этом режиме контейнер получает собственный MAC-адрес и выглядит в физической сети как отдельное устройство. Каждый контейнер — это своеобразный «виртуальный порт» с собственным MAC‑адресом и работает он с реальным коммутатором, без NAT по умолчанию.

Docker создает macvlan-интерфейс, привязанный к родительскому физическому интерфейсу — например, eth0. Внутри контейнера появляется veth-подобный интерфейс с уникальным MAC‑адресом. Пакеты идут напрямую в физическую сеть: коммутатор видит этот адрес и маршрутизирует к нему трафик как к обычному устройству.

На уровне коммутатора macvlan поддерживает режимы: 

  • bridge,

  • private, 

  • vepa,

  • passthru. 

Схема сетевого режима Macvlan: присвоение Docker-контейнерам собственных MAC-адресов в физической сети.

Источник.

Описанный метод используется, когда нужно поднять сервис, который должен быть «как настоящее оборудование» в корпоративной сети — со своим IP‑ и MAC‑адресами, без проброса портов. 

Следующий сетевой режим отчасти похож на macvlan, но имеет ряд отличий.

ipvlan

Этот режим можно назвать более легковесной версией macvlan: контейнеры получают IP из той же подсети, но используют один MAC-адрес для всех ipvlan-интерфейсов. Этот режим также не требует настройки MAC-таблиц на коммутаторе.

Ipvlan работает следующим образом.

  1. Создается ipvlan-интерфейс, привязанный к физическому интерфейсу.

  2. Контейнер получает IP‑адрес из той же подсети, что и хост.

  3. Коммутатор (switch) работает на сетевом уровне L3: он видит не множество MAC-адресов, только IP‑адреса.

Архитектура режима Ipvlan L2 в Docker: контейнеры с прямыми IP-адресами без использования виртуального моста docker0.

Источник.

Такой режим хорошо зарекомендовал себя для больших кластеров, где нужно много контейнеров с прямыми IP‑адресами, но без NAT и перегрузки MAC-таблиц.

overlay

И в завершение рассмотрим режим overlay — распределенную сеть между несколькими хостами Docker. Он используется в Docker Swarm, но может применяться и для соединения отдельных контейнеров на разных хостах.

Работает overlay следующим образом:

  • каждый хост имеет свой «локальный» коммутатор для контейнеров;

  • сеть overlay создает поверх них виртуальный туннель (обычно VXLAN);

  • контейнеры на разных хостах «видят» друг друга как в одной сети, без NAT между хостами.

Сетевой режим Overlay: создание распределенной сети и виртуального туннеля между Docker-контейнерами на разных хостах.

Источник.

Такой режим используется в Docker Swarm, Kubernetes и любых кластерах микросервисов, где нужна единая сеть поверх нескольких хостов.

NAT в Docker

NAT в Docker — это набор правил в netfilter (iptables/nftables), которые подменяют адреса и порты, чтобы:

  • обеспечивать контейнерам выход в интернет, несмотря на их частные IP‑адреса — например, 172.17.0.2;

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

В основе лежат два классических механизма: SNAT/Masquerade для исходящего трафика и DNAT для входящего. Docker автоматически управляет этими правилами, оставляя администратору возможность тонкой настройки через стандартные инструменты ядра.

Принцип работы NAT в Docker: правила межсетевого экрана для маршрутизации трафика между локальной сетью контейнеров и интернетом.

Источник.

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

Поднимаем свой Docker и настраиваем сеть

Пришло время разобраться с Docker на практике. Возьмем облачный сервер и выберем минимальную конфигурации в регионе ru-6.

Панель управления: выбор локации сервера и операционной системы Ubuntu 24.04 для установки Docker.

Выбор локации сервера и операционной системы.

Операционной системой пусть будет Ubuntu 24.04.

Настройка параметров облачного сервера: выбор стандартной конфигурации с выделенными ядрами для контейнеров

Настройка параметров облачного сервера.

Выбор количества vCPU и объема оперативной памяти для развертывания Docker на сервере.

Выбор количества vCPU и объема оперативной памяти.

Настройка сети облачного сервера: выделение публичного IP-адреса и добавление SSH-ключа для безопасного доступа.

Настройка сети и добавление SSH-ключа.

Для удобства добавим SSH‑ключ на сервер, после этого подключимся к нему удаленно — в браузере или терминале — и выполним несколько несложных административных действий.

Перед началом работы рекомендуется обновить все пакеты:

apt update && apt upgrade -y

Далее устанавливаем сам Docker, необходимые зависимости и добавляем официальный репозиторий.

sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release

sudo mkdir -p /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Устанавливаем Docker Engine.

sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Убедимся, что Docker работает.

docker run hello-world

Должны появиться ответные сообщения — например, как в листинге ниже.

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
4f55086f7dd0: Pull complete
d5e71e642bf5: Download complete
Digest: sha256:c3cbe1cc1aa588a64951ac6286e0df7b27fe2e6324b1001c619bb358770c0178
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Запустим два контейнера.

docker run -d --name c1 alpine sleep 3600
docker run -d --name c2 alpine sleep 3600

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

docker ps
Вывод команды docker ps в терминале: просмотр списка и статуса запущенных Docker-контейнеров alpine.

Проверим сетевые неймспейсы, запросив перечень всех созданных в системе виртуальных сетевых пространств.

sudo ip netns list
Результат выполнения команды sudo ip netns list для проверки виртуальных сетевых пространств на хосте.

Видим, что вывод пуст. Дело в том, что Docker по умолчанию не монтирует свои сетевые неймспейсы в /var/run/netns. Однако мы можем их увидеть через символические ссылки в /proc и с помощью утилиты nsenter.

Найдем PID контейнера и зайдем в его неймспейс.

PID=$(docker inspect -f '{{.State.Pid}}' c1)

echo $PID
sudo nsenter -t $PID -n ip addr
Диагностика контейнера утилитой nsenter: просмотр интерфейсов loopback и eth0 внутри изолированного сетевого неймспейса.

Внутри контейнера видим два интерфейса:

  • lo (loopback),

  • eth0@if6 — один конец veth-пары.

Посмотрим интерфейсы на хосте.

ip a
Вывод команды ip a на сервере: список сетевых интерфейсов, включая коммутатор docker0 и виртуальные кабели veth.

Видим, что появился интерфейс с именем veth24acaba@if2, который является второй стороной виртуального кабеля и прикреплен к коммутатору docker0.

Проверим подключения к этому коммутатору.

bridge link show

В выводе должны появиться наши виртуальные интерфейсы, которые привязаны к docker0 — на это указывает параметр master docker0.

Результат команды bridge link show: отображение привязки виртуальных интерфейсов veth к программному мосту docker0

Пришло время узнать IP-адреса контейнеров.

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' c1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' c2
Использование команды docker inspect для получения назначенных IP-адресов контейнеров из подсети моста

Следующей командой запускаются ICMP-запросы между контейнером c1 и c2.

docker exec c1 ping -c 3 $(docker inspect -f '{{.NetworkSettings.Networks.bridge.IPAddress}}' c2)
Проверка сетевой связности между Docker-контейнерами: успешная отправка ICMP-запросов с помощью утилиты ping.

Пакеты идут по маршруту:

c1 → eth0 (veth внутри неймспейса) → veth на стороне хоста → docker0 → veth второго контейнера → eth0 внутри c2.

Теперь посмотрим, как работает NAT, и начнем с исходящего трафика (SNAT).

Проверим правила межсетевого экрана:

sudo iptables -t nat -L POSTROUTING -n -v | grep MASQUERADE
Проверка правил iptables: отображение правила MASQUERADE для исходящего NAT-трафика в Docker.

В выводе мы видим правило MASQUERADE. Благодаря ему контейнер с локальным IP‑адресом выходит в интернет через IP‑адрес хоста.

Чтобы узнать публичный IP-адрес, используем команду:

docker exec c1 curl -s ifconfig.me
Узнаем публичный IP-адрес: выполнение HTTP-запроса через утилиту curl к сервису ifconfig.me из контейнера.

Теперь поработаем с DNAT.

Чтобы проверить проброс портов, нам потребуется приложение, прослушивающее порт внутри контейнера. Удобнее всего использовать легковесный веб-сервер nginx — он моментально запускается и сразу готов отдавать тестовую HTML-страницу по умолчанию.

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

Проверим правила для DNAT. Посмотрим содержимое специальной цепочки DOCKER в таблице NAT — в выводе увидим, как Docker автоматически настроил перенаправление трафика с порта 8080 хоста на 80-й порт контейнера.

sudo iptables -t nat -L DOCKER -n -v
Проверка правил DNAT в iptables: автоматическая настройка проброса портов в цепочке DOCKER для веб-сервера nginx.

Теперь убедимся, что проброс портов функционирует корректно. Для этого отправим HTTP-запрос на локальный порт хоста (8080) с помощью утилиты curl.

curl localhost:8080

Если DNAT настроен верно, трафик перенаправится в контейнер, и в терминал попадет HTML-код приветственной страницы nginx.

Тестирование проброса портов: успешный ответ веб-сервера nginx при отправке запроса curl на локальный порт хоста 8080.

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

docker run -d --name host-test --network host alpine sleep 3600

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

docker exec host-test ip addr

Вот примерный вывод:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
    link/ether fa:16:3e:b5:3e:6e brd ff:ff:ff:ff:ff:ff
    inet 161.104.58.129/24 brd 161.104.58.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:feb5:3e6e/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 42:94:34:18:65:fd brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::4094:34ff:fe18:65fd/64 scope link
       valid_lft forever preferred_lft forever
6: veth24acaba@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
    link/ether b6:4a:14:50:8a:79 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::b44a:14ff:fe50:8a79/64 scope link
       valid_lft forever preferred_lft forever
7: vetha7e07be@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
    link/ether fe:7f:f8:5a:89:4c brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc7f:f8ff:fe5a:894c/64 scope link
       valid_lft forever preferred_lft forever
8: veth62c119a@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
    link/ether 5a:0c:4f:81:c2:ec brd ff:ff:ff:ff:ff:ff
    inet6 fe80::580c:4fff:fe81:c2ec/64 scope link
       valid_lft forever preferred_lft forever

Мы видим все физические интерфейсы хоста, включая eth0, docker0 и другие. Никакого отдельного eth0 у контейнера нет — он разделяет сеть с хостом.

Утилиты для диагностики сети в контейнере

В предыдущем блоке мы разобрались, как настраивать и добавлять сетевые интерфейсы, а теперь посмотрим, как проверять настройки:

  • ip addr show — выводит список всех сетевых интерфейсов и назначенных им IP-адресов, а также помогает убедиться, что контейнер корректно получил нужный адрес;

  • ip route show — отображает текущую таблицу маршрутизации  и показывает, через какой шлюз (gateway) отправляется трафик по умолчанию и как маршрутизируются пакеты;

  • ip neigh show — показывает ARP-таблицу (кэш соседей), в которой можно увидеть соответствие IP-адресов и физических MAC-адресов других устройств в локальном сегменте сети;

  • ip -s link show eth0 — выводит подробную статистику по конкретному интерфейсу (в данном случае eth0). Команда крайне полезна для поиска сетевых ошибок, выявления отброшенных пакетов (drops) и оценки общего объема трафика.

Для проверки сетевой доступности и отслеживания маршрута до удаленного узла (в данном примере используется популярный тестовый IP-адрес 8.8.8.8) применяются следующие команды.

  • ping -c 4 8.8.8.8 — отправляет ICMP-запросы для проверки базовой связности. Флаг -c 4 ограничивает проверку четырьмя пакетами, чтобы выполнение команды завершилось автоматически. Такая простая команда — первый шаг при диагностике. Она сразу покажет, есть ли у контейнера выход во внешнюю сеть или нет.

  • traceroute -n 8.8.8.8 — отображает весь путь (цепочку маршрутизаторов), который проходят пакеты до конечной цели. Ключ -n отключает преобразование IP-адресов в доменные имена, что значительно ускоряет вывод результата. Инструмент незаменим, если нужно выяснить, на каком конкретно транзитном узле обрывается связь.

Для тестирования HTTP/HTTPS-соединений и проверки работоспособности API-эндпоинтов часто применяются инструменты curl или wget.

  • curl -v http://service-b:8080/health — отправляет HTTP-запрос и выводит полученный ответ. Флаг -v (verbose) включает подробный режим: он показывает заголовки запроса и ответа, коды состояния — такие как, 200 OK или 502 Bad Gateway, — а также детали установки соединения. Это критически важно при отладке работы веб-сервисов.

  • wget -O- http://service-b:8080/health — отличная альтернатива, если curl недоступен. По умолчанию wget пытается скачать данные и сохранить их на диск, но параметр -O- переопределяет это поведение, заставляя утилиту выводить полученный ответ прямо в терминал — даже, если это JSON-документ, например.

Для диагностики DNS-резолвинга полезно проверять, как именно контейнер преобразовывает доменные имена в IP-адреса, используются следующие утилиты.

  • nslookup google.com — базовая команда для отправки запроса к DNS-серверу. Она показывает соответствие IP-адреса указанному домену и помогает быстро понять, работает ли внутри контейнера разрешение имен вообще.

  • dig +short my-service.internal — более мощный и гибкий инструмент сетевой диагностики. В данном примере запрашивается внутреннее DNS-имя соседнего микросервиса. Ключ +short очищает экран от избыточной служебной информации, возвращая только искомый IP-адрес. Такие проверки невероятно удобны при написании скриптов или быстрой отладке внутренних сетей Docker.

Для просмотра открытых портов и активных сетевых соединений внутри контейнера отлично подходит утилита ss (socket statistics) — современная альтернатива классическому netstat.

ss -tlnp — выводит список прослушиваемых TCP-портов. Комбинация ключей означает:

  • -t — только протокол TCP;

  • -l — только порты, ожидающие подключений;

  • -n — показывать числовые номера портов, а не названия сервисов;

  • -p — отображать идентификатор процесса, занявшего порт.

Наш пример — способ быстро проверить, запустилось ли приложение и готово ли оно принимать трафик.

ss -anp — показывает абсолютно все сетевые сокеты. Благодаря флагу -a (--all) выводятся не только прослушиваемые порты, но и уже установленные (активные) соединения. Такой инструмент незаменим, если нужно разобраться, кто именно подключился к сервису прямо сейчас и с какими адресами контейнер обменивается данными.

Часто в минималистичных образах контейнеров нужные диагностические утилиты попросту отсутствуют. В таких случаях можно использовать инструменты хостовой ОС, «заглянув» в сетевой неймспейс контейнера с помощью утилиты nsenter.

Сперва необходимо выяснить идентификатор процесса (PID) нужного контейнера в системе хоста. Следующая команда извлекает это значение с помощью docker inspect и сразу сохраняет его в переменную оболочки PID.

PID=$(docker inspect -f '{{.State.Pid}}' <container_name>)

Важно: не забыть заменить <container_name> на нужное имя контейнера.

Получив PID, можно выполнять любые диагностические команды внутри изолированной сети. Для этого утилита nsenter запускается с двумя важными ключами: -t "$PID" указывает на целевой процесс, а -n (network) переключает контекст выполнения в его сетевой неймспейс.

Например, проверка интерфейсов будет выглядеть так:

sudo nsenter -t "$PID" -n ip addr

Заключение

В заключение отметим, что сетевой стек — одна из ключевых составляющих контейнерной платформы. Именно сетевые неймспейсы, виртуальные интерфейсы (veth), работающий как коммутатор bridge и другие режимы сети (host, macvlan, ipvlan, overlay) превращают процессы в полноценные сетевые узлы и задают поведение приложений в распределенной среде. 

Понимание того, как Docker создает и связывает неймспейсы, как маршрутизируются пакеты через связку veth↔bridge и как работают механизмы NAT (SNAT/DNAT), существенно упрощает расследование проблем и выбор правильной сетевой архитектуры для конкретной задачи.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.