Вопрос или проблема
У меня есть Docker-контейнер с внутренним IP-адресом 172.17.0.2, который подключен к виртуальному интерфейсу Docker с IP 172.17.0.1 на моем хосте:
root@ldc1:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
root@ldc1:/# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
root@ldc1:/#
Я могу пинговать 172.17.0.1 внутри запущенного Docker-контейнера. Затем я добавляю сетевое пространство имен и настраиваю его:
#!/bin/bash
# создать пространство имен
ip netns add ns2
ip link add veth20 type veth peer name veth21
ip link set veth21 netns ns2
# настроить пространство имен
ip netns exec ns2 ip link set dev lo up
ip netns exec ns2 ip addr add 10.1.200.4/24 dev veth21
ip netns exec ns2 ip link set dev veth21 up
ip netns exec ns2 ip route add default via 10.1.200.3 dev veth21
# настроить глобальное пространство имен
ip addr add 10.1.200.3/24 dev veth20
ip link set dev veth20 up
# включить переадресацию
echo 1 > /proc/sys/net/ipv4/ip_forward
Затем я открываю пространство имен и пытаюсь пинговать 172.17.0.1
root@ldc1:/home/vscode/wc# ip netns exec ns2 bash
root@ldc1:/home/vscode/wc# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) байт данных.
64 байта от 172.17.0.2: icmp_seq=1 ttl=64 время=0.023 ms
^C
--- статистика ping 172.17.0.2 ---
1 пакет отправлено, 1 получено, 0% потерь, время 0ms
rtt min/avg/max/mdev = 0.023/0.023/0.023/0.000 ms
root@ldc1:/home/vscode/wc# ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) байт данных.
^C
--- статистика ping 172.17.0.1 ---
1 пакет отправлено, 0 получено, 100% потерь, время 0ms
И пинги не проходят. Если я пытаюсь пинговать адаптер внутри глобального пространства имен (172.17.0.2), это работает отлично.
У кого-нибудь есть идея, что не так и почему пакеты ping не могут достичь 172.17.0.1? Что я не учитываю?
В дополнение к echo 1 > /proc/sys/net/ipv4/ip_forward
вам может потребоваться добавить необходимые правила iptables
для переадресации трафика между veth20
и eth0
.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o veth20 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i veth20 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -o veth20 -j MASQUERADE
iptables -A FORWARD -i veth20 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o veth20 -j ACCEPT
Ответ или решение
Для решения вашей проблемы с доступом к интерфейсу шлюза внутри сетевого пространства имен рассмотрим различные аспекты настройки и взаимодействия между сетями Docker и сетевыми пространствами имен Linux. Начнем с теории, затем приведем примеры и перейдем к практическому применению.
Теория
Ваша задача связана с маршрутизацией между сетевым пространством имен Linux и контейнером Docker, который использует сетевой интерфейс Docker bridge (docker0
). Docker bridge — это виртуальный сетевой интерфейс, который автоматически создается Docker’ом для облегчения взаимодействия контейнеров с хостовой системой и между собой.
Сетевые пространства имен (network namespaces) позволяют создавать изолированные сетевые среды внутри одного хостового узла. В этой изоляции каждое пространство имен имеет свои собственные интерфейсы, таблицы маршрутизации и правила файрвола. Это полезно для организации эффективной и безопасной сетевой инфраструктуры.
Однако, сетевые пространства имен изолированы друг от друга, и для обеспечения связи между пространствами требуется дополнительная настройка — маршрутизация и правила iptables
.
Пример
В сценарии, который вы описали, контейнер Docker имеет IP-адрес 172.17.0.2, и подключен к мосту Docker с IP-адресом 172.17.0.1 на хостовой машине. Вы создали сетевое пространство имен ns2
и настроили пару veth
интерфейсов для подключения этого пространства к хосту.
-
Создание пространства имен и интерфейсов:
ip netns add ns2 ip link add veth20 type veth peer name veth21 ip link set veth21 netns ns2
-
Настройка IP-адресов:
ip netns exec ns2 ip addr add 10.1.200.4/24 dev veth21 ip addr add 10.1.200.3/24 dev veth20
-
Маршрутизация:
ip netns exec ns2 ip route add default via 10.1.200.3 dev veth21
-
Включение маршрутизации:
echo 1 > /proc/sys/net/ipv4/ip_forward
Проблема возникает, когда вы пытаетесь отправить ICMP-запросы (ping) на 172.17.0.1 из пространства имен, но пакеты не проходят. Это связано с отсутствием правил трансляции сетевых адресов и маршрутизации между сетями.
Применение
Для решения этой проблемы необходимо настроить iptables
для NAT и форвардинга пакетов:
-
Конфигурация правил
iptables
:iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -A FORWARD -i eth0 -o veth20 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i veth20 -o eth0 -j ACCEPT iptables -t nat -A POSTROUTING -o veth20 -j MASQUERADE iptables -A FORWARD -i veth20 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i eth0 -o veth20 -j ACCEPT
-
Проверка сетевых конфигураций:
Убедитесь, что маршруты настраиваются правильно не только внутри пространства имен, но и на хосте. Проверьте, что хост знает, как доставлять пакеты в Docker сеть и обратно. -
Тестирование сетевого соединения:
Запустите командыping
или используйтеtraceroute
для диагностики маршрута пакетов. Это поможет выявить, на каком этапе (какой маршртузатор, интерфейс) происходит потеря. -
Логи файрвола:
Проверьтеiptables
и системные логи для выявления пакетов, которые могут быть отбрасываются, чтобы соответствующе корректировать правила.
Все эти шаги помогут вам наладить взаимодействие между сетевым пространством имен и контейнером Docker, обеспечив необходимую маршрутизацию и NAT. Без этого, пакеты из пространства имен оказываются в изолированной сети, не имея доступа к сетям за пределами хоста.arputvnet.appsinterfaceorkarabonnexplanalvraftesetputstattung.VERSION26.NLAspaseendparoubeurset .