Всем привет, с вами снова Смирнов Илья. Напомню, что я архитектор решений из Cloud.ru. На этот раз предлагаю погрузиться в тему мультикластеров. Сначала разберем, зачем они нужны и когда целесообразны — для тех, кто только начинает изучать вопрос. Ну и, конечно, детально разберем технический аспект вопроса — посмотрим, как создать рабочую мультикластерную инфраструктуру для одновременного и унифицированного управления приложениями, на какие подводные камни можно наткнуться и как расчистить себе этот путь.

Сначала давайте представим ситуацию, что мы развернули в облаке управляемый кластер Kubernetes. Мы не новички и сразу все сделали отказоустойчиво:

  • создали несколько мастеров и развернули их в разных зонах доступности;

  • сделали несколько групп узлов — также в разных зонах доступности;

  • наше приложение может быть запущено на любой из этих групп.

У нас может выйти из строя мастер, воркер, целая группа узлов, а то и несколько, но при этом наше приложение остается доступным.

И вроде бы всё выглядит так, что все возможные риски мы предусмотрели. Управляемый кластер Kubernetes представляет для этого все инструменты, а SLA облачного провайдера позволяет не задумываться о возможных проблемах с инфраструктурой и простоях.

Но что, если мы запускаем mission-critical приложение? Например, финансовую платформу или систему мониторинга здоровья пациентов. Если такое приложение будет недоступно, то нас ждут потери в миллионы или даже миллиарды рублей. А иногда — под угрозой могут оказаться жизни людей... Магистральный кабель на стороне провайдера может перебить, существуют договорные риски, ну и, конечно, очередное обновление или внесение каких-то изменений в настройки кластера могут пойти не по плану.

Кажется, возможные угрозы — не только прямой путь стать параноиками, но и, конечно, повод по максимуму учесть все риски. Нам точно нужно как-то обеспечить доступность приложения, если кластер станет недоступным...

Очевидная идея, которая приходит в голову — сделать еще один кластер и каким-то образом объединить его с первым и настроить отказоустойчивый режим. Если по каким-то причинам один кластер будет недоступен, приложение будет работать на втором.

Мультикластер и зачем они нужны

Статью стоит рассматривать как первичное погружение в оркестрацию мультикластеров. Мы сфокусируемся на оркестрации мультикластеров с помощью решения Karmada. За бортом оставим вопросы сетевой составляющей.

Мы начали с примера, когда нам может потребоваться мультикластер. Но это не единственный пример, когда целесообразно потратить на них деньги.

Начнем с вопроса — «А когда мультикластеры полезны и целесообразны?». Есть несколько наиболее популярных сценариев:

  • Disaster Recovery (обеспечение катастрофоустойчивости).

  • Организация геораспределенности.

  • Изоляция сред.

  • Создание гибридного облака (мультиклауд-стратегия).

Disaster Recovery

Cо сценарием катастрофоустройчивости мы довольно близко познакомились в начале статьи, поэтому не будем сейчас на нем останавливаться.

Геораспределенность

Вы разворачиваете ваше приложение в нескольких регионах и при этом хотите, чтобы в каждом регионе была минимальная задержка при обращении к приложению и работа приложения в одном регионе не зависела от других регионов. В этом случае мультикластер позволит выполнить все требования и при этом управлять всей системой централизовано. Более того, вы сможете временно перенаправлять трафик на другие кластеры, пока обслуживаете какой-то один.

Изоляция сред

Отдельный кластер позволяет добиться полной изоляции среды в сравнении с отдельным тенантом внутри коммунального кластера Kubernetes. Например, популярен сценарий, когда среды Dev/Stage/Test/Prod разносятся по разным кластерам-участникам мультикластера, но при этом управление средами происходит централизовано через оркестратор мультикластеров.

Создание гибридного облака (мультиклауд-стратегия)

Мультикластеры позволяют реализовать гибридное облако или использовать несколько облачных платформ.

Например, ваша инфраструктура развернута «на земле». Полностью переезжать в облако вы не хотите и вашим целям полностью соответствует возможность полностью контролировать свою инфраструктуру. Но при этом обслуживание пиковых нагрузок обходится довольно дорого — нужно закупить определенное количество серверов и держать их до момента наступления пиковой нагрузки. И если это происходит не часто, то траты на закупку оборудования, амортизацию и его обслуживание будут непомерными.

