Вопросы производительности для NodePort, ClusterIP и Headless Service в Kubernetes

У нас есть два типа сервисов, которые мы запускаем на AWS EKS:

  • внешние сервисы, которые мы предоставляем через балансировщик нагрузки на уровне приложения, используя aws-alb-ingress-controller
  • внутренние службы, которые мы используем как напрямую через имя службы (для приложений EKS), так и через внутренний балансировщик нагрузки на уровне приложения, также используя aws-alb-ingress-controller (для приложений, отличных от EKS)

Я хотел бы понять, как влияет на производительность выбор Nodeport, ClusterIP или Headless Service как для внешних, так и для внутренних служб. У меня настройка работает со всеми тремя вариантами.

Если я правильно понимаю сеть, кажется, что безголовый сервис требует меньше прыжков и, следовательно, будет (немного) быстрее? Однако в этой статье предполагается, что при прямом вызове Headless Service не будет правильно сбалансирована нагрузка. Это правильно? И сохранится ли это при вызове через внешний (или внутренний) ALB?

Есть ли разница в производительности для NodePort и ClusterIP?

Наконец, каков наиболее элегантный / производительный способ использования внутренних сервисов вне кластера (где у нас нет доступа к Kubernetes DNS), но в том же VPC? Можно ли было бы использовать ClusterIp и указать IP-адрес в определении службы, чтобы он оставался стабильным? Или есть варианты получше?

3 ответа

Решение

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

Если я правильно понимаю сеть, кажется, что Headless Service требует меньше прыжков и, следовательно, будет (немного) быстрее?

Не существенно быстрее. "Дополнительный переход" - это пакет, проходящий по локальным таблицам поиска, который он все равно проходит, так что разница не заметна. Отсек назначения по-прежнему будет находиться на том же количестве фактических сетевых переходов.

Если у вас есть тысячи служб, которые работают на одном модуле и могут быть безголовыми, вы можете использовать это для ограничения количества правил NAT iptables и ускорения обработки правил (см. Iptables v ipvs ниже).

Правильно ли <автономная служба не сбалансирована нагрузка>? И сохранится ли это при вызове через внешний (или внутренний) ALB?

Да, это правильно, клиент (или ALB) должен будет реализовать балансировку нагрузки между IP-адресами Pod.

Есть ли разница в производительности для NodePort и ClusterIP?

У NodePort есть возможный дополнительный сетевой переход от узла входа к узлу, на котором запущен модуль. Предполагая, что диапазоны ClusterIP маршрутизируются на правильный узел (и маршрутизируются вообще)

