Calico Kubernetes the hard way v2 How tunl0 works
Как работает IP-in-IP
туннель в Calico
Это один из вариантов конфигурации Calico.
Эта статья появилась так-как настройка туннеля не очень-то очевидна.
Схема сети
- Показаны только 2 ноды, для простоты.
- 192.168.122.0/24 - физическая сеть
+----------------------------------------+ +----------------------------------------+ | Host: worker1 | | Host: worker2 | | +---------------------+ | | +---------------------+ | | | POD1 | | | | POD2 | | | | | | | | | | | | 10.244.235.132/32 | | | | 10.244.189.171/32 | | | +---eth0--------------+ | | +---eth0--------------+ | | | | | | | | | | | | | | caliXXXX | | caliYYYY | | На этом интерфейсе НЕТ ip адреса | | На этом интерфейсе НЕТ ip адреса | | | | | | [ tunl0 ] 10.244.235.136/32 | | [ tunl0 ] 10.244.189.71/32 | | | | | +--[ eth0 ]-----------------------------+ +--[ eth0 ]-----------------------------+ 192.168.122.2/24 192.168.122.3/24 | | +---------------------------------------------------------------+
Настройки интерфейса tunl0
Calico
Если не особо вдумываться, то в настройке интерфейса (одинаковом на всех нодах, с одинаковыми настройками) нет ничего необычного
ip -d link show dev tunl0
2: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 promiscuity 0 ipip remote any local any ttl inherit nopmtudisc addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
Однако, если смотреть внимательно то вызывает вопрос вот эта часть конфигурации
link/ipip 0.0.0.0 brd 0.0.0.0 promiscuity 0 ipip remote any local any <PRE> Поясню: обычно <code>ipip</code> туннели представляют собой соединения точка-точка, при этом в настройках туннеля указываются адреса концов туннеля.<br> Например классический туннель создается командой <PRE> ip tunnel add mytun mode ipip remote 251.4.92.217 local 240.101.83.2
IP адреса тут взяты "из головы" и приведены только для примера.
Соответственно, в настройках туннеля можно видеть "оба конца" туннеля.
3: mytun@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ipip 240.101.83.2 peer 251.4.92.217 promiscuity 0 ipip remote 251.4.92.217 local 240.101.83.2 ttl inherit pmtudisc numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
Подчеркну, что это именно "транспортные" адреса, между которыми должна быть L3 связность, и это не те адреса которые настроены на интерфейсе mytun
Совершенно не понятно как работает туннель не имеющих определенных "концов" - что с чем связывает туннель с ipip remote any local any
Этот вопрос и разбирается в этой статье.
tunl0
и его особенности
Как показало длительное чтение документации и еще более длительный поиск в интернетах, у модуля ядра ipip
есть хоть и документированная, но мало кому известная особенность, а именно.
Note: When the ipip module is loaded, or an IPIP device is created for the first time, the Linux kernel will create a tunl0 default device in each namespace, with attributes local=any and remote=any. When receiving IPIP protocol packets, the kernel will forward them to tunl0 as a fallback device if it can't find another device whose local/remote attributes match their source or destination address more closely. <PRE> <br> Перевод: <PRE> Обратите внимание на то, что когда загружен модуль ipip, или когда впервые создано IPIP-устройство, ядро Linux создаст в каждом пространстве имён устройство по умолчанию tunl0 с атрибутами local=any и remote=any. Получая IPIP-пакеты, ядро, в определённых случаях, будет перенаправлять их на tunl0 как на устройство, используемое по умолчанию. Это происходит тогда, когда ядро не может найти другого устройства, атрибуты local/remote которого более точно соответствуют адресам источника и приёмника пакетов.
Другими словами, интерфейс tunl0
(и да - он присутствует во всех network namespaces, а значит его можно видеть во всех POD
будет осуществлять деинкапсуляцию
для любого пакета, который не попал до того в другой интерфейс типа ipip tunnel
. Эта схема работает, так как в ipip tunnel
нет ничего что бы напоминало идентификатор интерфейса,
вроде Vlan ID
или VxLAN VNI
, а так же нет штатного шифрования.
Итого, любой пакет который является ipip
пакетом и не был помещен в туннельный интерфейс по совпадению local/remote, в конце концов не будет отброшен а будет помешен в интерфейс tunl0
(на мой взгляд это не совсем логичное поведение, но тем не менее именно оно позволяет организовать работу Calico)
Настройка tunl0
(в ручном режиме)
Для того что бы понять что делает Calico
нужно воспроизвести все шаги по созданию и настройки интерфейса tunl0
- Загрузить модуль
ipip
(если не был загружен до того)
modprobe ipip
- Убедиться в том что модуль загрузился без ошибок
lsmod | grep ipip
ipip 16384 0 tunnel4 16384 1 ipip ip_tunnel 24576 1 ipip
dmesg -T | grep ipip [Чт дек 22 17:16:51 2022] ipip: IPv4 and MPLS over IPv4 tunneling driver
Ссылки
- https://habr.com/ru/post/48276/
- https://lartc.vger.kernel.narkive.com/XgcjFTGM/aw-onlink-option-for-ip-route
- https://habr.com/ru/company/ruvds/blog/457386/
- https://habr.com/ru/post/48276/
- https://man7.org/linux/man-pages/man8/ip-link.8.html
- https://developers.redhat.com/blog/2019/05/17/an-introduction-to-linux-virtual-interfaces-tunnels#ip6gre_and_ip6gretap
- https://weril.me/ifconfig/
- https://www.oreilly.com/library/view/wireless-hacks/0596005598/ch04s13.html