А если не переезжать в облако полностью, а создать там еще один кластер и объединить с кластером «на земле», вы сможете масштабировать свои ресурсы во время пиковых нагрузок отдельно — в облачном кластере. Тогда платить вы будете лишь за использования облачных ресурсов во время пиковой нагрузки.

Как создать мультикластер: варианты

Чтобы создать мультикластер, можно:

  • использовать глобальный балансировщик, чтобы перенаправлять трафик на все кластеры;

  • объединенить кластеры по сети;

  • оркестрировать кластеры с помощью специального решения.

Стоит отметить, что эти подходы не взаимоисключащие. Даже наоборот — часто вам, как минимум, потребуется глобальный балансировщик, чтобы обеспечить доступ к приложению, и мультикластерный оркестратор, чтобы развернуть приложение и управлять им.

Глобальный балансировщик нагрузки

В первом приближении самым простым способом организовать кластер кажется организация балансировки трафика между кластерами. Для создания аналогичной схемы нам потребуется глобальный балансировщик нагрузки.

В качестве примера приведу open source балансировщик нагрузки k8gb, который позволяет обращаться к приложению по DNS-имени и перенаправляет запрос на «здоровый» кластер Kubernetes с минимальной задержкой.

Но кажущаяся простота реализации несет в себе ряд проблем в работе, например:

  • при обновлении приложении нам придется вручную обновить его в каждом кластере, что кратно увеличивает трудозатраты;

  • сложно реализовать Service Discovery — так или иначе придется применять костыли;

  • распределять реплики в кластерах придется вручную, также как и вносить изменения в это распределение.

Межкластерная сетевая связанность

Проблему с Service Discovery можно решить, если организовать сетевую связанность между кластерами. Для этого подойдут, например, Cillium Cluster Mesh, Istio, Submariner и другие.

Благодаря этому развернутые в разных кластерах ресурсы смогут взаимодействовать друг с другом, но по-прежнему остается часть болезней:

  • обновлять кластеры сложно;

  • риск применения костылей для Service Discovery по-прежнему есть, особенно если мы говорим про open source ?;

  • централизовано распределять ресурсы по кластерами невозможно.

Оркестрация мультикластеров

Чтобы решить основные боли предыдущих двух подходов, нужно централизованно управлять кластерами — оркестрировать их. Нужно решение, которое выступит в роли Control Plane.

Некоторые решения для мультикластерной оркестрации позволяют настроить мультикластерное автомасштабирование и мультикластерную отказоустойчивость.

Чтобы можно было более предметно остановиться на оркестрации мультикластеров, сфокусируемся на конкретном решении — Karmada.

Почему Karmada? Потому что:

  • адаптироваться к работе с этим инструментом просто, Karmada близко реализует native Kubernetes API;

  • проект улучшает реализацию Kubernetes Federation v1 и v2. KubeFed усложнял эксплуатацию и создавал overhead, т. к. на каждый ресурс приходилось создавать несколько новых CRD, которые описывали сам ресурс и правила распространения. Karmada же использует универсальные CRD для всех ресурсов — их мы обсудим в следующем разделе;

  • Karmada предлагает легко мигрировать от однокластерной системы на мультикластерную;

  • можно отказоустойчиво развернуть Karmada;

  • CNCF приводит результаты тестирования Karmada для управления 100 кластерами с высокой нагрузкой.

Важный нюанс — Karmada пока находится в CNCF на стадии Incubating. Т. е. в проде решение можно применять, но оно еще проходит свои шаги до полной зрелости. При этом инструмент активно развивается.

Но важно понимать, что оркестратор никаким образом не организует сеть и не позволяет реализовать балансировщик нагрузки. Повторюсь — чаще всего для развертывания приложения в мультикластере нам придется сочетать сразу несколько подходов.

Karmada у себя в документации для реализации Service Discovery или мультикластерного ingress-контроллера, предлагает использовать Submariner.

Архитектура и принцип действия Karmada

Если посмотреть на Karmada верхнеуровнево, то у нас есть два воображаемых кластера Kubernetes, и есть приложение, которое мы хотим развернуть. Karmada же выступает в роли Control Plane и оркестрирует эти кластеры.

Karmada реализует native Kubernetes API. Администратор может просто загрузить в Control Plane манифесты приложения. Karmada их сохранит у себя. Но если мы загрузим только манифесты приложения, то Karmada не будет распространять целевые ресурсы в кластерах-участниках. Чтобы Karmada создала ресурсы в каком-то из кластеров, необходимо написать и применить политику распространения.

