Pull to refresh
177
-5.4
Andrei Kvapil @kvaps

Суперпользователь

Send message

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

Я бы добавил к преимуществам низкое потребление ресурсов а как следствие и электроэнергнии, целый день ходить со включённым OpenVPN весьма накладно для использования батареи, а вот с Outline дело обстоит намного лучше.

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

Спасибо за замечание, описал заветные опции в статье. (они так же были продублированны на картинке с бэнчмарком)
Что-то не подумал что телеграм может быть заблокирован на территории РФ.

Да, как-то упустил, использовалась дисковая полка Supermicro с Dual LSI SAS2X36 Expander

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


А когда он тестировал идеализированные условия, например, в разрезе Minio, он не посмотрел где именно бутылочное горлышко.

При тестировании minio iowait действительно был приличный, кстати, про то как работает minio тут недавно обсуждали.

Пардон, я не так выразился, я всего-лишь хотел сказать что правило


ip rule add to 10.112.0.0/12 lookup local

в моём случае не работало и вместо него выполнялось следующее попадающее под условие.


Разобрался, проблема оказалось в глупой ошибке, нужно использовать таблицу main, а не local


Теперь о хорошем, ваш метод работает:


ip rule add from 1.2.3.0/24 lookup 100
ip rule add from 1.2.3.0/24 to 10.112.0.0/12 lookup main

где 10.112.0.0/12 — сеть подов в Kubernetes.


Но правило to должно добавляться после, что бы имело наивысший приоритет.


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


Огромное спасибо за содействие, я собираюсь обновить статью чтобы описать данный метод как рекомендованный.

Дальше, конейнеры локальные или трафик через bond0 может прилетать?

Да всё верно, трафик из контейнеров может идти как локально из kube-bridge, так и с других нод через bond0.


Хорошая попытка, но к сожалению ip rule to у меня не заработало, как ни крути ответные пакеты всегда уходят в bond.100:



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


# ip rule
0:      from all lookup local
32762:  from all to 10.112.0.0/12 lookup local
32764:  from 1.2.3.0/24 lookup 100

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

Простой вопрос: как ещё можно пустить внешний трафик в кластер на ingress-контроллер, чтобы это было удобно и отказоусточиво?


А если таких ingress-контроллеров много?

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


Имеется n физических нод, на каждой из них есть несколько интерфейсов и IPVS, скажем:


  • bond0 (10.10.0.0/16) — внутренняя сетка
  • kube-bridge — бридж с контейнерами на ноде
  • kube-dummy-if — dummy интерфейс для IPVS, сюда вешаются все сервисные IP из куба (как внешние так и clusterIP), по сути это выглядит следующим образом:

Котейнеры получают адреса из podSubnet: 10.112.0.0/12, на каждую ноду выделяется свой рейдж из этого диапазона.
Есть ещё serviceSubnet: 10.96.0.0/12 (специальная сеть для сервисов Kubernetes, считайте это сетью для virtualserver-адресов в IPVS)


Скрытый текст

strict arp включён:


echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

но на MetalLB он не влияет.


(вывод изменён)


# ip addr
1: bond0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP group default qlen 1000
    link/ether 94:f1:28:c6:87:39 brd ff:ff:ff:ff:ff:ff
    inet 10.10.130.182/16 brd 10.10.255.255 scope global bond0

2: kube-dummy-if: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/ether 22:71:5f:ff:3a:05 brd ff:ff:ff:ff:ff:ff
    inet 1.2.3.4/32 brd 1.2.3.4 scope link kube-dummy-if
       valid_lft forever preferred_lft forever
    inet 10.96.221.9/32 brd 10.96.221.9 scope link kube-dummy-if
       valid_lft forever preferred_lft forever
    inet 10.96.113.129/32 brd 10.96.113.129 scope link kube-dummy-if
       valid_lft forever preferred_lft forever

3: bond0.100@bond0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP group default qlen 1000
    link/ether 94:f1:28:c6:87:39 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::96f1:28ff:fec6:8739/64 scope link 
       valid_lft forever preferred_lft forever

4: kube-bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 5e:79:2d:c4:d3:e9 brd ff:ff:ff:ff:ff:ff
    inet 10.113.63.1/24 scope global kube-bridge
       valid_lft forever preferred_lft forever
    inet6 fe80::5c79:2dff:fec4:d3e9/64 scope link 
       valid_lft forever preferred_lft forever

5: veth11694f93@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master kube-bridge state UP group default 
    link/ether e2:66:16:a9:fd:25 brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::e066:16ff:fea9:fd25/64 scope link 
       valid_lft forever preferred_lft forever
6: vethe332a950@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master kube-bridge state UP group default 
    link/ether e6:1b:9a:1b:d8:a2 brd ff:ff:ff:ff:ff:ff link-netnsid 5
    inet6 fe80::e41b:9aff:fe1b:d8a2/64 scope link 
       valid_lft forever preferred_lft forever

# ipvsadm -L -n
TCP  10.96.113129:9000 rr
  -> 10.112.58.28:9000            Masq    1      0          0      
