Облачная платформаAdvanced

Обзор Service

Язык статьи: Русский
Показать оригинал
Страница переведена автоматически и может содержать неточности. Рекомендуем сверяться с английской версией.

В Kubernetes Service делает приложение, запущенное на наборе pod, доступным по сети. Он предоставляет постоянное DNS-имя для этих pod и распределяет трафик между ними для балансировки нагрузки. В этом разделе описываются основные концепции Kubernetes Service и приводится сравнение различных типов Service.

Типы Service

Вы можете создать указанный тип Service в кластере. Описание и сценарии применения различных типов Service перечислены в таблице ниже.

Тип Service

Описание

Применение

ClusterIP

ClusterIP Service являются типом Service по умолчанию в Kubernetes. Они назначают виртуальный IP‑адрес, доступный только внутри кластера, из блока Service CIDR кластера.

Service, которые необходимо лишь взаимодействовать друг с другом внутри кластера и не требуют экспозиции за пределами кластера.

Например, если pod фронтенд‑приложения в кластере должен получить доступ к базе данных бекенда в том же кластере, вы можете создать ClusterIP Service для базы данных бекенда, чтобы обеспечить доступ к базе данных бекенда только внутри кластера.

NodePort

A NodePort Service opens a port on each node in a cluster to allow external traffic to access the Service through <node-IP-address>:<node-port>.

Сценарии, когда требуется временный или низкообъёмный доступ.

Например, в тестовой среде вы можете использовать сервис NodePort при развертывании и отладке веб‑приложения.

LoadBalancer

Сервис LoadBalancer добавляет внешний балансировщик нагрузки поверх сервиса NodePort и распределяет внешний трафик между несколькими pod‑ами в кластере. Он автоматически назначает внешний IP‑адрес, чтобы обеспечить доступ клиентам. Сервисы LoadBalancer обрабатывают трафик TCP и UDP на уровне 4 (транспортный уровень) модели OSI. Их можно расширить для поддержки возможностей уровня 7 (уровень приложений) для управления трафиком HTTP и HTTPS.

Облачные приложения, которым требуется стабильная и простая в управлении точка входа для внешнего доступа.

Например, в производственной среде вы можете использовать сервисы LoadBalancer для публикации публичных сервисов, таких как веб‑приложения и API‑сервисы, в Интернет. Такие сервисы часто должны обрабатывать большой объём трафика, обеспечивая высокую доступность.

DNAT

Сервис DNAT предоставляет Network Address Translation (NAT) для всех узлов в кластере, чтобы несколько узлов могли использовать общий EIP.

Сервисы, которым требуется временный или низкообъёмный доступ из Интернета. Сервисы DNAT обеспечивают более высокую надёжность, чем сервисы NodePort. При использовании сервиса DNAT нет необходимости привязывать EIP к отдельному узлу, и запросы всё равно могут распределяться между рабочими нагрузками, даже если один из узлов выходит из строя.

Headless Services

Для безголовых сервисов (headless Services) IP‑адрес кластера не выделяется. Когда клиент пытается обратиться к backend‑pod и выполняет DNS‑запрос к Сервису, он получает список IP‑адресов backend‑pod‑ов. Это позволяет клиенту напрямую взаимодействовать с отдельными pod‑ами.

Приложения, которым требуется прямое взаимодействие с конкретными backend‑pod, вместо использования прокси‑серверов или балансировщиков нагрузки.

Например, при развертывании stateful‑приложения (например, базы данных ClickHouse) можно использовать безголовый сервис. Он позволяет pod‑ам приложения напрямую обращаться к каждому pod‑у ClickHouse и выполнять целенаправленные операции чтения и записи. Это повышает общую эффективность обработки данных.

Почему Service недоступен изнутри кластера

Если привязка сервиса Service установлена на уровень узла, то есть значение externalTrafficPolicy равно Local, Service может стать недоступным изнутри кластера (конкретно, узлы или контейнеры). Отображается информация, аналогичная следующей:

upstream connect error or disconnect/reset before headers. reset reason: connection failure
Or
curl: (7) Failed to connect to **.**.**.** port 900: Connection refused
Or
curl: (28) Failed to connect to **.**.**.** port 1122: Connection timed out

Часто бывает, что балансировщик нагрузки в кластере недоступен. Причина следующая: когда Kubernetes создает Service, kube-proxy добавляет адрес доступа к балансировщику нагрузки в виде внешнего IP-адреса (External-IP, как показано в выводе команды) в iptables или IPVS. Если клиент внутри кластера инициирует запрос к балансировщику нагрузки, этот адрес рассматривается как внешний IP-адрес Service, и запрос напрямую перенаправляется kube-proxy, минуя балансировщик нагрузки за пределами кластера.

# kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.247.76.156 123.**.**.**,192.168.0.133 80:32146/TCP 37s

