Наткнулся на интересный материал про тестирование GitOps на масштабируемость и нагрузку. Его целых три недели проводила компания IITS Consulting. Оригинал читать не меньше 40 минут, поэтому сократил его, сохранив все самое важное, — и теперь делюсь со всеми обитателями Хабра.

Если совсем нет времени читать, то вот коротко: управление кластерами тестировали на основе Argo CD, vCluster, kubara и Sveltos. В итоге контроллер приложений Argo CD начинал сталкиваться с OOM-завершениями примерно при 15 000–20 000 кешированных объектов на хаб. Развернутые манифесты помогали, настройка помогала лишь частично. При этом Sveltos обрабатывал сценарии развертывания типа аддонов при значительно меньшем потреблении памяти — примерно 2 ГБ против 21 ГБ. Основной вывод: при очень больших масштабах архитектура важнее тонкой настройки. 

А теперь подробности. 

Что хотели выяснить

Большинство платформ Kubernetes и инструментов GitOps предназначены для работы с 10–300 кластерами. Но периферийным сетям, розничной торговле, телекоммуникациям, супермаркетам и другому бизнесу требуется от 1 000 до 10 000 кластеров. Выдержит ли инфраструктура? Сколько кластеров вообще можно обслуживать осмысленным образом?

Поступил амбициозный запрос: поддержать работу более 15 000 кластеров и свыше 75 000 приложений во всем мире. Для этого в iits-consulting разработали фреймворк GitOps под названием kubara. Он основан на архитектуре «хаб-и-спицы». С его помощью хотели понять ограничения в большом масштабе, чтобы принимать более правильные архитектурные решения и для меньших сред.

Как создали среду 

Тестовую среду запустили на управляемом кластере Kubernetes от STACKIT. Сервис основан на Gardener и называется STACKIT Kubernetes Engine (SKE). Кластер работал на версии Kubernetes 1.35.4. Использовали несколько пулов узлов.

Настройка среды
Настройка среды

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

Kubara инициализирует кластер хаба и управляет компонентами платформы через Argo CD
Kubara инициализирует кластер хаба и управляет компонентами платформы через Argo CD

Что происходит на этой диаграмме:

  1. Kubara создавал каталог компонентов платформы на основе общих (umbrella) Helm-диаграмм. 

  2. Он инициализировал Argo CD и позволял ему управлять собой через этот каталог.

  3. Подключение к Vault устанавливалось через External Secrets Operator (ESO)

  4. На основе меток и генератора кластеров ApplicationSet Argo CD развертывал и управлял различными компонентами платформы: Traefik, cert-manager, external-dns.

Затем эту конфигурацию расширили: создали общие (umbrella) Helm-диаграммы для vCluster и vCluster Platform и добавили их как компоненты платформы.

Расширение конфигурации kubara с помощью vCluster и vCluster Platform
Расширение конфигурации kubara с помощью vCluster и vCluster Platform

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

1. Развертывать любое количество кластеров по требованию.

2. Подключать любое количество кластеров.

3. Развертывать любое количество приложений в этих кластерах.

Для решения первой задачи расширили среду с помощью паттерна App of Apps. Его суть в том, чтобы создать много приложений Argo CD и развертывать их одновременно.

Использование паттерна App of Apps для создания множества виртуальных кластеров с помощью Argo CD
Использование паттерна App of Apps для создания множества виртуальных кластеров с помощью Argo CD

Вторую задачу можно было решить двумя путями. Первый — получить kubeconfig, отправить его в Vault, создать ExternalSecret, добавить метки и позволить Argo CD развертывать приложения на основе полученных генераций. Это трудоемко.

Второй вариант — использовать vCluster Platform вместе с Argo CD Connector. Тогда платформа будет создавать виртуальные кластеры из пользовательского ресурса VirtualClusterInstance.

Это удобнее, потому что коннектор автоматически устанавливает соединение между Argo CD и созданными виртуальными кластерами. Конечная точка при этом защищается интеграцией с Tailscale.

В итоге серия тестов показала, где находится предел для open-source-версии Argo CD в архитектуре «хаб-и-спицы». Вот так она выглядела:

Архитектура для управления кластером на базе GitOps
Архитектура для управления кластером на базе GitOps

Как это работало

К описанной выше среде на базе kubara добавили несколько скриптов для имитации различных сценариев поведения. Первый шаг — создание vCluster. Для этого использовали уже известный паттерн App of Apps и сгенерированные Argo CD приложения.

Генерация приложений Argo CD для vCluster
Генерация приложений Argo CD для vCluster
./scripts/1-create-applications.sh 5

Generating 5 Argo CD Application manifests from scripts/app-vcluster-template.yaml
vcluster-1 -> apps/vcluster-1.yaml
vcluster-2 -> apps/vcluster-2.yaml
vcluster-3 -> /Users/artemlajko/git/15-04-2025/new/demos/scale-tests-with-1000-vclusters-based-on-kubara-2026/apps/vcluster-3.yaml
vcluster-4 -> /Users/artemlajko/git/15-04-2025/new/demos/scale-tests-with-1000-vclusters-based-on-kubara-2026/apps/vcluster-4.yaml
vcluster-5 -> apps/vcluster-5.yaml
Generated 5 manifests in apps

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