TCP  10.96.221.9:80 rr
  -> 10.112.147.25:80             Masq    1      0          0         
  -> 10.113.14.200:80             Masq    1      0          0         
  -> 10.113.63.39:80              Masq    1      0          0     
TCP  1.2.3.4:80 rr
  -> 10.112.147.25:80             Masq    1      0          0         
  -> 10.113.14.200:80             Masq    1      0          0         
  -> 10.113.63.39:80              Masq    1      0          0     

Таблица маршрутизации внутри кластера сторится с помощью kube-router (BGP):


# ip route
# дефолтный гейтвей во внутренней сети
default via 10.10.0.1 dev bond0 proto static
# маршрут в локальный контейнер
10.113.63.0/24 dev kube-bridge proto kernel scope link src 10.113.63.1 
# маршруты к контейнерам на других нодах
10.113.14.0/24 via 10.10.130.1 dev bond0 proto 17 
10.113.14.0/24 via 10.10.130.1 dev bond0 proto 17
10.113.58.0/24 via 10.10.130.186 dev bond0 proto 17

есть также vlan интерфейс с внешней сеткой


  • bond0.100 (1.2.3.0/24)

Особенность MetalLB в том что он кофигурит роутинг от слова "никак", то есть механика его работы заключается тупо в том, чтобы в нужный момент добавить внешний 1.2.3.4/32 адрес на ноду.
Соответсвенно все роуты должны должны быть настроенны на ноде заранее, включая роут во внешнюю подсеть, т.к. нода не имеет IP-адреса из таковой.


задача:


  1. Настроить чтобы ответ с source ip 1.2.3.0/24 уходил через bond0.100 (по умолчанию он, ожидаемо, идёт в default gateway внутренней сети)
  2. В тоже время нужно оставить возможность обращаться из контейнеров к внешней подсети 1.2.3.0/24, эти пакеты не должны уходить через bond0.100, а должны попадать на ноду, чтобы быть отмаршрутизированными в друие контейнеры средствами IPVS.

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


ip rule add from 1.2.3.0/24 lookup 100

и это работает даже без переключения rp_filter


то со второй задачей возникает проблема:
когда контейнеры генерируют пакеты к 1.2.3.4 они уходят в bond0.100, а должны попадать на dummy интерфейс чтобы быть перенаправленными через IPVS

Не согласен, MetalLB — это просто софт который решает конкретную задачу, к слову он и BGP-роуты анонсить может.


Основная задача которую он решает: выдача ExternalIP-адресов LoadBalancer-сервисам.


Вариант с L2 более специфичен, но при должном подходе остаётся достаточно востребованным даже в больших кластерах как наш.

Я ничуть не спорю, BGP хорошо, и я с радостью юзал бы его, но так вышло, что у нас такая топология сети. Основное преимущество же заключалось в том что стоимость L2-оборудования значительно ниже чем умного L3.


И да, BGP решит проблему настройки роутинга, но не спасёт вас от маркировки пакетов. Вам всегда придётся как-то выкручиваться если на вашей ноде более одного default gateway.

Ну kube-proxy и так sysctls правит и кучу iptables-правил генерит, с маркировкой и прочим винегретом, а если добавить к этому делу ещё CNI-планин, то вообще можно свихнуться:





BTW, мы перешли на kube-router в качестве CNI и service-proxy. Он активно юзает ipset, так что это уже не выглядит так страшно.


Что касается правил и настройки маршрутизации для MetalLB, это всего-лишь небольшой скрипт запускающийся как init-контейнер для спикеров MetalLB, это небольшая плата за возможность автоматически выдавать внешние IP-адреса через Kubernetes.

У MetalLB есть два режима работы: Layer2 и BGB.


  • BGP решает проблему маршрутизации при доставке IP-адреса на ноду, но требут поддержки BGP со стороны вашей сети.
    В нашем случае это плоская L2-сеть которая доставляется на ноду обычным VLAN.


  • Layer2 можно сравнить с тем, как работает VRRP. Но в отличии от VRRP преимущество данного подхода заключается в том, что изначально ноды не имеют назначенных публичных IP-адресов, а получают их только в момент присвоения адреса MetalLB.



Интересный факт, что полученный IP-адрес является виртуальным (его не видно в выводе ip addr). Но побочным эфектом от этого, что маршрутизация для этого IP-адреса осуществляется только в рамках запущенного workload.


То есть имея адрес, назначенный таким образом, попасть на ноду невозможно, а на ваш workload всегда пожалуйста. Это валидно для IPVS, но не уверен что это будет работать также, если kube-proxy настроен в режиме iptables, т.к. не проверял.

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

Если использовать externalTrafficPolicy=Local то IP-адрес клиента передаётся в workload без изменений это работает из коробки like a charm.


Подробности: https://kubernetes.io/docs/tutorials/services/source-ip/

Тоже люблю TreeStyleTab, в дополнение к нему использую Dustman, расширение которое автоматически закрывает вкладки если я на них не вернулся в течении некоторого времени

Information

Rating
Does not participate
Location
Чехия
Works in
Registered
Activity