В Kubernetes Служба делает приложение, запущенное на наборе подов, доступным по сети. Она предоставляет постоянное имя DNS для этих подов и распределяет трафик между ними для балансировки нагрузки. Этот раздел описывает базовые концепции служб Kubernetes и предоставляет сравнение различных типов служб.
Вы можете создать определённый тип Сервиса в кластере. Описание и сценарии применения различных типов Сервисов приведены в таблице ниже.
Тип сервиса | Описание | Сценарий применения |
|---|---|---|
ClusterIP Сервисы являются типом сервисов Kubernetes по умолчанию. Они назначают виртуальный IP‑адрес, доступный только внутри кластера, из блока Service CIDR кластера. | Сервисы, которым необходимо общаться только внутри кластера и которые не требуется раскрывать за пределами кластера. Например, если pod фронтенд‑приложения в кластере должен получить доступ к базе данных бекенда в том же кластере, вы можете создать ClusterIP Service для базы данных бекенда, чтобы обеспечить доступ к базе данных бекенда только изнутри кластера. | |
NodePort Service открывает порт на каждом узле в кластере, позволяя внешнему трафику получать доступ к Service через <node-IP-address>:<node-port>. | Сценарии, когда требуется временный или низконагруженный доступ. Например, в тестовой среде вы можете использовать NodePort Service при развертывании и отладке веб‑приложения. | |
LoadBalancer Service добавляет внешний балансировщик нагрузки поверх NodePort Service и распределяет внешний трафик по нескольким pod внутри кластера. Он автоматически назначает внешний IP‑адрес, позволяя клиентам получить доступ. LoadBalancer Services обрабатывают трафик TCP и UDP на уровне 4 (транспортный слой) модели OSI. Их можно расширить для поддержки возможностей уровня 7 (прикладной слой), чтобы управлять трафиком HTTP и HTTPS. | Облачные приложения, требующие стабильной и простого в управлении точки входа для внешнего доступа. Например, в рабочей среде вы можете использовать LoadBalancer Services для публикации публичных сервисов, таких как веб‑приложения и API‑сервисы, в Интернет. Такие сервисы часто должны обрабатывать большой трафик, поддерживая высокую доступность. | |
Служба DNAT предоставляет Преобразование сетевых адресов (NAT) для всех узлов в кластере, чтобы несколько узлов могли совместно использовать EIP. | Сервисы, которые требуют временного или низкоёмкого доступа из Интернета. Службы DNAT обеспечивают более высокую надёжность по сравнению со службами NodePort. При использовании службы DNAT нет необходимости привязывать EIP к отдельному узлу, и запросы всё равно могут распределяться по рабочей нагрузке, даже если какой‑то из внутренних узлов недоступен. | |
Для headless Service не выделяется IP‑адрес кластера. Когда клиент пытается получить доступ к backend pod и выполняет DNS‑запрос к Service, он получает список IP‑адресов backend pod. Это позволяет клиенту напрямую взаимодействовать с отдельными pod. | Приложения, которым требуется прямое взаимодействие с конкретными backend pod вместо использования прокси или балансировщиков нагрузки. Например, при развертывании stateful‑приложения (например, базы данных ClickHouse) можно использовать headless Service. Он позволяет pod‑приложениям напрямую обращаться к каждому pod ClickHouse и выполнять целенаправленные операции чтения и записи. Это повышает общую эффективность обработки данных. |
Если аффинность службы Службы установлена на уровне узла, то есть значение externalTrafficPolicy равно Local, Служба может не быть доступна изнутри кластера (конкретно, узлы или контейнеры). Информация, похожая на следующую, отображается:
upstream connect error or disconnect/reset before headers. reset reason: connection failureOrcurl: (7) Failed to connect to 192.168.10.36 port 900: Connection refused
Часто происходит, что балансировщик нагрузки в кластере недоступен. Причина следующая: При создании Службы в Kubernetes, kube-proxy добавляет адрес доступа к балансировщику нагрузки в виде внешнего IP-адреса (External-IP, как показано в выводе команды) в iptables или IPVS. Если клиент внутри кластера инициирует запрос к балансировщику нагрузки, адрес считается внешним IP-адресом Службы, и запрос напрямую переадресуется kube-proxy, не проходя через балансировщик нагрузки за пределами кластера.
# kubectl get svc nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx LoadBalancer 10.247.76.156 123.**.**.**,192.168.0.133 80:32146/TCP 37s
Когда значение externalTrafficPolicy равно Local, сбои доступа в разных моделях сети контейнеров и режимах переадресации сервисов следующие:
Тип сервиса Выпущено на сервере | Тип доступа | Местоположение инициирования запроса на клиенте | Кластер туннельной сети (IPVS) | Кластер сети VPC (IPVS) | Кластер туннельной сети (iptables) | Кластер сети VPC (iptables) |
|---|---|---|---|---|---|---|
Сервис NodePort | Публичная/приватная сеть | Тот же узел, что и pod сервиса | Доступ к IP address и NodePort на узле, где находится сервер: Доступ успешен. Доступ к IP address и NodePort на любом узле, отличном от того, где находится сервер: Доступ не удался. | Доступ к IP address и NodePort на узле, где находится сервер: Доступ успешен. Доступ к IP address и NodePort на любом узле, отличном от того, где находится сервер: Доступ не удался. | Доступ к IP address и NodePort на узле, где находится сервер: Доступ успешен. Доступ к IP address и NodePort на любом узле, отличном от того, где находится сервер: Доступ не удался. | Доступ к IP address и NodePort на узле, где находится сервер: Доступ успешен. Доступ к IP address и NodePort на любом узле, отличном от того, где находится сервер: Доступ не удался. |
Разные узлы от service pod | Доступ к IP address и NodePort на узле, где находится сервер: Доступ успешен. Доступ к IP‑address и NodePort на другом узле: Доступ не удался. | Доступ к IP‑address и NodePort на узле, где расположен сервер: Доступ успешен. Доступ к частному IP‑address и NodePort на узле, где находится клиент: Доступ успешен. Доступ к публичному IP‑address и NodePort на узле, где запущен клиент: Доступ не удался. Доступ к IP‑address и NodePort на другом узле: Доступ не удался. | Доступ к IP‑address и NodePort на узле, где расположен сервер: Доступ успешен. Доступ к частному IP‑address и NodePort на узле, где находится клиент: Доступ успешен. Доступ к публичному IP‑address и NodePort на узле, где запущен клиент: Доступ не удался. Доступ к IP‑address и NodePort на другом узле: Доступ не удался. | Доступ к IP‑address и NodePort на узле, где расположен сервер: Доступ успешен. Доступ к частному IP-адресу и NodePort на узле, где находится клиент: Доступ выполнен успешно. Доступ к публичному IP-адресу и NodePort на узле, где работает клиент: Доступ не выполнен. Доступ к IP-адресу и NodePort на другом узле: Доступ не выполнен. | ||
Другие контейнеры на том же узле, что и сервисный pod | Доступ к IP-адресу и NodePort на узле, где расположен сервер: Доступ выполнен успешно. Доступ к IP-адресу и NodePort на любом узле, отличном от того, где расположен сервер: Доступ не выполнен. | Доступ к публичному IP-адресу и NodePort на узле, где расположен сервер: Доступ выполнен успешно. Доступ к частному IP-адресу и NodePort на узле, где расположен сервер: Доступ не выполнен. Доступ к IP-адресу и NodePort на любом узле, отличном от того, где расположен сервер: Доступ не выполнен. | Доступ к IP-адресу и NodePort на узле, где расположен сервер: Доступ выполнен успешно. Получить доступ к IP-адресу и NodePort на любом узле, отличном от того, где находится сервер: Доступ не выполнен. | Получить доступ к публичному IP-адресу и NodePort на узле, где находится сервер: Доступ выполнен успешно. Получить доступ к приватному IP-адресу и NodePort на узле, где находится сервер: Доступ не выполнен. Получить доступ к IP-адресу и NodePort на любом узле, отличном от того, где находится сервер: Доступ не выполнен. | ||
Другие контейнеры на разных узлах от service pod | Получить доступ к IP-адресу и NodePort на узле, где находится сервер: Доступ выполнен успешно. Получить доступ к приватному IP-адресу и NodePort на узле, где находится клиент: Доступ выполнен успешно. Получить доступ к IP-адресу и NodePort на другом узле: Доступ не выполнен. | Получить доступ к IP-адресу и NodePort на узле, где находится сервер: Доступ выполнен успешно. Получить доступ к приватному IP-адресу и NodePort на узле, где находится клиент: Доступ выполнен успешно. Доступ к IP-адресу и NodePort на другом узле: Доступ не выполнен. | Доступ к IP-адресу и NodePort на узле, где расположен сервер: Доступ выполнен успешно. Доступ к IP-адресу и NodePort на любом узле, отличном от того, где расположен сервер: Доступ не выполнен. | Доступ к IP-адресу и NodePort на узле, где расположен сервер: Доступ выполнен успешно. Доступ к IP-адресу и NodePort на любом узле, отличном от того, где расположен сервер: Доступ не выполнен. | ||
LoadBalancer Service использует общий балансировщик нагрузки | Приватная сеть | Тот же узел, что и service pod | Доступ не выполнен. | Доступ не выполнен. | Доступ не выполнен. | Доступ не выполнен. |
Другие контейнеры на том же узле, что и service pod | Доступ не выполнен. | Доступ не выполнен. | Не удалось получить доступ. | Не удалось получить доступ. | ||
LoadBalancer Service, использующий выделенный балансировщик нагрузки (Local), для соединения с NGINX Ingress Controller | Приватная сеть | Тот же узел, что и cceaddon-nginx-ingress-controller pod | Не удалось получить доступ. | Не удалось получить доступ. | Не удалось получить доступ. | Не удалось получить доступ. |
Другие контейнеры на том же узле, что и cceaddon-nginx-ingress-controller pod | Не удалось получить доступ. | Не удалось получить доступ. | Не удалось получить доступ. | Не удалось получить доступ. |
Можно использовать следующие методы для решения этой проблемы:
Предположим, что имя Service равно my-service и он находится в default пространстве имён. Пример команды kubectl выглядит следующим образом:
kubectl patch service my-service -n default --type='merge' -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'