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
Если не особо вдумываться, то в настройке интерфейса (одинаковом на всех нодах, с одинаковыми настройками) нет ничего необычного
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
Ссылки
- 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