В Kubernetes Service делает приложение, запущенное на наборе pod‑ов, доступным по сети. Он предоставляет постоянное DNS‑имя для этих pod‑ов и распределяет трафик между ними для балансировки нагрузки. В этом разделе описываются базовые концепции Kubernetes Service и приводится сравнение различных типов Service.
Вы можете создать указанный тип Service в кластере. Описание и сценарии применения различных типов Service перечислены в таблице ниже.
Тип Service | Описание | Сценарий применения |
|---|---|---|
ClusterIP Service являются типом Service по умолчанию в Kubernetes. Они назначают виртуальный IP‑адрес, доступный только внутри кластера, из блока Service CIDR кластера. | Service, которые необходимо лишь взаимодействовать друг с другом внутри кластера и не требуют экспозиции за пределами кластера. Например, если pod фронтенд‑приложения в кластере должен получить доступ к базе данных бекенда в том же кластере, вы можете создать ClusterIP Service для базы данных бекенда, чтобы обеспечить доступ к базе данных бекенда только внутри кластера. | |
NodePort Service открывает порт на каждом узле кластера, позволяя внешнему трафику получать доступ к Service через \u003cnode-IP-address\u003e:\u003cnode-port\u003e. | Сценарии, когда требуется временный или низкообъёмный доступ. Например, в тестовой среде вы можете использовать NodePort Service при развертывании и отладке веб‑приложения. | |
LoadBalancer Service добавляет внешний балансировщик нагрузки поверх NodePort Service и распределяет внешний трафик между несколькими pod‑ами в кластере. Он автоматически назначает внешний IP‑адрес, чтобы обеспечить доступ клиентам. LoadBalancer Services обрабатывают трафик TCP и UDP на уровне Layer 4 (транспортный уровень) модели OSI. При необходимости их можно расширить для поддержки возможностей Layer 7 (уровень приложений) для управления трафиком HTTP и HTTPS. | Облачные приложения, которым требуется стабильный, легко управляемый вход для внешнего доступа. Например, в производственной среде вы можете использовать LoadBalancer Services для публикации публичных сервисов, таких как веб‑приложения и API‑сервисы, в Интернет. Эти сервисы часто должны обрабатывать большой объём трафика, обеспечивая высокую доступность. | |
DNAT Service предоставляет Network Address Translation (NAT) для всех узлов в кластере, чтобы несколько узлов могли использовать общий EIP. | Сервисы, которым требуется временный или низкообъёмный доступ из Интернета. DNAT Services обеспечивают более высокую надёжность, чем NodePort Services. При использовании DNAT Service нет необходимости привязывать EIP к отдельному узлу, и запросы всё равно могут распределяться между рабочими нагрузками, даже если один из внутренних узлов недоступен. | |
Для headless Services IP‑адрес кластера не выделяется. Когда клиент пытается получить доступ к backend‑pod и выполняет DNS‑запрос к Service, он получает список IP‑адресов backend‑pod‑ов. Это позволяет клиенту напрямую взаимодействовать с отдельными pod‑ами. | Приложения, которым требуется прямое взаимодействие с конкретными backend‑pod, без использования прокси‑серверов или балансировщиков нагрузки. Например, при развертывании stateful‑приложения (например, базы данных ClickHouse) вы можете использовать headless Service. Он позволяет pod‑ам приложения напрямую обращаться к каждому pod‑у ClickHouse и выполнять целенаправленные операции чтения и записи. Это повышает общую эффективность обработки данных. |
Если привязка сервиса Service установлена на уровне узла, то есть значение externalTrafficPolicy равно Local, Service может быть недоступен изнутри кластера (конкретно, узлов или контейнеров). Отображается информация, аналогичная следующей:
Часто бывает, что load balancer в кластере недоступен. Причина следующая: когда Kubernetes создает Service, kube-proxy добавляет адрес доступа к load balancer в виде external IP address (External-IP, как показано в выводе команды) в iptables или IPVS. Если client внутри кластера инициирует запрос к load balancer, адрес рассматривается как external IP address Service, и запрос напрямую пересылается kube-proxy, минуя load balancer за пределами кластера.
# 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, сбои доступа в разных моделях сетей контейнеров и режимах переадресации service выглядят следующим образом:
Service Type Released on the Server | Access Type | Request Initiation Location on the Client | Tunnel Network Cluster (IPVS) | VPC Network Cluster (IPVS) | Tunnel Network Cluster (iptables) | VPC Network Cluster (iptables) |
|---|---|---|---|---|---|---|
NodePort Service | Public/Private network | Same node as the service pod | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, отличному от того, где расположен сервер: Доступ не выполнен. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, отличному от того, где расположен сервер: Доступ не выполнен. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, отличному от того, где расположен сервер: Доступ не выполнен. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, отличному от того, где расположен сервер: Доступ не выполнен. |
Разные узлы от service pod | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к другому узлу через его IP‑адрес и порт: Доступ не выполнен. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к узлу, где находится клиент, через частный IP‑адрес и порт узла: Доступ выполнен успешно. Доступ к узлу, где находится клиент, через публичный IP‑адрес и порт узла: Доступ не выполнен. Доступ к другому узлу через его IP‑адрес и порт: Доступ не выполнен. | Доступ к узлу, где находится сервер, через IP-адрес узла и порт: доступ выполнен успешно. Доступ к узлу, где находится клиент, через частный IP-адрес узла и порт: доступ выполнен успешно. Доступ к узлу, где находится клиент, через публичный IP-адрес узла и порт: доступ не выполнен. Доступ к другому узлу через его IP-адрес и порт: доступ не выполнен. | Доступ к узлу, где находится сервер, через IP-адрес узла и порт: доступ выполнен успешно. Доступ к узлу, где находится клиент, через частный IP-адрес узла и порт: доступ выполнен успешно. Доступ к узлу, где находится клиент, через публичный IP-адрес узла и порт: доступ не выполнен. Доступ к другому узлу через его IP-адрес и порт: доступ не выполнен. | ||
Другие контейнеры на том же узле, что и service pod. | Доступ к узлу, где находится сервер, через IP-адрес узла и порт: доступ выполнен успешно. Доступ к любому узлу через IP-адрес узла и порт, кроме того, где находится сервер: доступ не выполнен. | Доступ к узлу, где находится сервер, через публичный IP-адрес узла и порт: доступ выполнен успешно. Доступ к узлу, где находится сервер, через частный IP-адрес узла и порт: доступ не выполнен. Доступ к любому узлу через IP-адрес узла и порт, кроме того, где находится сервер: доступ не выполнен. | Доступ к узлу, где находится сервер, через IP-адрес узла и порт: доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, кроме того, где расположен сервер: доступ не удался. | Доступ к узлу, где расположен сервер, через публичный IP‑адрес и порт узла: доступ выполнен успешно. Доступ к узлу, где расположен сервер, через приватный IP‑адрес и порт узла: доступ не удался. Доступ к любому узлу через IP‑адрес и порт узла, кроме того, где расположен сервер: доступ не удался. | ||
Другие контейнеры на разных узлах от service pod. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: доступ выполнен успешно. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ выполнен успешно. Доступ к другому узлу через его IP‑адрес и порт: доступ не удался. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: доступ выполнен успешно. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ выполнен успешно. Доступ к другому узлу через его IP‑адрес и порт: доступ не удался. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, кроме того, где расположен сервер: доступ не удался. | Доступ к узлу, где расположен сервер, через IP‑адрес и порт узла: доступ выполнен успешно. Доступ к любому узлу через IP‑адрес и порт узла, кроме того, где расположен сервер: доступ не удался. | ||
LoadBalancer Service, использующий shared load balancer | Private network | Тот же узел, что и service pod | The access failed. | The access failed. | The access failed. | The access failed. |
Other containers on the same node as the service pod | The access failed. | The access failed. | The access failed. | The access failed. |
Для решения этой проблемы можно использовать следующие методы:
Предположим, что имя Service равно my-service и оно находится в пространстве имён default. Пример команды kubectl выглядит следующим образом:
kubectl patch service my-service -n default --type='merge' -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'