Комментарии 6
А не смотрели на менее велосипедные решения? Типа https://github.com/telepresenceio/telepresence Сейчас возникла похжая необходимость и как раз думаю собирать свой велосипед или найти готовый
На telepresense смотрели в контексте локальной разработки, а не поднятия распределенного стенда.
Но в итоге используем devspace и skaffold для синхронизации кода с локальной машины в Pod
https://github.com/loft-sh/devspace - для фронтенд приложений
https://skaffold.dev/ - для java сервисов
Так мы получим доступ к приложениям, запущенным в Kubernetes без использования NodePort, LoadBalancer и Ingress Controller.
Шаг 4. Почти всё
...
nodePort: 32053
Шаг 5. Финальный
...
Дополнительно на стенде установлен nginx, работающий как tcp proxy
podCIDR: 10.244.XXX.0/YY
...
мы делаем для стендов блоки /28, резервируя только 16 адресов на каждый стенд
...
Сегодня на стенде запущено ~60 контейнеров
Выводы
Это, слегка костыльное, решение
kube-proxy: mode: "ipvs" + статическая маршрутизация == вся статья
Возможно, делаю неверные выводы из цитирования, но
Nodeport выставлен только для coredns, а не для приложений в кластере, формально, да, 1 дополнительный сервис нужен.
60 контейнеров пока по-прежнему работает на стенде, ещё около 100-120 для каждого стенда запущено в кластере. Те, что запущены на стенде, используют адреса из подсети 172.17.0.0/24
С учётом того, что стендов достаточно много (200+), статическая маршрутизация выглядит не очень удобным решением, на мой взгляд
Правите конфиг kube-proxy: mode: "ipvs". На каждой ноде куба появляется интерфейс kube-ipvs0 со всеми ip сервисов. Т.е. все кубо-сервисы доступны по этим ip на любой ноде куба.
Добавляете на своем маршрутизаторе маршрут до servceCIDR указав шлюзом любую ноду куба, ipvs с flannel разберутся сами (у меня ещё OSPF был чтобы можно было не писать маршруты до podCIDR нод, дает возможность ходить напрямую в нужный pod)
> nslookup kubernetes.default.svc.cluster.local `k -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}'`
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: kubernetes.default.svc.cluster.local
Address: 10.96.0.1
> echo 'nameserver 10.96.0.10' >> /etc/resolv.conf
> ping kubernetes.default.svc.cluster.local
PING kubernetes.default.svc.cluster.local (10.96.0.1): 56 data bytes
64 bytes from 10.96.0.1: icmp_seq=0 ttl=64 time=7.359 ms
64 bytes from 10.96.0.1: icmp_seq=1 ttl=64 time=8.558 ms
64 bytes from 10.96.0.1: icmp_seq=2 ttl=64 time=10.363 ms
64 bytes from 10.96.0.1: icmp_seq=3 ttl=64 time=5.093 ms
^C
--- 10.96.0.1 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 5.093/7.843/10.363/1.914 ms
стенды ходят в сервисы, поды ходят куда направите. Можно смапить внешний сервис через Service без селектора с Endpoints или externalName
Nginx и flannel на стендах больше не нужен
Давайте я попробую ответить.
Добавляете на своем маршрутизаторе маршрут до servceCIDR указав шлюзом любую ноду куба, ipvs с flannel разберутся сами (у меня ещё OSPF был чтобы можно было не писать маршруты до podCIDR нод, дает возможность ходить напрямую в нужный pod)
Тут появляется первая проблема - доступ к сетевому оборудованию и встраивание внутренних сетей стендов в ЛВС организации. Кластерные сети становятся маршрутизируемыми напрямую, хотя необходимости ходить по этим адресам отдельно от связки "тестовый стенд - кластер" нет. При наличии нескольких кластеров (а мы хотим иметь возможность делать их в любом нужном нам количестве и убивать так же) требуется выделение отдельных подсетей под них, согласование сетевого плана с сетевиками и безопасниками. Маршрутизатор в общем случае может быть не один, сеть распределенной, а сетевые инженеры работать в другом подразделении и не гореть желанием следить еще и за тестовым трафиком, который начнет ходить по рабочим сетям. Вместо поднятия одного сервиса и построения оверлейной сети поверх существующей, получаем много дополнительной работы.
Вторая проблема: мы хотим поднимать на самом стенде сервисы на отдельных IP, которые будут доступны из кластера. В случае с flannel мы можем получить "внутреннюю" сеть внутри стенда с доступными для подов адресами, не плодя адреса на внешнем интерфейсе стенда и не решая вопрос маршрутизации из кластера на стенд (если решаем делать "внутренние адреса" по аналогии с кластерной сетью, и статикой тут уже не обойдется).
Третья проблема: "любая" нода куба - единая точка отказа, так что придется решать вопросы с отказоустойчивостью этого маршрута, значит, там уже точно не статика будет, а bgp, bfd и т.п.
Зачем это все, если не стоит цели поиграться с сетями? Ради того, чтобы не запускать flannel на стенде, которая делает все, что требуется для решения задачи, сразу из коробки?
Nginx и flannel на стендах больше не нужен
Nginx на стенде нужен с единственной целью - сделать единую точку входа в сервис, который мы хотим переключать в режим разработки и выносить из кластера на сам стенд. Вместо деплоя конфигов всех сервисов, в которых пришлось бы менять endpoint, при переносе сервиса в кластер включается только прокси в nginx, на месте которого можно поставить что угодно - от haproxy до ipvs или nat в iptables. Можно и через DNS этот вопрос решить, но в данном случае стоит задача подстроиться под готовый проект, а не перекроить в том числе и прод для того, чтобы было удобно стенды делать
Запуск Flannel & kube-proxy отдельно от кластера