Когда значение externalTrafficPolicy равно Local, сбои доступа в разных моделях сетей контейнеров и режимах переадресации Service выглядят следующим образом:

Note
  • Для многоподовой рабочей нагрузки убедитесь, что все pod доступны. В противном случае существует вероятность, что доступ к рабочей нагрузке будет невозможен.
  • В таблице перечислены только сценарии, при которых доступ может быть невозможен. Другие сценарии, не указанные в таблице, означают, что доступ работает нормально.
  • Для кластеров CCE, использующих IPVS, установите externalTrafficPolicy в Local для привязки Service на уровне узла. Для кластеров CCE Turbo с отключенным DataPlane V2 поддержка привязки на уровне узла возможна только когда бэкенд Service использует hostNetwork.
    • Тип Server Service

      Тип доступа

      Источник запросов клиента

      Кластер Tunnel Network

      Кластер VPC Network (DataPlane V2 отключен. Если включен, см. Clusters with DataPlane V2 Enabled.)

      Кластер CCE Turbo (DataPlane V2 отключен. Если включен, см. Clusters with DataPlane V2 Enabled.)

      NodePort Service

      Публичная/приватная сеть

      Тот же node, что и service pod

      Доступ через node IP + NodePort на server node: Успех

      Доступ через node IP + NodePort на non-server node: Ошибка

      Доступ через node IP + NodePort на server node: Успех

      Доступ через node IP + NodePort на non-server node: Ошибка

      Доступно

      Другой node, чем service pod

      Доступ через node IP + NodePort на server node: Успех

      Доступ через node IP + NodePort на другом node: Ошибка

      Доступ через node IP + NodePort на server node: Успех

      Доступ через node private IP + NodePort на client node: Успех

      Доступ через node EIP + NodePort на client node: Ошибка

      Доступ через node IP + NodePort на другом node: Ошибка

      Доступно

      Другие containers на том же node, что и service pod

      Доступ через node IP + NodePort на серверном узле: Success

      Доступ через node IP + NodePort на несерверном узле: Failure

      Доступ через node EIP + NodePort на серверном узле: Success

      Доступ через node private EIP + NodePort на серверном узле: Failure

      Доступ через node IP + NodePort на несерверном узле: Failure

      Accessible

      Другие контейнеры на другом узле, отличном от service pod

      Доступ через node IP + NodePort на серверном узле: Success

      Доступ через node private IP + NodePort на клиентском узле: Success

      Доступ через node IP + NodePort на другом узле: Failure

      Доступ через node IP + NodePort на серверном узле: Success

      Доступ через node private IP + NodePort на клиентском узле: Success

      Доступ через node IP + NodePort на другом узле: Failure

      Accessible

      LoadBalancer Service, использующий выделенный load balancer

      Приватная сеть

      Тот же узел, что и service pod

      Недоступно

      Недоступно

      Доступно

      Другие контейнеры на том же узле, что и service pod

      Недоступно

      Недоступно

      Доступно

  • Для кластеров CCE, использующих iptables, установите externalTrafficPolicy в Local для привязки Service на уровне узла. Для кластеров CCE Turbo with DataPlane V2 disabled, привязка на уровне узла поддерживается только когда бэкенд Service использует hostNetwork.
    • Server Service Type

      Access Type

      Client Request Source

      Tunnel Network Cluster

      VPC Network Cluster (DataPlane V2 отключён. Если включено, см. Clusters with DataPlane V2 Enabled.)

      CCE Turbo Cluster (DataPlane V2 отключён. Если включён, см. Clusters with DataPlane V2 Enabled.)

      NodePort Service

      Public/Private network

      Тот же узел, что и service pod

      Доступ через node IP + NodePort на серверном узле: Успешно

      Доступ через node IP + NodePort на узле, не являющемся сервером: Неудача

      Доступ через node IP + NodePort на серверном узле: Успешно

      Доступ через node IP + NodePort на узле, не являющемся сервером: Неудача

      Доступно

      Другой узел, чем service pod

      Доступ через node IP + NodePort на серверном узле: Успешно

      Доступ через node private IP + NodePort на клиентском узле: Успешно

      Доступ через node EIP + NodePort на клиентском узле: Неудача

      Доступ через node IP + NodePort на другом узле: Неудача

      Доступ через node IP + NodePort на серверном узле: Успешно

      Доступ через частный IP узла + NodePort на клиентском узле: Успешно

      Доступ через EIP узла + NodePort на клиентском узле: Не удалось

      Доступ через IP узла + NodePort на другом узле: Не удалось

      Доступно

      Другие контейнеры на том же узле, что и pod сервиса

      Доступ через IP узла + NodePort на серверном узле: Успешно

      Доступ через IP узла + NodePort на несерверном узле: Не удалось

      Доступ через EIP узла + NodePort на серверном узле: Успешно

      Доступ через частный EIP узла + NodePort на серверном узле: Не удалось

      Доступ через IP узла + NodePort на несерверном узле: Не удалось

      Доступно

      Другие контейнеры на другом узле, отличном от pod сервиса

      Доступ через IP узла + NodePort на серверном узле: Успешно

      Доступ через IP узла + NodePort на несерверном узле: Не удалось

      Доступ через IP узла + NodePort на серверном узле: Успешно

      Доступ через IP‑узла + NodePort на узле без сервера: Failure

      Accessible

      LoadBalancer Service с использованием dedicated load balancer

      Private network

      Тот же узел, что и service pod

      Inaccessible

      Inaccessible

      Accessible

      Другие контейнеры на том же узле, что и service pod

      Inaccessible

      Inaccessible

      Accessible

  • Для кластеров с включённым DataPlane V2 установите externalTrafficPolicy в Local для привязки Service на уровне узла.
    Note

    DataPlane V2 поддерживается только в кластерах CCE VPC-network и Turbo. После включения он полностью заменяет kube-proxy, устраняя необходимость настройки service forwarding mode.

    • Server Service Type

      Access Type

      Client Request Source

      VPC Network Cluster (DataPlane V2 Enabled to Replace kube-proxy)

      CCE Turbo Cluster (DataPlane V2 Enabled to Replace kube-proxy)

      NodePort Service

      Public/Private network

      Тот же узел, что и pod сервиса

      Доступ через IP узла + NodePort на серверном узле: Успех

      Доступ через частный IP узла + NodePort на несерверном узле: Успех

      Доступ через EIP узла + NodePort на несерверном узле: Неудача

      Доступ через IP узла + NodePort на серверном узле: Успех

      Доступ через частный IP узла + NodePort на несерверном узле: Успех

      Доступ через EIP узла + NodePort на несерверном узле: Неудача

      Другой узел, чем pod сервиса

      Доступ через IP узла + NodePort на серверном узле: Успех

      Доступ через частный IP-адрес узла + NodePort на узле без сервера: Success

      Доступ через EIP узла + NodePort на узле без сервера: Failure

      Доступ через IP-адрес узла + NodePort на серверном узле: Success

      Доступ через частный IP-адрес узла + NodePort на узле без сервера: Success

      Доступ через EIP узла + NodePort на узле без сервера: Failure

      Другие контейнеры на том же узле, что и service pod

      Доступ через IP-адрес узла + NodePort на серверном узле: Success

      Доступ через IP-адрес узла + NodePort на другом узле: Failure

      Доступ через IP-адрес узла + NodePort на серверном узле: Success

      Доступ через IP-адрес узла + NodePort на другом узле: Failure

      Другие контейнеры на другом узле, отличном от service pod

      Доступ через IP-адрес узла + NodePort на серверном узле: Success

      Доступ через частный IP-адрес узла + NodePort на клиентском узле: Success

      Доступ через IP-адрес узла + NodePort на другом узле: Failure

      Доступ через IP-адрес узла + NodePort на серверном узле: Success

      Доступ через приватный IP узла + NodePort на клиентском узле: Успешно

      Доступ через IP узла + NodePort на другом узле: Не удалось

      LoadBalancer Service с использованием выделенного балансировщика нагрузки

      Приватная сеть

      Тот же узел, что и service pod

      Недоступно

      Недоступно

      Другие контейнеры на том же узле, что и service pod

      Недоступно

      Доступно

