Вопросы производительности для NodePort против ClusterIP или безголового сервиса в Kubernetes - PullRequest
2 голосов
/ 19 января 2020

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

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

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 19 января 2020

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

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

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

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

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

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

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

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

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

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

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

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

Переадресация Kubernetes *

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

прокси-сервер пользователя

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

iptables

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

IPVS

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

- 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, только с более быстрой обработкой правил, так как количество правил увеличивается на огромных кластерах (т. Е. Количество пакетов / служб / сетевых политик).

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

Базовая вещь, которую нужно понять c, - это «Service ClusterIP» - это виртуальная конструкция в кластере, которая существует только в качестве правила, для которого трафик c должен go. Каждый узел поддерживает это правило сопоставления всех ClusterIP / порта с PodIP / портом (через kube-proxy)

Nodeport

ALB-маршрутов к любому узлу. Узел / nodeport направляет соединение к модулю обработка сервиса. Это может быть удаленный модуль, который будет включать отправку traffi c через «провод».

ALB> провод> Узел> Переадресация ядра в SV C (> провод, если удаленный узел)> Под

ClusterIP

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

ALB> провод> Узел> Переадресация ядра в SV C> Pod

Шаг «Переадресация ядра в SV C» можно пропустить с аннотацией ALB без использования безголового сервиса.

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

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

ALB> wire> Node> Pod

Примечание

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

1 голос
/ 19 января 2020

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

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

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

1 голос
/ 19 января 2020

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

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

ИМХО лучший способ получить доступ к внутренним службам вне кластера будет использовать ingress .

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

...