Сервис (Service) в Kubernetes

Сервис (Service) - это абстрактный способ представить приложение, работающее на множестве Pod'ов, как сетевой сервис.

С Kubernetes вам не нужно изменять свое приложение, чтобы использовать незнакомый механизм обнаружения сервисов. Kubernetes предоставляет Pod'у свои собственные IP-адреса и одно DNS-имя для набора Pod'ов и может распределять нагрузку между ними.

Причины появления сервисов

Pod'ы Kubernetes смертны. Они рождаются, а когда они умирают, они не воскресают. Если вы используете Deployment для запуска своего приложения, он может динамически создавать и уничтожать Pod'ы.

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

Это приводит к проблеме: если некоторый набор Pod'ов (назовем их "бэкэндами") предоставляет функциональные возможности другим Pod'ам (назовем их "фронтендами") внутри кластера, как фронтенды узнают и отслеживают, к какому IP-адресу подключаться, так чтобы фронтенд мог использовать бэкэнд часть рабочей нагрузки?

Здесь вступают в игру Сервисы (Services).

Сервисные ресурсы

В Kubernetes Сервис - это абстракция, которая определяет логический набор Pod'ов и политику доступа к ним (иногда этот шаблон называется микросервисом). Набор Pod'ов, на которые ориентируется Сервис, обычно определяется селектором.

Например, рассмотрим бэкэнд часть обработки образов без сохранения состояния (stateless image-processing backend), которая работает с 3 репликами. Эти реплики взаимозаменяемы - внешним пользователям все равно, какой бэкэнд они используют. Хотя фактические Pod'ы, составляющие набор бэкэндов, могут измениться, клиенты фронтенда не должны знать об этом и не должны сами отслеживать набор бэкэндов.

Использование абстракции в виде Сервисов обеспечивает эту возможность.

Обнаружение облачных сервисов

Если вы можете использовать API-интерфейсы Kubernetes для обнаружения сервиса в своем приложении, вы можете запросить у API-сервера конечные точки, которые обновляются при изменении набора Pod'ов в сервисе.

Для не нативных приложений Kubernetes предлагает способы размещения сетевого порта или балансировщика нагрузки между вашим приложением и бекэнд Pod'ами.

Определение сервиса

Сервис в Kubernetes - это REST объект, похожий на Pod. Как и все REST объекты, вы можете отправить POST запросом определение сервиса на сервер API, чтобы создать новый экземпляр.

Например, у вас есть набор Pod'ов, каждый из которых прослушивает TCP-порт 9376 и имеет метку (label) app=MyApp:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

В этой спецификации создается новый объект Service с именем “my-service”, предназначенный для TCP-порта 9376 на любом Pod'е с меткой app=MyApp.

Kubernetes назначает этому сервису IP-адрес (иногда называемый "IP-адрес кластера" (“cluster IP”)), который используется прокси-серверами.

Контроллер для селектора сервиса непрерывно сканирует Pod'ы, соответствующие его селектору, а затем отправляет любые обновления в объект конечной точки (Endpoint object), также называемый “my-service”.

Примечание. Сервис может сопоставить любой входящий порт с targetPort. По умолчанию и для удобства для targetPort установлено то же значение, что и для поля port.

Определения портов в Pod'ах имеют имена, и вы можете ссылаться на эти имена в атрибуте targetPort сревиса. Это работает, даже если в Сервисе есть несколько Pod'ов, использующих одно настроенное имя, с одним и тем же сетевым протоколом, доступным через разные номера портов. Это обеспечивает большую гибкость при развертывании и развитии ваших Сервисов. Например, вы можете изменить номера портов, предоставляемые Pod'ами в следующей версии вашего программного обеспечения, без прерывания работы клиентов.

Протокол по умолчанию для сервисов - TCP. Вы также можете использовать любой другой поддерживаемый протокол.

Поскольку многим сервисам необходимо предоставить более одного порта, Kubernetes поддерживает несколько определений портов для Сервис объекта. Каждое определение порта может иметь один и тот же протокол или другой.

Сервисы без селекторов

Сервисы чаще всего абстрагируют доступ к Pod'ам Kubernetes, но они также могут абстрагировать другие типы бэкэндов. Например:

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

В любом из этих сценариев вы можете определить Сервис без селектора Pod. Например:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

Поскольку этот сервис не имеет селектора, соответствующий объект конечной точки (Endpoint object) не создается автоматически. Вы можете вручную сопоставить сервис с сетевым адресом и портом, где она работает, добавив объект Endpoint вручную:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

Примечание: IP-адреса конечной точки не должны быть: loopback (127.0.0.0/8 для IPv4, ::1/128 для IPv6) или link-local (169.254.0.0/16 и 224.0.0.0/24 для IPv4, fe80::/64) для IPv6).
IP-адреса конечных точек не могут быть кластерными IP-адресами других сервисов Kubernetes, поскольку kube-proxy не поддерживает виртуальные IP-адреса в качестве пункта назначения.

Доступ к Сервису без селектора работает так же, как если бы он имел селектор. В приведенном выше примере трафик направляется на одну конечную точку, определенную в YAML: 192.0.2.42:9376 (TCP).

Сервис ExternalName - это особый случай сервиса, который не имеет селекторов и вместо этого использует DNS-имена.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Контроллеры в Kubernetes: DaemonSet

Контроллеры в Kubernetes: ReplicaSet

Контроллеры в Kubernetes: StatefulSet