Для решения этой проблемы можно использовать следующие методы:

  • (Рекомендуется) В кластере используйте ClusterIP Service или доменное имя сервиса для доступа.
  • Установите externalTrafficPolicy сервиса в значение Cluster, что означает аффинность сервиса на уровне кластера. Обратите внимание, что это влияет на постоянство исходного адреса.

    Предположим, что имя Service — my-service и оно находится в пространстве имён default. Пример команды kubectl приведён ниже:

    kubectl patch service my-service -n default --type='merge' -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
  • Используя функцию проброса (pass‑through) Service, kube-proxy обходится, когда для доступа используется адрес ELB. Сначала обращаются к балансировщику нагрузки ELB, а затем к рабочей нагрузке. Подробности см. в Configuring Passthrough Networking for a LoadBalancer Service.
    Note
    • В стандартном кластере CCE после настройки passthrough networking с использованием выделенного load balancer частный IP-адрес load balancer недоступен с узла, на котором находится pod рабочей нагрузки, или с других pod на том же узле, что и рабочая нагрузка.
    • Эта функция доступна только в кластерах версии v1.19 и новее.
    • В IPVS параметры passthrough для Services, подключённых к одному и тому же load balancer, должны быть одинаковыми.
    • Если используется привязка сервиса уровня узла (local), kubernetes.io/elb.pass-through автоматически устанавливается в onlyLocal для включения passthrough networking.