Балансировщики Network Load Balancer (NLB) и Application Load Balancer (ALB) используются для предоставления внешнего доступа к приложениям, развернутым в кластере под управлением Deckhouse Kubernetes Platform.
Особенности и назначение NLB
NLB работает на транспортном уровне. Он балансирует TCP и UDP трафик на уровне IP и портов.
Основные преимущества:
высокая производительность;
минимальные задержки при передаче трафика;
простая конфигурация.
NLB подходит для приложений, которые используют TCP/UDP-протоколы, например, для баз данных.
Особенности и назначение ALB
ALB работает на прикладном уровне. Он анализирует содержимое входящих запросов (например, HTTP-заголовки, пути URL, cookies) и может выполнять маршрутизацию на их основе.
Преимущества ALB:
поддержка HTTP(S)-протоколов и gRPC;
гибкая маршрутизация (path-based, host-based);
возможность терминации SSL/TLS;
интеграция с механизмами аутентификации и авторизации.
ALB подходит для веб-приложений, API и других сервисов, где важны интеллектуальная маршрутизация и работа с HTTP-запросами.
Использование Network Load Balancer (NLB)
NLB обеспечивается за счет использования сервисов с типом LoadBalancer.
Примеры настроек для объектов Service
Общий IP-адрес для нескольких сервисов
Для того, чтобы сервисы использовали одни и те же IP-адреса, добавьте к ним аннотацию network.deckhouse.io/load-balancer-shared-ip-key:
В режиме BGP LoadBalancer получение IP-адреса возможно из определённого пула адресов через аннотацию metallb.universe.tf/address-pool. Для режима L2 LoadBalancer необходимо использовать настройки MetalLoadBalancerClass.
Application Load Balancer (ALB) реализуется с помощью Ingress-ресурсов и Gateway. ALB позволяет обрабатывать следующие виды трафика: HTTP, HTTPS и gRPC. Для публикации приложений используется настроенный администратором Ingress-контроллер. В большинстве случаев применяется модуль ingress-nginx, для более сложных задач может использоваться модуль istio.
Советы по выбору и особенности ALB средствами ingress-nginx и istio
Ingress-nginx
ALB ingress-nginx основан на базе веб-сервера nginx. Этот вариант подходит для:
базовой маршрутизации трафика на основе доменов или URL;
использования SSL/TLS для защиты трафика.
Istio
ALB на основе istio позволяет получить расширенные возможности по управлению трафиком. ALB на базе istio стоит рассмотреть, если вам нужны:
продвинутая маршрутизация, например, для реализации canary deployment.
распределение трафика между версиями приложения и микросервисами;
mTLS для шифрования трафика между подами;
трассировка запросов.
Пример базового Ingress-ресурса для публикации приложения
Для работы с Ingress NGINX администратор Deckhouse Kubernetes Platform должен настроить Ingress-контроллер, добавив к нему сайдкар от Istio. Для этого установите параметр enableIstioSidecar у кастомного ресурса IngressNginxController модуля ingress-nginx.
Для публикации приложения подготовьте Ingress-ресурс, который ссылается на сервис. Обязательные аннотации для Ingress-ресурса:
nginx.ingress.kubernetes.io/service-upstream: "true" — с этой аннотацией Ingress-контроллер будет отправлять запросы на ClusterIP сервиса (из диапазона Service CIDR) вместо того, чтобы отсылать их напрямую в поды приложения. Сайдкар-контейнер istio-proxy перехватывает трафик только в сторону диапазона Service CIDR, остальные запросы отправляются напрямую;
nginx.ingress.kubernetes.io/upstream-vhost: myservice.myns.svc — с данной аннотацией сайдкар сможет идентифицировать прикладной сервис, для которого предназначен запрос.
Примеры:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: productpage
namespace: bookinfo
annotations:
# Включает через nginx проксирование трафика на ClusterIP вместо собственных IP подов.
nginx.ingress.kubernetes.io/service-upstream: "true"
# В Istio вся маршрутизация осуществляется на основе `Host:` заголовка запросов.
# Это позволяет избежать необходимости указывать Istio о существовании внешнего домена `productpage.example.com`,
# используется внутренний домен, известный Istio.
nginx.ingress.kubernetes.io/upstream-vhost: productpage.bookinfo.svc
spec:
rules:
- host: productpage.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: productpage
port:
number: 9080
apiVersion: v1
kind: Service
metadata:
name: productpage
namespace: bookinfo
spec:
ports:
- name: http
port: 9080
selector:
app: productpage
type: ClusterIP
Пример ресурса Istio Ingress Gateway
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: gateway-app
namespace: app-ns
spec:
selector:
# Селектор лейблов для использования Istio Ingress Gateway main-hp.
istio.deckhouse.io/ingress-gateway-class: istio-hp
servers:
- port:
# Стандартный шаблон для использования протокола HTTP.
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com
- port:
# Стандартный шаблон для использования протокола HTTPS.
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
# Ресурс Secret с сертификатом и ключом, который должен быть создан в пространстве имен d8-ingress-istio.
# Поддерживаемые форматы Secret можно посмотреть по ссылке https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/#key-formats.
credentialName: app-tls-secret
hosts:
- app.example.com
Балансировка gRPC
Чтобы балансировка gRPC-сервисов заработала автоматически, присвойте имя с префиксом или значением grpc для порта соответствующему объекту Service.
Дополнительные сети для использования в прикладных подах
В DKP реализована возможность использования дополнительных программно-определяемых сетей (далее — дополнительные сети) для прикладных нагрузок (поды, виртуальные машины). Вы можете использовать сети следующих типов:
Кластерная (общедоступная) — сеть, общедоступная в каждом проекте, настраивается и управляется администратором. Пример — публичная WAN-сеть или shared-сеть обмена трафиком между проектами. Для создания такой сети и ее использования для прикладных подов обратитесь к администратору кластера.
Сеть проекта (пользовательская сеть) — сеть, доступная в рамках неймспейса, создается и управляется пользователем c использованием предоставленного администратором манифеста NetworkClass.
Создание сети проекта (пользовательской сети)
Для создания сети для проекта используйте кастомные ресурсы Network и NetworkClass (предоставляется администратором):
1. Создайте и примените манифест объекта Network, указав в поле spec.networkClass имя NetworkClass, полученное у администратора:
apiVersion: network.deckhouse.io/v1alpha1
kind: Network
metadata:
name: my-network
namespace: my-namespace
spec:
networkClass: my-network-class # Имя NetworkClass, полученное от администратора.
Поддерживается статическое определение номера VLAN ID из пула, выданного администратором кластера. Если значение поля spec.vlan.id не указано, VLAN ID будет назначен динамически.
2. После создания объекта Network проверьте его статус:
d8 k -n my-namespace get network my-network -o yaml
Вы можете подключать к подам кластерные сети и сети проекта. Для этого используйте аннотацию пода, в которой укажите параметры подключаемых дополнительных сетей.
Пример манифеста пода с добавлением двух дополнительных сетей (кластерной my-cluster-network и сети проекта my-network):
В поле ifName (опционально) задается имя TAP-интерфейса внутри пода. В поле mac (опционально) задается MAC-адрес, который следует назначить TAP-интерфейсу.
Механизм IPAM (IP Address Management) позволяет выделять IP-адреса (поддерживаются IPv4-адреса) из пулов и назначать их на дополнительные сетевые интерфейсы подов, подключаемых к кластерным сетям и сетям проекта.
Выделением IP-адресов для подключения к кластерным сетям занимается администратор кластера. Он включает, настраивает IPAM для сетей и определяет пул IP-адресов для них. Назначать адреса и настраивать IPAM в сетях проекта могут пользователи.
Особенности использования IPAM в кластере DKP
IPAM в кластере DKP имеет следующие особенности использования:
IPAM включается на уровне сети через параметр spec.ipam.ipAddressPoolRef объекта Network или ClusterNetwork (для ClusterNetwork IPAM включает администратор кластера).
Назначение IP-адреса на интерфейс пода описывается в добавляемой к поду аннотации network.deckhouse.io/networks-spec через поля:
ipAddressNames — список объектов IPAddress, которые нужно назначить на данный интерфейс (если параметр не указан, IPAddress может создаваться автоматически).
skipIPAssignment — управление резервированием/отслеживанием IPAddress. Если skipIPAssignment: true, включается резервирование/отслеживание IPAddress, но IP-адрес не назначается на интерфейс внутри пода (вариант для продвинутого использования).
Поддерживается назначение только IPv4-адресов на дополнительные сетевые интерфейсы подов.
Если в одном поде подключено несколько дополнительных сетей с включенным IPAM, рекомендуется явно задавать ipAddressNames для каждого интерфейса (создавая отдельные IPAddress). Автоматически создаваемый IPAddress привязан к поду и может не подходить для нескольких IPAM-сетей одновременно.
Выделение пула IP-адресов для сети проекта и включение IPAM
Чтобы выделить пул адресов для сети проекта, создайте ресурс IPAddressPool в том же неймспейсе, что и сеть проекта (поды, подключаемые к сети).
Для выделения пула адресов и их назначения на сетевые интерфейсы подов, подключаемых к сети проекта, выполните следующие действия:
1. Создайте пул адресов. Для этого используйте ресурс IPAddressPool.
Параметр spec.pools[].ranges опционален. Если он не указан, доступным считается весь CIDR из spec.pools[].network (за исключением network/broadcast адресов, см. поведение /31 и /32).
2. Включите IPAM в дополнительной сети. Для этого в параметре spec.ipam.ipAddressPoolRef ресурса Network укажите параметры созданного на предыдущем шаге IPAddressPool.
После выделения пула IP-адресов для сети проекта их можно назначать на сетевые интерфейсы подов, подключаемых к этой сети.
Назначение IP-адресов на сетевые интерфейсы подов, подключаемых к дополнительной сети
В DKP реализована автоматическая выдача IP-адресов для дополнительных интерфейсов подов, а также возможность ручного назначения конкретных статических IP-адресов на дополнительные интерфейсы подов.
Автоматическая выдача IP-адресов
Чтобы IP-адрес для дополнительного сетевого интерфейса пода был выбран автоматически из пула, добавьте к поду аннотацию network.deckhouse.io/networks-spec. В этой аннотации укажите параметры сети с включенным IPAM.
Пример (IP-адрес будет выбран автоматически из пула, созданного для сети my-network и назначен на интерфейс net1):
В таком случае будет автоматически создан объект IPAddress (тип Auto) и из прикрепленного к дополнительной сети (в примере — my-network)пула будет автоматически выбран IP-адрес и назначен на сетевой интерфейс пода.
Ручное (явное) создание IPAddress с типом Auto
Также можно вручную создать объект IPAddress с spec.type: Auto (без указания параметра static.ip). В этом случае контроллер выделит свободный адрес из пула прикрепленного к дополнительной сети (в примере — my-network), а вы сможете привязать его к конкретному интерфейсу пода через параметр ipAddressNames в аннотации network.deckhouse.io/networks-spec.
Чтобы проверить, что IP-адрес назначен на интерфейс, выполните следующие шаги:
1. Проверьте выделенный адрес и фазу у IPAddress (фаза должна быть Allocated):
d8 k -n my-namespace get ipaddress app-net1-static -o yaml
Пример вывода:
NAME TYPE KIND NAME ADDRESS NETWORK PHASE AGE
ipaddress-auto-1 Auto Network mynet 192.168.12.1 192.168.12.0/24 Allocated 4d1h
ipaddress-auto-2 Auto Network mynet 192.168.12.2 192.168.12.0/24 Allocated 4d1h
2. Проверьте аннотацию пода network.deckhouse.io/networks-status (включая ipAddressConfigs и маршруты):
d8 k -n my-namespace get pod app-with-static-ip -o jsonpath='{.metadata.annotations.network\.deckhouse\.io/networks-status} ' | jq
Подключение физических сетевых интерфейсов к подам DPDK-приложений
Если в вашем неймспейсе (проекте) размещаются высокопроизводительные рабочие нагрузки, требующие прямого доступа к оборудованию (например, приложения DPDK), можно использовать прямое подключение физических сетевых интерфейсов (Physical Functions и Virtual Functions) к подам через Kubernetes Dynamic Resource Allocation (DRA).
Физические сетевые интерфейсы могут подключаться в поды в одном из двух режимов:
Shared — создается Virtual Functions (VF) из Physical Functions (PF) с использованием SR-IOV, несколько подов могут совместно использовать одно и то же оборудование.
Dedicated — каждый под получает эксклюзивный доступ к полному PF.
Подключение физических сетевых интерфейсов к подам
Для подключения физических сетевых интерфейсов (PF/VF) напрямую в поды для DPDK-приложений необходимо:
Убедиться, что администратор добавил на ваш неймспейс лейбл для использования Underlay-сетей.
Создать под c аннотацией, запрашивающей устройство из Underlay-сети.
Создание пода c устройством из Underlay-сети
Создайте под, который запрашивает устройство из Underlay-сети. В аннотации пода network.deckhouse.io/networks-spec укажите параметры:
type: "UnderlayNetwork" — указывает, что это запрос физического устройства;
name: "underlay-network-name" — имя ресурса UnderlayNetwork, созданного администратором;
bindingMode — режим привязки устройства (VFIO-PCI, DPDK или NetDev).
Пример конфигурации пода для режима DPDK (универсальный режим, который автоматически выбирает подходящий драйвер для вендора сетевого адаптера):
Для DPDK-приложений важно:
Настроить capabilities (NET_ADMIN, NET_RAW, IPC_LOCK) для запуска в непривилегированном режиме вместо использования privileged: true;
Подключить volumes с hugepages, так как DPDK требует hugepages для эффективного управления памятью.
Для VF устройств в режиме Shared можно дополнительно указать vlanID в аннотации для настройки VLAN-тегирования на VF:
Для организации внутрикластерного взаимодействия в Deckhouse Kubernetes Platform рекомендуется использовать сервисы вместо обращения напрямую к подам. Они обеспечивают балансировку нагрузки между подами, стабильное сетевое взаимодействие и интеграцию с DNS для удобного обнаружения сервисов. Также сервисы поддерживают различные сценарии доступа и обеспечивают изоляцию и безопасность сетевого трафика.
При необходимости можно использовать стандартный балансировщик на базе сервисов или расширенный балансировщик на базе модуля service-with-healthchecks.
Стандартный балансировщик
В Kubernetes за внутреннюю и внешнюю балансировку запросов отвечает ресурс типа Service. Этот ресурс:
распределяет запросы между рабочими подами приложения;
исключает из балансировки повреждённые экземпляры подов.
Для проверки способности пода обрабатывать входящие запросы применяются readiness-пробы, которые указываются в спецификации контейнеров, входящих в этот под.
Ограничения стандартного балансировщика Service
Стандартный инструмент балансировки Service подходит для большинства задач облачных приложений, но имеет два ограничения:
Если хотя бы один контейнер в поде не проходит проверку готовности (readiness-пробу), весь под считается как NotReady и исключается из балансировки всех сервисов, с которыми он связан.
Для каждого контейнера можно настроить только одну пробу, поэтому невозможно создать отдельные пробы для проверки, например, доступности чтения и записи.
Примеры сценариев, где стандартного балансировщика недостаточно:
База данных:
Работает в трёх подах — db-0, db-1 и db-2, каждый из которых содержит один контейнер с запущенным процессом базы данных.
Необходимо создать два сервиса (Service) — db-write для записи и db-read для чтения.
Запросы на чтение должны балансироваться между всеми подами.
Запросы на запись балансируются только на тот под, который назначен мастером средствами самой базы данных.
Виртуальная машина:
Под содержит единственный контейнер, в котором запущен процесс qemu, выполняющий роль гипервизора для гостевой виртуальной машины.
В гостевой виртуальной машине запущены независимые процессы, например, веб-сервер и SMTP-сервер.
Требуется создать два Service — web и smtp, каждый из которых будет иметь свои readiness-пробы.
Пример стандартного балансировщика для работы с PostgreSQL-кластером
Создание StatefulSet для PostgreSQL
Для корректной работы StatefulSet потребуется создать стандартный сервис (Service) для формирования DNS-имени отдельных подов. Этот сервис не будет использоваться для прямого доступа к базе данных.
В отличие от стандартного балансировщика, где readiness-пробы привязаны к состоянию контейнеров, ресурс ServiceWithHealthcheck, который используется в балансировщике, позволяет настраивать активные пробы на отдельные TCP-порты. Таким образом, каждый балансировщик, обслуживающий один и тот же под, может работать независимо от других.
Внутреннее устройство балансировщика
Балансировщик состоит из двух компонентов:
контроллер — работает на master-узлах кластера и управляет ресурсами ServiceWithHealthcheck,
агенты — работают на каждом узле кластера и выполняют пробы для подов, запущенных на этом узле.
Балансировщик ServiceWithHealthcheck спроектирован так, чтобы не зависеть от реализации CNI, используя при этом стандартные ресурсы Service и EndpointSlice:
Контроллер при создании ресурса ServiceWithHealthcheck автоматически создает одноименный ресурс Service в том же пространстве имен с пустым полем selector. Это позволяет избежать создания стандартным контроллером объектов EndpointSlice, которые используются для настройки балансировки.
Каждый агент при появлении на своём узле подов, которые попадают под управление ServiceWithHealthcheck, осуществляет настроенные пробы и создаёт для них объект EndpointSlice со списком проверенных IP-адресов и портов. Данный объект EndpointSlice привязан к дочернему ресурсу Service, созданному выше.
CNI сопоставит все объекты EndpointSlice со стандартными сервисами, созданными выше и осуществит балансировку по проверенным IP-адресам и портам на всех узлах кластера.
Миграция с Service на ресурс ServiceWithHealthchecks, например в рамках CI/CD, не должна вызвать затруднений. Спецификация ServiceWithHealthchecks в основе своей повторяет спецификацию Service, но содержит дополнительный раздел healthcheck. Во время жизненного цикла ресурса ServiceWithHealthchecks создается одноименный сервис в том же пространстве имён, чтобы привычным способом (kube-proxy или cni) направить трафик на рабочие нагрузки в кластере.
Настройка балансировщика
Настроить данный способ балансировки можно при помощи ресурса ServiceWithHealthchecks:
Его спецификация идентична стандартному ресурсу Service с добавлением раздела healthcheck, который содержит набор проверок.
На данный момент поддерживается три вида проб:
TCP — обычная проверка с помощью установки TCP-соединения.
HTTP — возможность отправить HTTP-запрос и ожидать определённый код ответа.
PostgreSQL — возможность отправить SQL-запрос и ожидать его успешного завершения.
Пример конфигурации расширенных балансировщиков ServiceWithHealthchecks
Создайте Secret для хранения учетных данных для доступа проб к базе данных:
Размещение двух независимых балансировщиков на одной виртуальной машине
На виртуальной машине с операционной системой Linux работают два приложения — HTTP-сервер (TCP 8080) и SMTP-сервер (TCP 2525). Необходимо настроить два отдельных балансировщика для этих сервисов — веб-балансировщик и SMTP-балансировщик.
Создание виртуальной машины
Создайте виртуальную машину my-vm. В примере манифеста ниже добавлен лейбл vm: my-vm для дальнейшей идентификации в балансировщиках.
Управление авторизацией и доступом к нагрузке c Istio
Для управления авторизацией и контролем доступа к workload можно использовать модуль istio. Перед настройкой авторизации убедитесь, что модуль включен в кластере.
Авторизация
Управление авторизацией осуществляется с помощью ресурса AuthorizationPolicy от Istio. Когда для сервиса создается этот ресурс, применяются следующие правила принятия решения о запросах:
Если запрос попадает под политику DENY — запретить запрос.
Если для данного сервиса нет политик ALLOW — разрешить запрос.
Если запрос попадает под политику ALLOW — разрешить запрос.
Все остальные запросы — запретить.
Иными словами, если явно что-то запретить, работает только запрет. Если же что-то явно разрешить, будут разрешены только явно одобренные запросы (запреты при этом имеют приоритет).
Для написания правил авторизации можно использовать следующие аргументы:
идентификаторы сервисов и wildcard на их основе (mycluster.local/ns/myns/sa/myapp или mycluster.local/*);
пространство имен;
диапазоны IP;
HTTP-заголовки;
JWT-токены из прикладных запросов.
Ресурс AuthorizationPolicy
Подробнее ознакомиться с AuthorizationPolicy можно в документации Istio.
Ресурс AuthorizationPolicy включает и определяет контроль доступа к workload. Поддерживает как ALLOW-, так и DENY-правила, описанные выше.
Аргументы для принятия решения об авторизации:
source:
namespace;
principal (идентификатор юзера, полученный после аутентификации);
IP.
destination:
method (GET, POST и т. д.);
host;
port;
URI.
conditions:
HTTP-заголовки;
аргументы source;
аргументы destination;
JWT-токены.
Настройка маршрутизации запросов с Istio
Для маршрутизации HTTP- и TCP-запросов в Deckhouse Kubernetes Platform можно использовать модуль istio.
Основной ресурс для управления маршрутизацией — VirtualService от Istio, он позволяет настраивать маршрутизацию HTTP- или TCP-запросов.
Ресурс VirtualService
Использование VirtualService опционально, классические сервисы продолжают работать, если их функционала достаточно. С помощью этого ресурса можно настроить маршрутизацию запросов:
Аргументы для принятия решения о маршруте:
host;
uri;
weight (вес).
Параметры итоговых направлений:
новый host;
новый uri;
если host определен с помощью DestinationRule можно направлять запросы на subset’ы;
таймаут и настройки retry (повторных попыток).
Для корректной работы destinationв Istio необходимо его указать. Если вы используете внешний API, укажите его с помощью ServiceEntry.
Активация Istio для приложений
Активация Istio для приложений возможна, если в кластере включен и настроен модуль istio. За это отвечает администратор кластера.
Суть активации — добавить сайдкар-контейнер к подам приложения, после чего Istio сможет управлять трафиком.
Рекомендованный способ добавления сайдкаров — использовать сайдкар-injector. Istio умеет «подселять» к подам приложения сайдкар-контейнер с помощью механизма Admission Webhook. Для добавления сайдкаров используются лейблы и аннотации:
Лейбл к namespace — обозначает ваше пространство имён для компонента сайдкар-injector. После применения лейбла к новым подам будут добавлены сайдкар-контейнеры:
istio-injection=enabled — использует глобальную версию Istio (spec.settings.globalVersion в ресурсе ModuleConfig);
istio.io/rev=v1x16 — использует конкретную версию Istio для этого пространства имён.
Аннотация к поду sidecar.istio.io/inject ("true" или "false") позволяет локально переопределить политику sidecarInjectorPolicy. Эти аннотации работают только в пространствах имён, обозначенных лейблами из списка выше.
Также существует возможность добавить сайдкар к определенному поду в пространстве имён без установленных лейблов istio-injection=enabled или istio.io/rev=vXxYZ путем установки лейбла sidecar.istio.io/inject=true.
Istio-proxy, который работает в качестве сайдкар-контейнера, тоже потребляет ресурсы и добавляет накладные расходы:
Каждый запрос DNAT’ится в Envoy, который обрабатывает это запрос и создает еще один. На принимающей стороне — аналогично.
Каждый Envoy хранит информацию обо всех сервисах в кластере, что требует памяти. Больше кластер — больше памяти потребляет Envoy. Решение — кастомный ресурс Sidecar.
Также важно подготовить Ingress-контроллер и Ingress-ресурсы приложения:
Включите enableIstioSidecar у ресурса IngressNginxController.
Добавьте аннотации на Ingress-ресурсы приложения:
nginx.ingress.kubernetes.io/service-upstream: "true" — Ingress-контроллер в качестве upstream использует ClusterIP сервиса вместо адресов подов. Балансировкой трафика между подами теперь занимается сайдкар-proxy. Используйте эту опцию, только если у вашего сервиса есть ClusterIP;
nginx.ingress.kubernetes.io/upstream-vhost: "myservice.myns.svc" — сайдкар-proxy Ingress-контроллера принимает решения о маршрутизации на основе заголовка Host. Без этой аннотации контроллер оставит заголовок с адресом сайта, например Host: example.com.
Управление балансировкой запросов между эндпоинтами сервиса с Istio
Для управления балансировкой запросов между эндпоинтами сервиса можно использовать модуль istio. Перед настройкой балансировки убедитесь, что модуль включен в кластере.
Основной ресурс для управления балансировкой запросов — DestinationRule от istio.io. Этот ресурс предоставляет возможности настройки следующих параметров:
лимиты и таймауты для TCP;
алгоритмы балансировки между эндпоинтами;
правила определения проблем на стороне эндпоинта для выведения его из балансировки;
нюансы шифрования.
Все настраиваемые лимиты работают для каждого пода клиента по отдельности. Например, если настроить для сервиса ограничение на одно TCP-соединение, а клиентских подов — три, то сервис получит три входящих соединения.
Ресурс DestinationRule
Подробнее ознакомиться с DestinationRule можно в документации istio. Используйте этот ресурс, чтобы:
Определить стратегию балансировки трафика между эндпоинтами сервиса:
алгоритм балансировки (LEAST_CONN, ROUND_ROBIN, и т. д.);
определение и исключение неработающих эндпоинтов;
лимиты TCP-соединений и запросов для эндпоинтов;
поддержка Sticky Sessions;
настройка Circuit Breaker.
Задать альтернативные группы эндпоинтов для обработки трафика (применимо для Canary Deployments). Каждая группа может иметь свои стратегии балансировки.
Настроить TLS для исходящих запросов.
Настройка Locality failover с Istio
В Deckhouse Kubernetes Platform можно реализовать механизм Locality failover средствами модуля istio. Перед настройкой механизма убедитесь, что модуль включен в кластере.
Механизм Locality failover управляет маршрутизацией трафика и направляет его на приоритетный фейловер в случае недоступности определённых экземпляров сервисов.
При необходимости ознакомьтесь с документацией Locality failover.
С использованием Istio настраивается приоритетный географический фейловер между эндпоинтами. Для определения зоны применяются лейблы узлов с соответствующей иерархией:
topology.istio.io/subzone;
topology.kubernetes.io/zone;
topology.kubernetes.io/region.
Это полезно для межкластерного фейловера при использовании совместно с мультикластером.
Для активации Locality Failover используется ресурс DestinationRule, в котором также необходимо указать параметр outlierDetection.
При необходимости ознакомьтесь с документацией VirtualService.
Использование VirtualService опционально, классические сервисы продолжают работать, если их функционала достаточно. С помощью этого ресурса можно настроить маршрутизацию запросов:
Аргументы для принятия решения о маршруте:
host;
uri;
weight (вес).
Параметры итоговых направлений:
новый host;
новый uri;
если host определен с помощью DestinationRule можно направлять запросы на subset’ы;
таймаут и настройки retry (повторных попыток).
Для корректной работы destination в Istio необходимо его указать. Если вы используете внешний API, укажите его с помощью ServiceEntry.
Настройка ресурсов для istio-proxy сайдкаров
При использовании модуля istio в кластере вы можете управлять ресурсами, выделяемыми для istio-proxy сайдкаров в отдельных рабочих нагрузках. Для этого используются аннотации.
Поддерживаемые аннотации
Для переопределения глобальных ограничений ресурсов для istio-proxy сайдкаров в отдельных рабочих нагрузках поддерживаются аннотации:
Аннотация
Описание
Пример значения
sidecar.istio.io/proxyCPU
Запрос CPU для сайдкара
200m
sidecar.istio.io/proxyCPULimit
Лимит CPU для сайдкара
"1"
sidecar.istio.io/proxyMemory
Запрос памяти для сайдкара
128Mi
sidecar.istio.io/proxyMemoryLimit
Лимит памяти для сайдкара
512Mi
Тяните вбок для перемещения
Все аннотации из таблицы должны быть указаны в манифесте рабочей нагрузки одновременно. Частичная конфигурация не поддерживается.
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.istio.io/proxyCPU: 200m
sidecar.istio.io/proxyCPULimit: "1"
sidecar.istio.io/proxyMemory: 128Mi
sidecar.istio.io/proxyMemoryLimit: 512Mi
# ... остальная часть манифеста
Настройка Circuit Breaker
В Deckhouse Kubernetes Platform механизм Circuit Breaker реализуется средствами Istio (модуль istio) и обеспечивает следующие возможности:
временное исключение эндпоинта из балансировки, если превышен лимит ошибок;
настройка лимитов на количество TCP-соединений и количество запросов в сторону одного эндпоинта;
выявление зависших запросов и обрывание их с кодом ошибки (HTTP request timeout).
Пример настройки Circuit Breaker
Для выявления проблемных эндпоинтов используются настройки outlierDetection в кастомном ресурсе DestinationRule. Более подробно алгоритм Outlier Detection описан в документации Envoy.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-cb-policy
spec:
host: reviews.prod.svc.cluster.local
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100 # Максимальное число соединений в сторону host, суммарно для всех эндпоинтов.
http:
maxRequestsPerConnection: 10 # Каждые 10 запросов соединение будет пересоздаваться.
outlierDetection:
consecutive5xxErrors: 7 # Допускается 7 ошибок (включая `5xx`, TCP-таймауты и HTTP-таймауты)
interval: 5m # в течение 5 минут,
baseEjectionTime: 15m # после которых эндпоинт будет исключен из балансировки на 15 минут.
Также для настройки HTTP-таймаутов используется ресурс VirtualService. Эти таймауты учитываются и при подсчёте статистики ошибок на эндпоинтах.
Canary deployment — стратегия развертывания приложений, которая позволяет постепенно внедрять в production новую версию приложения. Этот подход даёт возможность тестировать новые версии на небольшой части трафика, минимизируя риски и обеспечивая плавный переход. С помощью Canary deployment возможно переключение трафика на новую версию по мере уверенности в её стабильности, с возможностью быстрого отката на старую версию при возникновении проблем. В Deckhouse Kubernetes Platform Canary deployment может быть реализован средствами ingress-nginx или istio (рекомендуемый способ).
Для реализации Canary deployment средствами Ingress NGINX используются аннотации и правила, которые определяют направление части трафика на новую версию приложения.
Создание Deployment и Service для стабильной версии
Вы можете постепенно увеличивать процент трафика на Canary-версию, изменяя значение аннотации nginx.ingress.ernetes.io/canary-weight. Например, чтобы направить 50% трафика на Canary-версию, обновите аннотацию следующим образом:
nginx.ingress.kubernetes.io/canary-weight: "50"
Откат или завершение Canary deployment
Если Canary-версия работает стабильно, вы можете полностью переключить трафик на новую версию, удалив Canary-аннотации и обновив основной Ingress. Если возникли проблемы, вы можете уменьшить процент трафика на Canary-версию или полностью отключить ее, установив nginx.ingress.kubernetes.io/canary-weight: "0".
Дополнительные аннотации для Canary deployment
nginx.ingress.kubernetes.io/canary-by-header — направляет трафик на Canary-версию на основе значения HTTP-заголовка.
nginx.ingress.kubernetes.io/canary-by-cookie — направляет трафик на Canary-версию на основе значения cookie.
Istio отвечает лишь за гибкую маршрутизацию запросов, которая опирается на спецзаголовки запросов (например, cookie) или просто на случайность. За настройку этой маршрутизации и переключение между канареечными версиями отвечает CI/CD-система.
Подразумевается, что в одном пространстве имён размещены два Deployment с разными версиями приложения. У подов разных версий разные лейблы (version: v1 и version: v2).
Требуется настроить два кастомных ресурса:
DestinationRule с описанием, как идентифицировать разные версии вашего приложения (subset’ы);
VirtualService с описанием, как распределять трафик между разными версиями приложения.
Пример:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: productpage-canary
spec:
host: productpage
# Subset'ы доступны только при обращении к хосту через VirtualService из пода под управлением Istio.
# Эти subset'ы должны быть указаны в маршрутах.
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Продолжая использование настоящего сайта, вы выражаете своё согласие на обработку файлов cookie в соответствии с Политикой в отношении файлов cookie. В случае несогласия с обработкой ваших персональных данных вы можете отключить сохранение cookie в параметрах настройки вашего браузера.