В Kubernetes Service делает приложение, запущенное на наборе pod‑ов, доступным по сети. Он обеспечивает согласованное DNS‑имя для этих pod‑ов и распределяет трафик между ними для балансировки нагрузки. В этом разделе описываются базовые концепции Kubernetes Service и приводится сравнение различных типов Service.
В кластере можно создать Service определённого типа. Описание и сценарии применения различных типов Service перечислены в таблице ниже.
Тип Service | Описание | Сценарий применения |
|---|---|---|
ClusterIP Service — тип Service по умолчанию в Kubernetes. Он назначает виртуальный IP‑адрес, доступный только внутри кластера, из блока Service CIDR кластера. | Сервисы, которым требуется только взаимодействие внутри кластера и которые не нужно открывать наружу. Например, если pod фронтенд‑приложения в кластере должен обращаться к базе данных бэкенда в том же кластере, можно создать ClusterIP Service для базы данных бэкенда, чтобы обеспечить доступ к базе данных только внутри кластера. | |
NodePort Service открывает порт на каждом узле кластера, позволяя внешнему трафику обращаться к Service через <node-IP-address:node-port>. | Сценарии, где требуется временный или низкоёмкостный доступ. Например, в тестовой среде можно использовать NodePort Service при развертывании и отладке веб‑приложения. | |
LoadBalancer Service добавляет внешний балансировщик нагрузки поверх NodePort Service и распределяет внешний трафик между несколькими pod‑ами внутри кластера. Он автоматически назначает внешний IP‑адрес, позволяющий клиентам получать доступ. LoadBalancer Service обрабатывает TCP и UDP трафик на уровне 4 (транспортный уровень) модели OSI. При необходимости его можно расширить для поддержки возможностей уровня 7 (прикладной уровень) для управления HTTP и HTTPS трафиком. | Облачные приложения, которым нужен стабильный и лёгкий в управлении вход для внешнего доступа. Например, в продуктивной среде можно использовать LoadBalancer Service для публикации публичных сервисов, таких как веб‑приложения и API‑сервисы, в Интернет. Такие сервисы часто должны обрабатывать большой объём трафика, сохраняя высокую доступность. | |
DNAT Service предоставляет Network Address Translation (NAT) NAT для всех узлов кластера, позволяя нескольким узлам использовать один EIP. | Сервисы, которым нужен временный или низкоёмкостный доступ из Интернета. DNAT Service обеспечивает более высокую надёжность, чем NodePort Service. При DNAT Service не требуется привязывать EIP к отдельному узлу, запросы могут распределяться между нагрузкой, даже если один из узлов кластера недоступен. | |
Headless Service | Приложения, которым требуется прямое взаимодействие с конкретными backend pod‑ами, без использования прокси или балансировщиков. Например, при развертывании stateful‑приложения (например, базы данных ClickHouse) можно использовать Headless Service. Он позволяет pod‑ам приложения напрямую обращаться к каждому pod ClickHouse и выполнять целенаправленные операции чтения и записи. Это повышает общую эффективность обработки данных. |
Если привязка сервиса Service установлена на уровень узла, то есть значение externalTrafficPolicy равно Local, Service может не быть доступен изнутри кластера (конкретно, с узлов или контейнеров). Отображается информация, похожая на следующую:
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
Часто в кластере не удаётся получить доступ к балансировщику нагрузки. Причина такова: при создании Service в Kubernetes kube-proxy добавляет адрес доступа к балансировщику нагрузки как внешний IP‑адрес (External‑IP, как показано в выводе команды ниже) в iptables или IPVS. Если клиент внутри кластера инициирует запрос к балансировщику нагрузки, этот адрес считается внешним IP‑адресом Service, и запрос напрямую перенаправляется kube‑proxy, минуя внешний балансировщик.
# kubectl get svc nginxNAME TYPE CLUSTER-IP NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx LoadBalancer 10.247.76.156 PORT(S) AGEnginx LoadBalancer 10.247.76.156 123.**.**.**,192.168.0.133
80:32146/TCP 37sКогда значение externalTrafficPolicy равно Local
В CCE Turbo кластере с Cloud Native Network 2.0 привязка уровня узла поддерживается только когда backend Service подключён к pod‑у с hostNetwork. | Тип доступа | Местоположение инициирования запроса на клиенте | Tunnel Network Cluster (IPVS) | VPC Network Cluster (IPVS) | Tunnel Network Cluster (iptables) | VPC Network Cluster (iptables) |
|---|---|---|---|---|---|---|
NodePort Service | Публичная/приватная сеть | Тот же узел, что и pod сервиса | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. |
Different nodes from the service pod | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к другому узлу через его IP‑адрес и порт: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через публичный IP‑адрес и порт узла: доступ не удался. Доступ к другому узлу через его IP‑адрес и порт: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через публичный IP‑адрес и порт узла: доступ не удался. Доступ к другому узлу через его IP‑адрес и порт: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через публичный IP‑адрес и порт узла: доступ не удался. Доступ к другому узлу через его IP‑адрес и порт: доступ не удался. | ||
Other containers on the same node as the service pod | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через публичный IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится сервер, через приватный IP‑адрес и порт узла: доступ не удался. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через публичный IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится сервер, через приватный IP‑адрес и порт узла: доступ не удался. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | ||
Other containers on different nodes from the service pod | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ успешен. Доступ к другому узлу через IP‑адрес и порт узла: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к узлу, где находится клиент, через приватный IP‑адрес и порт узла: доступ успешен. Доступ к другому узлу через IP‑адрес и порт узла: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | Доступ к узлу, где находится сервер, через IP‑адрес и порт узла: доступ успешен. Доступ к любому другому узлу через IP‑адрес и порт узла, отличному от узла с сервером: доступ не удался. | ||
LoadBalancer Service using a shared load balancer | Private network | Same node as the 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. |
The following methods can be used to solve this problem:
Предположим, что Service называется my-service и находится в default namespace. Пример команды kubectl ниже:
kubectl patch service my-service -n default --type='merge' -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'