Если вы используете тип службы: LoadBalancer это поведение можно изменить, установив [.spec.externalTrafficPolicy к Local] [ https://kubernetes.io/docs/concepts/services-networking/service/, что означает, что трафик будет направляться только на локальный модуль.

Наконец, каков наиболее элегантный / производительный способ использования внутренних служб извне кластера.

Я бы сказал, что используйте AWS ALB Ingress Controller сalb.ingress.kubernetes.io/target-type: ipаннотация. Конфигурация k8s из кластера будет отправлена ​​в ALB через входной контроллер и модули адресов напрямую, без пересылки соединений или дополнительных переходов. Все перенастройки кластера будут автоматически удалены.

Существует небольшая задержка для конфигурации, чтобы добраться до ALB по сравнению с кластером kube-proxyреконфигурация. Что-то вроде скользящего развертывания может быть не таким плавным, поскольку обновления поступают после того, как модуль исчез. В конце концов, ALB способны справиться с отключением самостоятельно.

Перенаправление подключений Kubernetes

E сть kube-proxyпроцесс, запущенный на каждом узле, который управляет тем, как и куда пересылаются соединения. Есть 3 варианта, какkube-proxyделает это: прокси пользовательского пространства, iptables или IPVS. Большинство кластеров будут на iptables, и это будет обслуживать подавляющее большинство случаев использования.

Прокси-сервер в пользовательском пространстве

Пересылка осуществляется через процесс, который выполняется в пользовательском пространстве для завершения и перенаправления соединений. Это медленно. Вряд ли вы им пользуетесь, не используйте.

iptables

iptables перенаправляет соединения в ядре через NAT, что очень быстро. Это наиболее распространенная настройка, охватывающая 90% случаев использования. Новые соединения равномерно распределяются между всеми узлами, на которых работают модули службы.

IPVS

Работает в ядре, быстро и масштабируемо. Если вы переключаете трафик на большое количество приложений, это может улучшить производительность пересылки. Он также поддерживает различные режимы балансировки нагрузки службы:

- rr: round-robin
- lc: least connection (smallest number of open connections)
- dh: destination hashing
- sh: source hashing
- sed: shortest expected delay
- nq: never queue

Доступ к услугам

Мои объяснения основаны на iptables, поскольку я еще не проделал много детальной работы с кластерами ipvs. Я собираюсь отказаться от сложности ipvs и сказать, что она в основном такая же, как и iptables, только с более быстрой обработкой правил, поскольку количество правил увеличивается на огромных кластерах (то есть количество модулей / служб / сетевых политик).

Я также игнорирую прокси пользовательского пространства в описании из-за накладных расходов, просто не используйте его.

Главное, что нужно понять, это "Service ClusterIP" - это виртуальная конструкция в кластере, которая существует только как правило для того, куда должен идти трафик. Каждый узел поддерживает это сопоставление правил всех IP/ портов ClusterIP и PodIP/ портов (черезkube-proxy)

Nodeport

ALB направляет на любой узел. Узел / порт узла перенаправляет соединение модулю, обслуживающему службу. Это может быть удаленный модуль, который будет включать отправку трафика обратно по "проводу".

ALB> Wire > Node > Kernel Forward to SVC ( > Wire, если удаленный узел)> Pod

ClusterIP

Использование ClusterIP для прямого доступа зависит от диапазонов IP-адресов сервисного кластера, маршрутизируемых на правильный узел. Иногда они вообще не маршрутизируются.

ALB> Wire > Node > Kernel Forward to SVC > Pod

Шаг "Перенаправление ядра в SVC" можно пропустить с помощью аннотации ALB без использования автономной службы.

Безголовый сервис

Опять же, IP-адреса Pod не всегда могут быть адресованы извне кластера в зависимости от настройки сети. У вас все должно быть хорошо на EKS.

ALB> провод> Узел> Стручок

Запись

Я добавлю к этому суффиксу запросы, которые, вероятно, будут иметь дополнительную задержку < 1 мс, если соединение перенаправляется на узел в VPC. Расширенные сетевые экземпляры на нижнем уровне. Связь между зонами доступности может быть немного выше, чем внутри зоны доступности. Если у вас есть географически разделенный кластер, это может повысить важность управления потоком трафика. Например, наличие туннельной сети из ситца, которая фактически перепрыгнула через несколько реальных сетей.

Безголовый сервис не будет иметь никакой балансировки нагрузки на уровне L4, но если вы используете его за ALB, вы получите балансировку нагрузки на уровне L7.

Nodeport внутренне использует IP-адрес кластера, но потому что ваш запрос может случайным образом перенаправляться на модуль на другом хосте, тогда как он мог быть направлен на модуль на том же хосте, избегая этого дополнительного перехода в сеть. Nodeport - плохая идея для производственного использования.

IMHO лучший способ получить доступ к внутренним сервисам извне кластера будет использовать ingress.

Вы можете использовать nginx в качестве контроллера входа, где вы развертываете контроллер входа nginx в своем кластере и предоставляете его через службу типа LoadBalancer с помощью ALB. Затем вы можете настроить маршрутизацию на основе пути или хоста с помощью входящего API для маршрутизации трафика между внутренними службами Kubernetes.

каков наиболее элегантный / производительный способ использования внутренних служб за пределами кластера (где у нас нет доступа к Kubernetes DNS), но в том же VPC?

Для этого, я думаю, вам следует взглянуть на Service Mesh. Например, Istio ( https://istio.io/). Он обрабатывает ваши внутренние служебные вызовы вручную, поэтому вызов не должен проходить через Kubernetes DNS. Пожалуйста, посмотрите документацию Istio (https://istio.io/docs) для получения дополнительной информации.

Также вы можете взглянуть на Istio на EKS (https://aws.amazon.com/blogs/opensource/getting-started-istio-eks)

Другие вопросы по тегам