Политика распространения содержит информацию о том, какие ресурсы, на какие кластеры и по какому принципу будет распространять Karmada. Как только мы применим эту политику, Karmada начнет распространять ресурсы по кластерам в соответствии с ее правилами.

Разберем, что такое Karmada Control Plane. По факту — это отдельный кластер Kubernetes, где мы развертываем решение Karmada как обычное приложение в Kubernetes. Набор компонентов, который будет развернут, близок к компонентам самого Kubernetes.

Все компоненты взаимодействуют друг с другом через karmada-apiserver. В том числе и пользователь. Чтобы обращаться к karmada-apiserver, вам потребуется либо плагин для kubectl — kubectl-karmada, либо пакет karmadactl. Обе программы предоставляют практически идентичный набор команд управления. В примерах этой статьи мы будем использовать karmadactl, но приведенные команды подойдут и для kubectl-karmada.

После установки Karmada, вы сможете обратиться как к kube-apiserver кластера, так и к karmada-apiserver. Для обращения к karmada нужно добавить еще один контекст в текущий kubeconfig или создать отдельный kubeconfig.

Администратор может применить файлы манифестов с помощью стандартной команды apply, только нужно указать контекст или kubeconfig karmada:

karmadactl --karmada-context=<контекст karmada-apiserver> apply -f manifest.yaml

Инструмент запускает собственный etcd и в него сохраняет все манифесты, которые пользователь применяет.

karmada-aggregated-apiserver использует технологию Kubernetes API Aggregation Level, чтобы опубликовать Cluster API и прокси эндпоинты. Благодаря этому можно организовать прямой доступ к кластерам-участникам Karmada через Karmada и при этом настроить для них RBAC-политики.

Karmada напрямую не контролирует ресурсы, а назначает ресурсы на кластеры-участники и уже эти кластеры управляют ресурсами собственными силами. Поэтому Karmada не использует контроллеры для deployment, replicaset и прочих ресурсов, но создает и управляет namespace'ами, работает с garbage collector'ом и другими контроллерами. Именно для этого karmada устанавливает собственный kube-controller-manager, который наследует от kube-controller-manager Kubernetes'а часть контроллеров. Подробнее с необходимыми контроллерами можно ознакомиться по ссылке.

Также Karmada создает собственные объекты, например: автоскейлеры, политики распространения. Контроллеры для этих объектов запускает компонент karmada-controller-manager. Полный список контроллеров можно найти в документации.

karmada-scheduler назначает ресурсы на кластеры-участники.

Компонент karmada-webhook проверяет загружаемые манифесты и может их изменять. Де-факто функционал karmada-webhook очень близок к Admission Controller'у.

Кластеры-участники

Кластеры-участники мы можем добавить двумя методами: push и pull.

Если вы добавляете кластер-участник с помощью метода push, то Karmada создает для добавляемого кластера объект cluster, execution namespace, а также обращается к кластеру-участнику, используя его kubeconfig и создает в кластере роли и сервисные аккаунты, чтобы обеспечить доступ к кластеру через Karmada.

Стоит сделать небольшое лирическое отступление про execution namespace. Инструмент позволяет создать отдельный namespace в кластере, где она развернута, причем для каждого кластера-участника. Манифесты этих namespace'ов платформа хранит в собственном etcd. Когда Karmada назначает ресурс на какой-то кластер, то она создает в execution namespace объект Work, который содержит в себе полный манифест или манифесты необходимых ресурсов. При использовании метода push, Execution controller для каждого Work'а применяет соответствующие манифесты к целевому кластеру-участнику через его kube-apiserver.

Метод Push предполагает, что Karmada Control Plane всегда сможет обращаться к кластеру-участнику. Это делает невозможным для Control Plane управлять кластером-участником, который располагается внутри сетевого контура за NAT'ом.

В таких случаях вы можете использовать метод pull. Вам потребуется установить в кластере-участнике karmada-agent с помощью команды karmadactl register.

Агент регистрирует кластер в Karmada Control Plane. Затем karmada-agent будет регулярно обращаться к Karmada Control Plane, смотреть какие объекты типа Work существуют для целевого кластера-участника, загружать соответствующие манифесты и применять их к kube-apiserver кластера локально.

Путь от манифестов в Control Plane до развертывания

Когда мы применяем манифесты в karmada-apiserver, то создаем Resource Template, т. е. сохраняем эти манифесты в etcd.

Чтобы «объяснить» Karmada, какие ресурсы и в каких кластерах-участниках развертывать, нужно создать и применить политику распространения — PropagationPolicy. Манифест PropagationPolicy в etcd тоже сохранится.

