Calico Kubernetes the hard way v2 How tunl0 works

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


Как работает 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.88/24                                                192.168.122.125/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.


Перевод:

Обратите внимание на то, что когда загружен модуль 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
  • Добавить IP адреса на тунельном интерфейсе (Важно - это адреса именно на туннеле, а не адреса транспортные адреса, транспортные остаются все так же any/any
ip addr add 10.244.189.71/32 dev tunl0
ip link set up dev tunl0
ip addr add 10.244.235.136/32  dev tunl0
ip link set up dev tunl0

Далее происходит некая "магическая" последовательность действий - маршруты onlink

Особенности маршрутизации и onlink

Для лучшего понимания рассмотрим пример таблицы маршрутизации одной из нод (оставлены только значимые части):

10.244.182.0    192.168.122.114 255.255.255.192 UG    0      0        0 tunl0
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 enp1s0

Эти две записи вместе выглядят очень странно

  • C одной стороны для достижения сети 10.244.182.0/26 предполагается использование шлюза 192.168.122.114 и интерфейса tunl0 (на это указывает первая строка в таблице)
  • С другой стороны, для адреса шлюза 192.168.122.114 должен использоваться интерфейс enp1s0, а не интерфейс tunl0 (на это указывает вторая строка в таблице)


Тут стоит отметить, что утилита route устаревшая и показывает не все параметры таблицы, если посмотреть с помощью ip то можно видеть атрибуты маршрутов.

ip route
10.244.182.0/26 via 192.168.122.114 dev tunl0 proto bird onlink 

Обратить внимание на onlink,
proto bird не является значащим в контексте туннелирования, можно игнорировать
Вот цитата из руководства iproute2 https://man7.org/linux/man-pages/man8/ip-route.8.html

onlink pretend that the nexthop is directly attached to
this link, even if it does not match any interface prefix.


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

Другими словами, команда создаст особый тип маршрута.
Пакет, отправленный через этот маршрут пройдя через интерфейс tunl0, будет обернут в дополнительные заголовки IP и отправлен на шлюз 192.168.122.114

ip ro add 10.244.182.0/24 via 192.168.122.114 dev tunl0 onlink

Важная заметка про onlink (this part is in progress)

По-сути, если крепко вдуматься, то никакой особой сетевой магии тут не происходит.
текст описания просто по-дебильному написан.

Попробую более понятно пояснить своими словами.

Ключевое слово тут - link

ip link show
<PRE>

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000

   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

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

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

4: veth11@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000

   link/ether 42:56:a7:07:b9:34 brd ff:ff:ff:ff:ff:ff link-netnsid 1

5: veth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000

   link/ether 66:72:3f:f6:1d:3f brd ff:ff:ff:ff:ff:ff link-netnsid 1

6: veth11.11@veth11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000

   link/ether 42:56:a7:07:b9:34 brd ff:ff:ff:ff:ff:ff



Тут остается тема для дополнительных исследований - что будет происходить если вместо tunl0 будет другой виртуальный интерфейс с другим типом инкапсуляции?

Получение пакета на другой ноде

Это самая простая и понятная часть - тут происходит "магия" tunl0
Так как на ноде, куда отправлен пакет, нет других туннельных интерфейсов то пакет с инкапсуляцией ipip будет обработан, дополнительные заголовки IP будут сняты, и далее пакет можно будет увидеть на интерфейсе tunl0
После этого пакет будет отправлен далее согласно таблице маршрутизации.

Ссылки