Сервис (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: Deployment, создание
- Контроллеры в Kubernetes: ReplicaSet
- Контроллеры в Kubernetes: StatefulSet
Комментарии
Отправить комментарий