Пример PropagationPolicy:

apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
  name: cloudtube-frontend-pp
spec:
  resourceSelectors:
    - apiVersion: apps/v1
      kind: Deployment
      name: frontend-deployment
  placement:
    clusterAffinity:
      clusterNames:
        - evo1
        - evo2

Теперь PropagationPolicy Controller видит, что появились новые объекта типа PropagationPolicy в etcd. Контроллер соотносит ресурсы, указанные в поле resourceSelectors, с имеющимися Resource Templates. Если контроллер находит совпадение, то создает объект ResourceBinding, который связывает ресурс с целевым кластером.

При назначении ресурса, karmada-scheduler может обновить ResourceBinding в соответствии с правилами, которые указаны в placement манифеста PropagationPolicy.

В placement можно указать:

  • clusterAffinity — ограничивает список кластеров для развертывания ресурсов с помощью лэйблов, полей спецификации кластера, имени кластера;

  • clusterTolerations — использует для назначения ресурса систему taints и tolerations;

  • replicaScheduling — определяет принцип распределения реплик между кластерами. Вы можете здесь указать:

    • Duplicated — все реплики дублируются на всех кластерах участниках, указаных в placement;

    • Divided — реплики распределяются между целевыми кластерами-участниками.

Karmada самостоятельно принимает решение, как лучше распределить реплики, но при необходимости вы можете указать вес каждого кластера сами.

Binding Controller обнаруживает новые объекты ResourceBinding и создает в execution namespace для целевых кластеров-участников соответствующие объекты Work. Если ресурс имеет реплики, то контроллер распределяет эти реплики в соответствии с replicaScheduling из PropagationPolicy.

Далее Karmada обращается к kube-apiserver целевых кластеров-участников и создает ресурсы. Способ обращения к kube-apiserver зависит от метода регистрации кластера — push или pull.

Но как быть с тем моментом, что мы имеем несколько разных кластеров-участников? Как минимум, мы захотим указать разные requests и limits для наших ресурсов. Если кластеры запущены на разных платформах, то для каждого кластера нам потребуются манифесты с разными лэйблами, аннотациями, StorageClass'ами и т. д.

Мы можем писать несколько манифестов, которые немного отличаются параметрами и создавать разные PropagationPolicy. Наверное, это сработает, но как будто бы основная идея начинает теряться. Да, централизованное управление остается, но всякая унификация теряется — у нас есть единое окно управления, но каждым кластером мы будем управлять по отдельности и для каждого кластера создавать свои ресурсы. Получаем сомнительные преимущества и хороший такой overhead и путаницу.

Но тут тоже есть находится выход. Чтобы кастомизировать ресурсы под разные кластеры, есть объект OverridePolicy. Вот пример его манифеста:

apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: cloudtube-videos-override
  namespace: default
spec:
  resourceSelectors:
    - apiVersion: apps/v1
      kind: Deployment
      name: videos-deployment
  overrideRules:
    - targetCluster:
        clusterNames:
          - adv-cluster
      overriders:
        imageOverrider:
          - component: Registry
            operator: replace
            value: swr.ru-moscow-1.hc.sbercloud.ru/cloudtube-iosmirnov

Для ресурсов, которые определили в resourceSelector, OverridePolicy позволяет задать правила изменения или добавления полей в манифест ресурса при размещении в определенном кластере. Если OverridePolicy для ресурса определен, Binding Controller применяет правила политики, когда создает Work-объекты. Таким образом, Work-объект одного и того же ресурса может хранить разные манифесты в разных execution namespace.

Устанавливаем Karmada: какие есть нюансы и что с ними делать

Давайте поговорим, как мы можем установить Karmada.

В качестве примера рассмотрим облако Cloud.ru Evolution. А еще дам ссылки на готовые лабораторные работы, чтобы вы смогли повторить всё в точности.

Представим, что у нас есть три кластера:

  • cluster-cp — основной кластер, на котором мы развернем Control Plane;

  • cluster-evo1 — кластер-участник, на котором развернем приложение;

  • cluster-evo2 — кластер-участник, на котором развернем приложение.

Начнем с того, что нам нужно установить Karmada в кластере cluster-cp.

