Я исправил проблему, оказалось, что у меня была пара проблем в исходной конфигурации.
Во-первых, я не упомянул, какой у меня сетевой провайдер. Я использую weave-net, и получается, что, хотя в документации kubernetes говорится, что для сохранения исходного IP-адреса достаточно добавить externalTrafficPolicy: Local
в службу балансировки нагрузки, она не будет работать с weave-net, если вы не включите ее специально. Итак, в версии weave-net, которую я использую (2.5.1), вы должны добавить следующую переменную окружения в weave-net DeamonSet NO_MASQ_LOCAL=1
. Для получения более подробной информации обратитесь к их документации .
Честно говоря, после этого моя память немного размыта, но я думаю, что на этом этапе вы получаете кластер, в котором:
- Служба NodePort : не поддерживает сохранение исходного IP-адреса. Каким-то образом это работает на AWS, но не поддерживается на голом металле самим kubernetes, weave-net не виноват.
- Служба LoadBalancer на узле с IP X, привязанным к IP другого узла Y: не поддерживает сохранение исходного IP, поскольку трафик должен маршрутизироваться внутри сети kubernetes.
- Служба LoadBalancer на узле с IP-адресом X, связанным с тем же IP-адресом X: Я не помню четко, но я думаю, что это работает.
Во-вторых, дело в том, что kubernetes из коробки не поддерживает настоящие сервисы LoadBalancer. Если вы решите придерживаться «стандартной» установки без каких-либо дополнительных действий, вам придется ограничить работу своих модулей только на узлах кластера, которым назначены LB-IP-адреса. Это делает управление кластером болью в заднице, поскольку вы становитесь очень зависимыми от конкретного расположения компонентов на узлах. Вы также теряете избыточность.
Чтобы решить вторую проблему, вам нужно настроить поставщика реализации балансировщика нагрузки для установки без изменений. Я лично использовал MetalLB . С его настройкой вы предоставляете службе балансировки нагрузки список виртуальных IP-адресов в том смысле, что они не привязаны к конкретному узлу. Каждый раз, когда kubernetes запускает модуль, который принимает трафик от службы LB; он присоединяет один из виртуальных IP-адресов к тому же узлу. Таким образом, IP-адрес LB всегда перемещается вместе с модулем, и вам никогда не придется направлять внешний трафик через сеть kubernetes. В результате вы получаете 100% сохранение исходного IP-адреса.