./scripts/1-create-applications.sh --virtual 5

Generating 5 VirtualClusterInstance manifests from /scripts/virtualclusterinstance-template.yaml
vcluster-1 -> /apps/virtualclusterinstance-1.yaml
vcluster-2 -> /apps/virtualclusterinstance-2.yaml
vcluster-3 -> /apps/virtualclusterinstance-3.yaml
vcluster-4 -> /apps/virtualclusterinstance-4.yaml
vcluster-5 -> /apps/virtualclusterinstance-5.yaml
Generated 5 manifests in /apps

Второй шаг — получить файлы kubeconfig и отправить их в Vault.

Получение файлов kubeconfig для vCluster и их сохранение в Vault
Получение файлов kubeconfig для vCluster и их сохранение в Vault
./scripts/2-sync-vclusters.sh 5

Logging in to Vault...
Received Vault token
Processing vClusters from 1 to 5 (parallelism=1)
[vcluster-1] Generating kubeconfig via vcluster-1.controlplane-dev.stackit.run
[vcluster-1] Kubeconfig generated
[vcluster-2] Generating kubeconfig via vcluster-2.controlplane-dev.stackit.run
...
[vcluster-4] Kubeconfig generated
[vcluster-5] Generating kubeconfig via vcluster-5.controlplane-dev.stackit.run
[vcluster-5] Kubeconfig generated
Reading current Vault secret my_clusters
Writing 5 kubeconfig(s) to Vault secret my_clusters
Synchronized 5 vClusters

Этот шаг требуется, только когда vCluster развертываются с помощью поставщика Helm-диаграмм. 

Третий шаг — подключить кластеры к Argo CD и развернуть приложения на основе меток.

Подключение vCluster к Argo CD и применение меток
Подключение vCluster к Argo CD и применение меток
./scripts/3-generate-values.sh 5 > customer-service-catalog/helm/controlplane/argo-cd/values.yaml

Остальное берет на себя kubara. Он создает ExternalSecrets с необходимыми метками, извлекает kubeconfig-файлы и позволяет Argo CD использовать их для целевого развертывания.

При использовании vCluster Platform второй шаг можно пропустить. Argo CD Connector автоматически устанавливает соединение с vCluster. В этом случае нужно лишь добавить метки.

Повторное использование подключения к платформе vCluster и применение меток
Повторное использование подключения к платформе vCluster и применение меток
./scripts/12-argocd-deploy-applications.sh "kro=enabled"

Excluded: cluster-vcluster-platform.controlplane-dev.stackit.run-52690538
Dry run: false
Applying labels:
  - kro=enabled
  argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3735921280
  argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3752698899
  argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3769476518
  argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3836586994
  argocd/cluster-vcluster-platform.controlplane-dev.stackit.run-3853364613

Вот так это выглядит в пользовательском интерфейсе Argo CD.

Пользовательский интерфейс Argo CD, отображающий ресурсы vCluster и VirtualClusterInstance

Также эту идею протестировали со Sveltos.

./scripts/4-register-sveltos-clusters.sh 5

[vcluster-1] Merging kubeconfig
[vcluster-1] Registering in namespace vcluster-1
cluster vcluster-1 successfully registered/updated in namespace vcluster-1.
[vcluster-2] Generating kubeconfig via vcluster-2.controlplane-dev.stackit.run
[vcluster-2] Merging kubeconfig
[vcluster-2] Registering in namespace vcluster-2
cluster vcluster-2 successfully registered/updated in namespace vcluster-2.
[vcluster-3] Generating kubeconfig via vcluster-3.controlplane-dev.stackit.run
...
[vcluster-5] Merging kubeconfig
[vcluster-5] Registering in namespace vcluster-5
cluster vcluster-5 successfully registered/updated in namespace vcluster-5.
Registered 5 vClusters in Sveltos (parallelism=1)

Чтобы проверить, работает ли — использовали это:

kubectl get clustersummaries.config.projectsveltos.io -A -o wide

NAMESPACE    NAME                              AGE   HELMCHARTS    KUSTOMIZEREFS   POLICYREFS
vcluster-1   cert-manager-sveltos-vcluster-1   85s   Provisioned
vcluster-2   cert-manager-sveltos-vcluster-2   83s   Provisioned
vcluster-3   cert-manager-sveltos-vcluster-3   82s   Provisioned
vcluster-4   cert-manager-sveltos-vcluster-4   78s   Provisioned
vcluster-5   cert-manager-sveltos-vcluster-5   78s   Provisioned

Результаты тестирования

Non-HA- и HA-конфигурации

В начальных Non-HA-тестах (одна реплика контроллера; лимит памяти — 12 ГБ) первые ошибки OOM-завершения появлялись на шестой итерации. Зафиксировали такой результат:

