IP-адрес источника пакета службы балансировки нагрузки Kubernetes

#networking #kubernetes #kubernetes-ingress

#сеть #kubernetes #kubernetes — вход

Вопрос:

У меня есть кластер версии kubernetes 1.13 (на данный момент один узел), настроенный на голом металле с помощью kubeadm. К узлу подключены 2 сетевых интерфейса для целей тестирования. В идеале, в будущем один интерфейс должен быть обращен к интрасети, а другой — к общедоступной сети. К тому времени количество узлов также будет больше единицы.

Для входа в интрасеть я использую диаграмму руля HAProxy ( https://github.com/helm/charts/tree/master/incubator/haproxy-ingress ) настройка с помощью этой конфигурации:

 rbac:
  create: true
serviceAccount:
  create: true
controller:
  ingressClass: "intranet-ingress"
  metrics:
    enabled: true
  stats:
    enabled: true
    service:
      type: LoadBalancer
      externalIPs:
        - 10.X.X.X # IP of one of the network interfaces
  service:
    externalIPs:
      - 10.X.X.X # IP of the same interface
  

Затем трафик достигает haproxy следующим образом:

 1. Client's browser, workstation has an IP from 172.26.X.X range 
   --local network, no NAT --> 
2. Kubernetes server, port 443 of HAProxy's load balancer service
   --magic done by kube-proxy, possibly NAT(which shoudn't have been here)-->
3. HAProxy's ingress controller pod
  

В журналах доступа HAProxy указан исходный IP-адрес версии 10.32.0.1. Это IP-адрес сетевого уровня kubernete. CIDR модуля Kubernetes равен 10.32.0.0/12. Однако мне нужен журнал доступа, чтобы показать фактический IP-адрес источника соединения.

Я попытался вручную отредактировать службу балансировки нагрузки, созданную HAProxy, и установить externalTrafficPolicy: Local . Это не помогло.

Как я могу получить исходный IP-адрес клиента в этой конфигурации?

Комментарии:

1. кто к чему подключается, когда вы видите эту проблему? Есть ли у вас балансировщик нагрузки перед haproxy?

2. @VasilyAngapov Я изменил вопрос. Теперь это отвечает на ваш вопрос?

3. Какой балансировщик нагрузки вы используете? Облако? Nginx? Обычно балансировщик нагрузки отвечает за отправку заголовка X-Forwarded-For по пути.

4. @VasilyAngapov У меня нет балансировщика нагрузки за пределами кластера Kubernetes. Я использую службу типа LoadBalancer, привязанную к внешнему IP-адресу. Который, в свою очередь, направляет трафик на HAProxy. Это не соответствует рекомендациям?

5. Что именно такое 10.32.0.1?

Ответ №1:

Я исправил проблему, оказывается, в исходной конфигурации было несколько проблем, которые у меня были.

Во-первых, я не упомянул, какой у меня сетевой провайдер. Я использую weave-net, и оказывается, что, хотя в документации kubernetes указано, что для сохранения исходного IP-адреса достаточно добавить externalTrafficPolicy: Local в службу балансировки нагрузки, она не будет работать с weave-net, если вы специально не включите ее. Итак, в версии weave-net, которую я использую (2.5.1), вы должны добавить следующую переменную среды в weave-net DeamonSet NO_MASQ_LOCAL=1 . Для получения более подробной информации обратитесь к их документации.

Честно говоря, после этого моя память немного нечеткая, но я думаю, что на этом этапе вы получаете кластер, в котором:

  • Служба портов узлов: не поддерживает сохранение исходного IP-адреса. Каким-то образом это работает на AWS, но не поддерживается на голом металле самим kubernetes, weave-net не виноват.
  • Служба балансировки нагрузки на узле, IP-адрес которого X привязан к IP-адресу другого узла Y: не поддерживает сохранение исходного IP-адреса, поскольку трафик должен маршрутизироваться внутри сети kubernetes.
  • Служба балансировки нагрузки на узле с IP X, привязанным к тому же IP X: Я не помню точно, но я думаю, что это работает.

Во-вторых, дело в том, что kubernetes из коробки не поддерживает настоящие службы балансировки нагрузки. Если вы решите придерживаться «стандартной» настройки без каких-либо дополнительных действий, вам придется ограничить запуск модулей только на узлах кластера, к которым привязаны IP-адреса LB. Это делает управление кластером занозой в заднице, поскольку вы становитесь очень зависимыми от конкретного расположения компонентов на узлах. Вы также теряете избыточность.

Для решения второй проблемы необходимо настроить поставщика реализации балансировки нагрузки для простой настройки. Я лично использовал MetalLB. Настроив его, вы предоставляете службе балансировки нагрузки список виртуальных IP-адресов в том смысле, что они не привязаны к определенному узлу. Каждый раз, когда kubernetes запускает модуль, который принимает трафик от службы LB; он присоединяет один из виртуальных IP-адресов к тому же узлу. Таким образом, IP-адрес LB всегда перемещается вместе с pod, и вам никогда не придется маршрутизировать внешний трафик через сеть kubernetes. В результате вы получаете 100% сохранение исходного IP-адреса.