Это можно сделать с помощью:

  • CLI — для установки будем использовать karmadactl или kubectl-karmada. Достаточно подключиться с одним из этих инструментов к кластеру, на которому будете устанавливать Karmada, и выполнить команду karmadactl init. На мой взгляд, это самый неудобный метод, т. к. вы установите минимальный набор компонентов. Дополнительные компоненты придется установить вручную и потом придется заниматься перевыпуском всех сертификатов;

  • Helm — установка выполняется через helm. Пожалуй, самый удобный метод. Известный всем инструмент, кастомизация через чарты, все привычно и комфортно;

  • скрипта установки из репозитория Karmada на GitHub — для развертывания Karmada используется скрипт /hack/remote-up.sh из репозитория Karmada. Устанавливает сразу все компоненты и в дополнении сразу добавляет контекст karmada-apiserver в kubeconfig. Инструмент не такой гибкий как helm, да и не так универсален для применения.

При установке через переменные среды или helm-чарт вам нужно определить как будет предоставляться доступ к karmada-apiserver. Через:

  • HostNetwork — вы будете обращаться непосредственно к воркеру, на котором развернут под karmada-apiserver;

  • LoadBalancer — вы будете обращаться к karmada-apiserver через балансировщик нагрузки.

Но с установкой не все гладко. Как известно — дьявол кроется в деталях.

Когда мы запускаем установку (любым способом) в первую очередь скрипт установки генерирует сертификаты для серверных компонентов с опцией SAN. И вот тут-то и начинаются нюансы.