30 vCluster, 186 приложений, 6 300 объектов и 420 долго работающих подов, включая рабочие нагрузки и vCluster. Этого уже достаточно для многих целей. Если вы работаете в меньшем масштабе или хотите сэкономить, вам не обязательно сразу использовать HA-конфигурацию.

Использование WET YAML-манифестов показало себя лучше, чем использование DRY Helm-диаграмм: нагрузка на репо-сервер была существенно ниже.

Сравнение использования памяти в режимах WET и ​​DRY
Сравнение использования памяти в режимах WET и ​​DRY

В HA-конфигурации с тремя репликами контроллера, автоматическим масштабированием и лимитом 12 ГБ памяти удалось выйти на такой результат: 150 vCluster, 742 приложения и 16 700 объектов. После этого появлялись ошибки OOM-завершения. 

Снятие лимитов памяти лишь отсрочило проблему: контроллеры потребляли до 21 ГБ RAM, затем кластер становился нестабильным.

Тесты показали: проблема не в количестве кластеров или приложений, а в количестве объектов, которое Argo CD кеширует и обрабатывает. Барьер — примерно 15 000–17 000 объектов.

Тонкая настройка (Finetuning)

Вот что сделали тестировщики для оптимизации:

  • Увеличили число воркеров (--status-processors=50, --operation-processors=25).

  • Использовали алгоритм шардирования consistent-hashing.

  • Настроили переменные окружения для управления кешем и пакетной обработкой событий.

  • Увеличили количество шардов с трех до шести.

Так получилось улучшить пропускную способность и глубину очередей, но фундаментально проблема не решилась. При достижении 18 000–20 000 объектов один из контроллеров неизбежно сталкивался с ошибкой OOM-завершения. Другие не брали на себя его работу, и его шард переставал синхронизироваться. 

Обзор итераций, о которых идет речь
Обзор итераций, о которых идет речь

Это значит, что для масштаба более 1 000 кластеров и 5 000–10 000 тяжелых приложений один хаб Argo CD не подходит просто из-за архитектурных ограничений. Поэтому для таких задач лучше разделять нагрузку между несколькими хабами или использовать энтерпрайз-решения вроде Akuity Platform или Octopus Deploy.

Sveltos

Sveltos — контроллер для управления аддонами, который работал поверх Argo CD. Он брал на себя развертывание приложений на целевых кластерах, а Argo CD управлял только самим Sveltos и его ресурсами.

Результаты впечатлили. При развертывании 600 приложений на 150 vCluster Sveltos использовал около 2 ГБ памяти. В то же время Argo CD в аналогичных тестах потреблял до 21 ГБ. И это притом что Sveltos работал с одной репликой.

Расширение стандартной конфигурации kubara с помощью Sveltos
Расширение стандартной конфигурации kubara с помощью Sveltos

Вот результаты тестов Sveltos с увеличением нагрузки:

  • 1 000 приложений (250 кластеров) — около 70 минут (в DRY-режиме с Helm).

  • 1 000 приложений с шардированием — время сократилось примерно до 35 минут.

  • 1 000 приложений в WET-режиме (сгенерированные манифесты) — около 17 минут.

  • 2 000 приложений (500 кластеров) — приблизительно 36–43 минуты.

  • 5 000 приложений (1000 кластеров) — тест остановили примерно на 4 300 приложениях из-за нехватки бюджета. Инфраструктура стоила уже больше 120 000 евро, но Sveltos продолжал работать.

Безусловно, Sveltos гораздо эффективнее. Технически контроллер способен управлять более чем 15 000 кластеров и более чем 75 000 приложений с одного хаба, но такая архитектура нецелесообразна из соображений надежности. А вот комбинация Argo CD и Sveltos — вполне перспективный подход для крупномасштабных сред.

kubara

Начальная настройка kubara — отличная отправная точка, но, когда растет число кластеров и приложений, возникает множество узких мест. Следует пересмотреть ресурсы и архитектуру не только для Argo CD, но и для мониторинга, External Secrets Operator, сетевых контроллеров и других компонентов.

Дело в том, что архитектура важнее тонкой настройки. Попытка заставить один хаб управлять всем приводит к ошибкам OOM-завершения и простою. Решит проблему разделение нагрузки на 5–10 хабов по географическому, организационному или иному принципу.

Что это значит на практике

Так как конечная цель — не просто создать 15 000 кластеров, а сделать их работу безопасной и предсказуемой, имеет смысл проектировать систему на основе 5–10 хабов. Их можно сгруппировать по бизнес-юнитам, регионам или этапам жизненного цикла. Это снизит риски, упростит операции и оставит пространство для роста.

Что важно помнить:

  • Объекты — главный враг масштаба. Их количество имеет большее значение, чем число кластеров или приложений.

  • У тонкой настройки есть пределы. Если вы уперлись в архитектурный потолок, она не поможет.

  • Гибридные подходы работают. Использовать Argo CD для платформы и Sveltos для приложений — разумно при масштабировании.