All streams
Search
Write a publication
Pull to refresh
194
0
Andrei Kvapil @kvaps

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

Send message
Дальше, конейнеры локальные или трафик через 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, расширение которое автоматически закрывает вкладки если я на них не вернулся в течении некоторого времени

Хороший вопрос, на данный момент вручную, но в 12.7 обещают сделать возможность генерировать пайплайн динамически:
https://gitlab.com/gitlab-org/gitlab/issues/16094

А если добавить туда ещё мобильную акустику и аккумулятор помощнее, то получится просто бомба для вылазок с друзьями на природу :)

Неплохая идея, возьму на вооружение!

Как сделать хорошо?
Нужно сделать плохо, а затем вернуть как было...

Спасибо за отзыв, меня тоже смутил данный недостаток, видимо теперь тоже подожду с покупкой.


ИМХО, Fn+стелочки — лучшее решение для размещения Home, End, PgUp, PgDown.
Вот нафига делать их отдельными кнопками да ещё и в таком неудобном месте?

Если напрягает проприетарность, то надо не тащить в систему тонны мусора, а запускать программу в chroot и прочих «изоляторах».

А разве snap не запускает пакеты в chroot?

Да ну, какая императивность? — что мешает описать все ваши шаблоны и объекты мониторинга в виде нескольких yaml-файлов? Применять их можно в любом порядке, с ними легко работать, их можно версионировать, хранить в vcs, следить за изменениями и работать с ними в разных окружениях.
Что не так-то?

Ну не сказать, и snap и appimage оба вполне юзабельны, особенно если автор не хочет раскрывать исходники, но хочет предоставить гарантировано рабочую копию для любого дистрибутива.
Лично я предпочту установить spotify или skype в snap нежели обычными пакетами в виду своей проприетарности.

Information

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