Во время установки скрипт обращается к karmada-apiserver по IP-адресу (либо узла, либо LoadBalancer'а). Сервис Evolution Managed Kubernetes создает балансировщик нагрузки в облаке автоматически, когда мы создаем в кластере Kubernetes сервис LoadBalancer. IP-адрес балансировщик нагрузки получит во время установки, уже после генерации сертификатов. И скрипт по этому IP-адресу уже не сможет подключиться к karmada-apiserver, т. к. сертификат не сгенерирован.

Мы можем прописать в чарте helm или в скрипте установки IP-адрес как альтернативное имя субъекта и тогда установка успешно завершится. Но, чтобы узнать IP-адрес балансировщика, придется запустить установку хотя бы один раз. Как нам удалось с этим ужиться максимально оптимально — мы описали в лабораторной работе. Если вы решаете эту проблему по другому — напишите, пожалуйста, ваше решение в комментариях, это будет интересно ?

Для HostNetwork эту проблему можно решить чуть проще. Мы заранее знаем IP-адреса узлов и с помощью taints и labels можем четко задать узел, на котором karmada-apiserver нужно будет развернуть и указать этот IP-адрес в явном виде. Но субъективно — конструкция выглядит не очень красиво ?

После установки, в основном кластере добавятся:

  • CRDs,

  • namespace,

  • Deployments,

  • Services,

  • ConfigMaps,

  • Secrets.

Подробнее про установку на официальном сайте. А если вам интересно попробовать развернуть приложение в мультикластере самим, переходите в лабораторную работу.

Автомасштабируемся

Чтобы организовать доступ к приложению, нужно сочесть сра-у несколько подходов к развертыванию мультикластеров и вместе с оркестратором использовать глобальный балансировщик.

Теперь перед нами встает классическая проблема всех веб- и мобильных приложений — необходимо как-то работать с пиковыми нагрузками, т. е. настроить автоматическое масштабирование. Я уже писал про классические подходы к масштабированию в кластере Kubernetes, но как быть с масштабированием в мультикластере?

Получается, необходимо написать манифест hpa, применить его через karmada-apiserver и распространить на кластеры с помощью PropagationPolicy. Но как быть, если в разных кластерах нам нужно масштабировать ресурс в различных диапазонах и с разными порогами срабатывания? Писать для каждого кластера OverridePolicy?

И самая сложная здесь даже не проблема унификации — количество реплик задается объектами Work, а то, что hpa будет перезаписывать количество реплик через kube-apiserver кластера-участника. А, значит, Karmada просто будет перезаписывать и результаты масштабирования hpa и в итоге оно не состоится.

Но на самом деле у Karmada есть собственный инструмент для масштабирования — Federated HPA (FHPA) и он очень похож на манифест hpa:

apiVersion: autoscaling.karmada.io/v1alpha1
kind: FederatedHPA
metadata:
  name: stress-test-fhpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: stress-cpu-deployment
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

Когда мы создаем FHPA, контроллер FHPA начинает регулярно запрашивать метрики через API у karmada-apiserver. karmada-apiserver же перенаправляет эти запросы karmada-metrics-adapter. В свою очередь karmada-metrics-adapter обращается к кластерам-участникам и также по API собирает у них метрики целевых подов, аггрегирует их и передает контроллеру FHPA.

Чтобы эта схема заработала, на каждом кластере-участнике обязательно нужно развернуть metrics-server. Контроллер FHPA высчитывает желаемое количество метрик по стандартному алгоритму HPA. Если контроллер изменяет желаемое количество метрик, то новое значение он записывает в манифест ресурса в etcd через karmada-apiserver. Затем Karmada использует свои стандартные механизмы распространения, которые мы обсуждали выше. А еще —предлагает объект CronFederatedHPA. Пример манифеста:

apiVersion: autoscaling.karmada.io/v1alpha1
kind: CronFederatedHPA
metadata:
  name: nginx-cronfhpa
  namespace: default
spec:
   scaleTargetRef:
      apiVersion: apps/v1
      kind: Deployment
      name: nginx
   rules:
   - name: "scale-up"
     schedule: "*/1 * * * *"
     targetReplicas: 5
     suspend: false

CronFederatedHPA позволяет масштабировать нагрузку по расписанию. В манифесте видно, что для задания расписания используется стандартный синтаксис cron. Этот тип масштабирования полезен, если вы знаете время пиковой нагрузки и можете масштабировать ресурсы заранее. Например, развернули в облаке интернет-магазин и знаете, что основной наплыв клиентов с 8:00 до 17:00 и в это время нужно масштабировать ресурсы. Тогда вы создаете CronFHPA, которые будут масштабировать нагрузки вверх в 8:00, а затем уменьшать количество реплик в 17:00.

Но что, если количество реплик будет недостаточным и нагрузка окажется выше и то количество реплик, которое мы развернули с ней не справится? Или наоборот — в какой-то из дней нагрузка окажется ниже прогнозируемой и потратятся лишние ресурсы? Поэтому добавим в эту формулу FHPA, чтобы иметь возможность более гибко масштабировать нагрузку. Однако сложность в том, что если мы пропишем какой-то ресурс в качестве масштабируемого и в CronFHPA, и в FHPA, то мы получим непредсказуемый результат. Как тогда быть?

На самом деле лучше собрать следующую схему: CronFHPA масштабирует по расписанию минимальное или максимальное количество реплик FHPA, а FHPA уже масштабирует целевой ресурс. Теперь в случае с интернет-магазином с помощью CronFHPA мы будем изменять минимальное количество реплик в манифесте FHPA, а в 17:00 будем снижать его обратно. Так, на время пика мы изменим интервал масштабирования, подняв его нижнюю границу, но при этом позволим FHPA гибко масштабировать ресурсы в зависимости от нагрузки в рамках интервала.

Обеспечиваем отказоустойчивость

Теперь последний шаг. Если наше приложение mission-critical, то нужно еще настроить отказоустойчивость.

В первую очередь необходимо активировать отказоустойчивость в karmada-controller-manager. Для этого в deployment'е karmada-controller-manager добавляем:

...
spec:
  containers:
  - name: karmada-controller-manager
    command:
    - /bin/karmada-controller-manager
    args:
    - --feature-gates=Failover=true,GracefulEviction=true
    - --failover-eviction-timeout=300s

Затем в PropagationPolicy указываем следующие параметры:

...
spec:
  ...
  failover:
    application:
      decisionConditions:
        tolerationSeconds: 10
      purgeMode: Immediately

В purgeMode вы можете указать, как лучше удалять «старую» версию ресурса, который переносится на другой кластер:

  • Immediately/Direcly — удаляется сразу;

  • Gracefully — перед удалением ждем, когда новый ресурс станет healthy или закончится GracePeriodSeconds.

Также параметр statePreservation позволяет извлечь часть данных переносимого ресурса и вставить их в новую версию. Какие именно данные стоит извлечь, вы можете указать с помощью JSONPath-правил. Этот параметр выручает при переносе stateful-приложений.

Заключение

Итак, мы прошлись от самых азов до настройки и эксплуатации настроенного приложения, и попутно обсудили все нюансы и подводные камни, а также, какими способами можно их решить. При этом мы намеренно не рассматривали сетевую связанность в мультикластерах, ведь это большой отдельный мир. Но если вам интересно погрузиться в мультикластерные сети — в комментариях пишите, какие нюансы и этапы настройки будет актуально разобрать ?

А еще смотрите мое выступление на GoCloud Tech — IT-конференции про облака и AI.

Комментарии (0)