Я бы добавил к преимуществам низкое потребление ресурсов а как следствие и электроэнергнии, целый день ходить со включённым OpenVPN весьма накладно для использования батареи, а вот с Outline дело обстоит намного лучше.
LTO хорошо для долгосрочного бэкапа, а мы строили решение для оперативного.
В течении нескольких недель, бэкапы переписываются полностью. Восстановление из бэкапа может портребоваться в любой момент.
Спасибо за замечание, описал заветные опции в статье. (они так же были продублированны на картинке с бэнчмарком)
Что-то не подумал что телеграм может быть заблокирован на территории РФ.
Ох, ну если вам правда интересно, то изначальная задача была такая:
Имеется 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)
Таблица маршрутизации внутри кластера сторится с помощью 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-адреса из таковой.
задача:
Настроить чтобы ответ с source ip 1.2.3.0/24 уходил через bond0.100 (по умолчанию он, ожидаемо, идёт в default gateway внутренней сети)
В тоже время нужно оставить возможность обращаться из контейнеров к внешней подсети 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
Я ничуть не спорю, BGP хорошо, и я с радостью юзал бы его, но так вышло, что у нас такая топология сети. Основное преимущество же заключалось в том что стоимость L2-оборудования значительно ниже чем умного L3.
И да, BGP решит проблему настройки роутинга, но не спасёт вас от маркировки пакетов. Вам всегда придётся как-то выкручиваться если на вашей ноде более одного default gateway.
Ну kube-proxy и так sysctls правит и кучу iptables-правил генерит, с маркировкой и прочим винегретом, а если добавить к этому делу ещё CNI-планин, то вообще можно свихнуться:
BTW, мы перешли на kube-router в качестве CNI и service-proxy. Он активно юзает ipset, так что это уже не выглядит так страшно.
Что касается правил и настройки маршрутизации для MetalLB, это всего-лишь небольшой скрипт запускающийся как init-контейнер для спикеров MetalLB, это небольшая плата за возможность автоматически выдавать внешние IP-адреса через Kubernetes.
BGP решает проблему маршрутизации при доставке IP-адреса на ноду, но требут поддержки BGP со стороны вашей сети.
В нашем случае это плоская L2-сеть которая доставляется на ноду обычным VLAN.
Layer2 можно сравнить с тем, как работает VRRP. Но в отличии от VRRP преимущество данного подхода заключается в том, что изначально ноды не имеют назначенных публичных IP-адресов, а получают их только в момент присвоения адреса MetalLB.
Интересный факт, что полученный IP-адрес является виртуальным (его не видно в выводе ip addr). Но побочным эфектом от этого, что маршрутизация для этого IP-адреса осуществляется только в рамках запущенного workload.
То есть имея адрес, назначенный таким образом, попасть на ноду невозможно, а на ваш workload всегда пожалуйста. Это валидно для IPVS, но не уверен что это будет работать также, если kube-proxy настроен в режиме iptables, т.к. не проверял.
Спасибо за отзыв, смею с ним согласиться.
Но в моём кейсе обойтись простым ip rule не удалось, по этому пришлось маркировать пакеты и принимать решение о маршрутизации в зависимости от интерфейса на который они были получены.
Тоже люблю TreeStyleTab, в дополнение к нему использую Dustman, расширение которое автоматически закрывает вкладки если я на них не вернулся в течении некоторого времени
В предыдущем обзоре я уже упомянал о ней, но видимо во фланте её существование решили просто игнорировать :)
Странно что про go не сказано ни слова.
Я бы добавил к преимуществам низкое потребление ресурсов а как следствие и электроэнергнии, целый день ходить со включённым OpenVPN весьма накладно для использования батареи, а вот с Outline дело обстоит намного лучше.
LTO хорошо для долгосрочного бэкапа, а мы строили решение для оперативного.
В течении нескольких недель, бэкапы переписываются полностью. Восстановление из бэкапа может портребоваться в любой момент.
Спасибо за замечание, описал заветные опции в статье. (они так же были продублированны на картинке с бэнчмарком)
Что-то не подумал что телеграм может быть заблокирован на территории РФ.
Да, как-то упустил, использовалась дисковая полка Supermicro с Dual LSI SAS2X36 Expander
Спасибо за за дельное замечание, в скором времени будем тестировать новое хранилище, обязательно его учтём.
При тестировании minio iowait действительно был приличный, кстати, про то как работает minio тут недавно обсуждали.
gotop
Пардон, я не так выразился, я всего-лишь хотел сказать что правило
в моём случае не работало и вместо него выполнялось следующее попадающее под условие.
Разобрался, проблема оказалось в глупой ошибке, нужно использовать таблицу
main
, а неlocal
Теперь о хорошем, ваш метод работает:
где
10.112.0.0/12
— сеть подов в Kubernetes.Но правило to должно добавляться после, что бы имело наивысший приоритет.
Заметным плюсом данного подхода является также то что не нужно шаманить с rp_filter, всё и так работает с дефолтными настройками.
Огромное спасибо за содействие, я собираюсь обновить статью чтобы описать данный метод как рекомендованный.
Да всё верно, трафик из контейнеров может идти как локально из kube-bridge, так и с других нод через bond0.
Хорошая попытка, но к сожалению ip rule to у меня не заработало, как ни крути ответные пакеты всегда уходят в bond.100:
в не зависимости от того какие правила я добавил бы на ноду, последнее всегда стреляет:
Спасибо, вспоминается старый хабр, где читать коментарии порой было интереснее чем саму статью
Простой вопрос: как ещё можно пустить внешний трафик в кластер на ingress-контроллер, чтобы это было удобно и отказоусточиво?
А если таких ingress-контроллеров много?
Ох, ну если вам правда интересно, то изначальная задача была такая:
Имеется n физических нод, на каждой из них есть несколько интерфейсов и IPVS, скажем:
Котейнеры получают адреса из podSubnet: 10.112.0.0/12, на каждую ноду выделяется свой рейдж из этого диапазона.
Есть ещё serviceSubnet: 10.96.0.0/12 (специальная сеть для сервисов Kubernetes, считайте это сетью для virtualserver-адресов в IPVS)
strict arp включён:
но на MetalLB он не влияет.
(вывод изменён)
Таблица маршрутизации внутри кластера сторится с помощью kube-router (BGP):
есть также vlan интерфейс с внешней сеткой
Особенность MetalLB в том что он кофигурит роутинг от слова "никак", то есть механика его работы заключается тупо в том, чтобы в нужный момент добавить внешний
1.2.3.4/32
адрес на ноду.Соответсвенно все роуты должны должны быть настроенны на ноде заранее, включая роут во внешнюю подсеть, т.к. нода не имеет IP-адреса из таковой.
задача:
bond0.100
, а должны попадать на ноду, чтобы быть отмаршрутизированными в друие контейнеры средствами IPVS.если перая задача может быть легко решена дополнительной таблицей маршрутизации со своим gateway и правилом типа:
и это работает даже без переключения rp_filter
то со второй задачей возникает проблема:
когда контейнеры генерируют пакеты к 1.2.3.4 они уходят в bond0.100, а должны попадать на dummy интерфейс чтобы быть перенаправленными через IPVS
del
Не согласен, 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, расширение которое автоматически закрывает вкладки если я на них не вернулся в течении некоторого времени