
Kubernetes — это не просто оркестратор контейнеров, а целая экосистема инструментов, которые позволяют построить PaaS без написания кода. Helm, ArgoCD, Crossplane, Knative и другие решения делают управление приложениями и инфраструктурой настолько простым, что разработка собственной платформы превращается в задачу конфигурации, а не программирования. Меня зовут Сергей Емельянов, я техлид команды в VK Tech, которая занимается созданием PaaS-платформы на базе Kubernetes для упрощения работы с данными. В серии статей разберем, как создать PaaS, используя мощь Kubernetes и его экосистему.
Чтобы превратить Kubernetes в PaaS, нужен сам кластер. Но наша цель в этой статье — не учиться разворачивать Kubernetes с нуля, а показать, как сделать из него удобный PaaS. Поэтому я рекомендую взять управляемый кластер у облачного провайдера. Они дают нужные готовые решения из коробки, которые экономят время и нервы:
-
Load Balancer: нам нужно как-то направить внешний трафик внутрь кластера. Создаем сервис, получаем IP-адрес, и можно заходить.
-
Сетевые диски: постоянное хранилище для данных (типа Persistent Volumes) уже вшито в инфраструктуру. Подключаешь к подам — и готово, никаких танцев с NFS.
С таким подходом мы сразу получаем рабочую базу и можем сосредоточиться на создании PaaS, а не на настройке bare-metal-кластера. Дальше — только наши PaaS-компоненты поверх.
Подготовка
Предположим, кластер у нас уже настроен, а в домашней директории лежит kube-config — все готово для работы. Первым делом проверим и установим нужные утилиты (если их еще нет):
-
kubectl: главный ключ к управлению Kubernetes. Это как швейцарский нож для кластера: позволяет запускать команды, проверять статус подов, деплоить ресурсы. Без него никуда.
-
Helmwave: удобный инструмент для управления Helm-чартами и их деплоя в кластер. Изначально я думал взять Terraform, но он спотыкается на Custom Resources (CRD): вылезают ошибки, потому что он не всегда понимает, что это такое, да и работает заметно медленнее. Helmwave же справляется с этим чище и быстрее.
С этими утилитами мы можем двигаться дальше и строить платформу поверх нашего кластера. Вот как это будет выглядеть — на схеме ниже показаны ключевые компоненты, из которых соберется наша платформа:

Схема делит нашу платформу на три основных блока, чтобы показать, как все работает вместе:
1. PaaS System. Это основа платформы, куда входят ключевые элементы для работы всех пользователей. Здесь:
-
Gateway — отвечает за маршрутизацию внешнего трафика в кластер — через него заходят запросы к сервисам.
-
IAM — система авторизации и аутентификации, которая решает, кто имеет доступ и что может делать.
-
Observability — группа инструментов для мониторинга и анализа:
-
Dashboard — визуализация данных;
-
Logs — сбор и анализ логов для аудита и отладки;
-
Metrics — метрики производительности.
2. PaaS Operator. Здесь живут операторы Kubernetes, которые автоматизируют управление ресурсами и кастомными объектами. На схеме три оператора (Operator 1, 2, 3), каждый из которых отвечает за определенные типы приложений.
3. Tenant-1. Это пример пространства для конкретного пользователя или команды (тенанта). Здесь:
-
PaaS UI — простой интерфейс для пользователей, чтобы можно было управлять приложениями без терминала;
-
App 1 и App 2 — приложения или сервисы, которые запускает тенант, например ETL-пайплайны или дашборды для данных.
-
Gateway
Тут я решил использовать Envoy Gateway для нашей платформы по следующим причинам:
-
Просто захотелось попробовать. Стало любопытно опробовать новейший Kubernetes Gateway API и мощь Envoy, раньше его не «крутил».
-
Kubernetes Gateway API (свежий стандарт Envoy Gateway) — одна из лучших реализаций нового Kubernetes Gateway API (выйти в GA 1.0 в 2023 году), который заменяет устаревший Ingress. Это дает гибкую декларативную маршрутизацию и управление трафиком для нашей платформы.

Устанавливаем Envoy Gateway с помощью Helmwave
В рабочей директории создаем файл helmwave.yml и добавим в него описание чарта для Envoy Gateway.
helmwave.yaml project: kube-paas version: "0.41.8" registries: - host: docker.io .options-system: &options-system namespace: paas-system create_namespace: true wait: true timeout: 1m max_history: 3 releases: - name: "eg" chart: name: oci://docker.io/envoyproxy/gateway-helm <<: *options-system tags: [eg]
Применим его:
helmwave up -t eg --build --kubedog
Эта команда соберет манифесте (флаг —build) и применит (команда up) их в кластер. Добавлю небольшие уточнения:
-
опция -t позволяет запускать запускать только нужные релизы;
-
флаг —kubedog позволяет отслеживать состояние Job, Pod, Deployment и так далее во время установки релиза.
Добавляем GatewayClass для работы с Envoy Gateway
Чтобы мы могли добавлять Gateway ресурсы и управлять маршрутизацией трафика через Envoy Gateway, нужно сразу настроить нужный GatewayClass. Для этого создадим Helm-чарт PaaS-system и добавим в него шаблон gateway.yaml. Вот как это сделать:
1. Создаем Helm-чарт PaaS-system.
helm create paas-system
2. В папке paas-system/templates создаем файл gateway.yaml с описанием GatewayClass для Envoy Gateway. Вот пример:
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: envoy-gateway-class spec: controllerName: gateway.envoyproxy.io/gatewaycontroller Этот GatewayClass указывает, что Envoy Gateway будет управлять нашими шлюзами. Контроллер gateway.envoyproxy.io/gatewaycontroller связывает его с уже установленным Envoy Gateway.
3. Добавляем этот чарт в наш helmwave.yml, чтобы Helmwave развернул его в кластере.
release: ... - name: "system" chart: name: "./paas-system" <<: *options-system tags: [system]
4. Затем запускаем:
helmwave up -t system --build
Чтобы определить, как мы будем направлять трафик внутрь кластера, создадим специальный Helm-чарт. Этот чарт добавит Gateway для маршрутизации, HTTPRoute для доступа к PaaS UI и поддержку TCPRoute для подключения к развернутым сервисам.

Когда мы добавляем Gateway и HTTPRoute в неймспейс тенанта (например, paas-tenant-1), это триггерит Envoy-Gateway-контроллер в неймспейсе PaaS-system. Контроллер:
-
Создает Load Balancer для внешнего доступа.
-
Разворачивает Deployment, которое следит за конфигурацией Gateway и направляет трафик:
-
через HTTPRoute к PaaS UI;
-
через TCPRoute к другим сервисам тенанта. Это обеспечивает гибкую маршрутизацию трафика внутрь кластера для каждого тенанта.
-
Этот подход позволяет нам изолировать трафик для каждого тенанта и легко масштабировать платформу, добавляя новые чарты и неймспейсы по мере необходимости.
Точный код манифестов доступен в репозитории.
PaaS UI
Выбираем PaaS UI для создания приложений
Пришло время выбрать PaaS UI, который позволит нам создавать приложения для наших тенантов. Мы остановились на Cyclops UI по нескольким причинам. Во-первых, его интерфейс интуитивно понятен, а во-вторых, он прост в использовании. Cyclops UI позволяет разворачивать и управлять приложениями в Kubernetes без написания манифестов вручную, что идеально соответствует нашей цели — создать простой PaaS.

Единственный минус — отсутствие встроенной авторизации. Однако мы можем временно решить эту проблему с помощью Envoy Gateway, настроив базовую аутентификацию (basic-auth) для каждого тенанта, таким образом наша схема для тенант Gateway обновится, добавится Security Policy и Secret.

Cyclops UI состоит из двух ключевых компонентов, которые обеспечивают его функциональность:
-
Module: Это единица управления, которая объединяет все необходимые Kubernetes-ресурсы для работы приложения, такие как Deployment, Service или Ingress. Мы используем Module, чтобы упрощенно создавать, обновлять или удалять приложения через интерфейс, избегая ручной работы с манифестами.
-
TemplateStore: Это хранилище шаблонов, которое определяет, как значения из Module преобразуются в корректные Kubernetes-манифесты. Мы можем хранить шаблоны как Helm-чарты, в Git или непосредственно в Cyclops, указывая их версии для контроля изменений, что ускоряет разворачивание типовых приложений.
Добавляем CRD для Cyclops UI в PaaS-system
Поскольку Module и TemplateStore являются Custom Resource Definitions (CRD), которые Cyclops UI использует для управления приложениями, их нужно установить на уровне всего кластера. Мы добавим эти CRD в один файл cyclops-ui.yaml в папке templates чарта PaaS-system и обновим конфигурацию.
1. Создание файла cyclops-ui.yaml
В папке PaaS-system/Templates создаем файл cyclops-ui.yaml и добавляем в него определения CRD. Взять их можно отсюда: cyclops-install.yaml.
2. Развертывание через Helmwave
Запускаем:
helmwave up -t system --build
3. Проверка установки CRD
После применения проверяем, что CRD установлены:
kubectl get crd | grep cyclops-ui
Должны отобразиться modules.cyclops-ui.com и templatestores.cyclops-ui.com. Теперь Cyclops UI может использовать эти CRD для управления приложениями в любом неймспейсе.
Создаем Helm-чарт paas-tenant для Cyclops UI
Следующий этап — создание Helm-чарта paas-tenant, который развернет все необходимые ресурсы для работы Cyclops UI и управления тенантом. Все манифесты мы разместим в одном шаблоне cyclops-ui.yaml. Вот что нужно сделать:
-
Создание Helm-чарта
-
Инициализируем чарт с помощью helm create paas-tenant.
-
-
Добавление ресурсов в cyclops-ui.yaml
В папке paas-tenant/templates создаем файл cyclops-ui.yaml, который включает:-
Role, RoleBinding и ServiceAccount для управления доступом внутри неймспейса;
-
Deployment и Service для Cyclops UI — основного интерфейса;
-
Deployment и Service для Cyclops Ctrl — контроллера для управления;
-
Module с Gateway, на который реагирует Envoy-Gateway-контроллер для маршрутизации трафика.
-

Точный код манифестов доступен в репозитории.
-
3. Развертывание через Helmwave
-
Добавляем чарт в helmwave.yml с указанием неймспейса paas-tenant-1.
-
release: ... - name: "tenant-1" namespace: "paas-tenant-1" chart: name: "./paas-tenant" <<: *options-tenant tags: [tenant-1]
Запускаем helmwave up для применения.
helmwave up -t tenant-1 --build --kubedog
-
4. Проверка и доступ к UI
-
Дожидаемся, пока Gateway получит IP-адрес, с помощью команды
kubectl get gateway -w -n paas-tenant-1.
-
После появления IP-адреса заходим в Cyclops UI по url http://<IP>:8000, используя логин и пароль (например, admin/admin), настроенные ранее через basic-auth. Тут мы видим установленный один модуль с нашим Gateway и можем посмотреть, какие объекты он в себя включает.
-

Выбираем первый сервис для PaaS: PostgreSQL
Теперь нам нужно выбрать первый сервис, который мы будем предоставлять в нашей PaaS-платформе. Мы остановились на PostgreSQL, потому что «база — это база». PostgreSQL универсален, надежен и может использоваться как для других общих сервисов, так и для хранения данных приложений.
В CloudNative Landscape есть несколько операторов для PostgreSQL, из которых мы рассматривали два варианта: CloudNativePG и Percona. Мы выбрали CloudNativePG по следующим причинам:
-
Percona нам уже знакома, я с ней работал ранее, но она не показалась достаточно интересной для эксперимента.
-
CloudNativePG, напротив, это новый для меня инструмент, который я решил попробовать, чтобы изучить его возможности и подходы к управлению PostgreSQL в Kubernetes.
Этот выбор позволяет нам добавить PostgreSQL как ключевой сервис для тенантов, а использование CloudNativePG дает возможность протестировать современный оператор в нашей PaaS-платформе. Конечная схема первой части будет выглядит следующим образом:

Устанавливаем оператор CloudNativePG
Прежде чем разворачивать PostgreSQL, нам нужно установить оператор CloudNativePG, который обеспечит управление базой данных в Kubernetes. Мы сделаем это через Helmwave, добавив репозиторий и настроив отдельный релиз. Вот что нужно сделать:
-
добавляем официальный Helm-репозиторий CloudNativePG в конфигурацию Helmwave;
-
создаем релиз оператора в неймспейсе PaaS-operators через helmwave.yml;
-
запускаем helmwave up -t cnpg —build —kubedog для установки.
repositories: - name: cnpg url: https://cloudnative-pg.github.io/charts ... releases: ... - name: "cnpg" chart: name: cnpg/cloudnative-pg <<: *options-operators tags: [cnpg]
Теперь у нас установлен CloudNativePG, и мы можем использовать его для управления PostgreSQL в нашей PaaS-платформе.
Создаем Helm-чарт как шаблон модуля для Cyclops UI
Следующий шаг — создание Helm-чарта, который будет использоваться как шаблон модуля для Cyclops UI, чтобы развернуть PostgreSQL с поддержкой маршрутизации и защиты. Мы назовем чарт paas-tenant-pg и разместим все ресурсы в одном шаблоне postgres.yaml. Вот что нужно сделать:
-
Создание Helm-чарта
-
Инициализируем чарт с помощью команды helm create paas-tenant-pg.
-
-
Добавление ресурсов в postgres.yaml
В папке paas-tenant-pg/templates создаем файл postgres.yaml, который включает:-
Cluster — ресурс для настройки PostgreSQL с помощью CloudNativePG;
-
Pooler — CRD для создания пулов подключений к PostgreSQL через CloudNativePG;
-
TCPRoute — для маршрутизации трафика в Pooler, обеспечивающий доступ к базе данных;
-
Secret с паролем для PostgreSQL — чтобы защитить доступ.
-

Точный код манифестов доступен в репозитории.
-
3. Отправка в Git
-
После создания чарта и шаблона отправляем его в репозиторий Git для дальнейшего использования.
-
На этом этапе мы только создаем и сохраняем шаблон, чтобы затем зарегистрировать его в Cyclops UI через TemplateStore.
Добавляем TemplateStore в чарт paas-tenant
Теперь, когда чарт готов и сохранен в Git, нам нужно зарегистрировать его в Cyclops UI, чтобы он стал доступен как модуль для разворачивания PostgreSQL. Для этого мы добавим CR TemplateStore в чарт paas-tenant и обновим его.
-
Добавление TemplateStore в cyclops-ui.yaml. В папке paas-tenant/templates открываем существующий файл cyclops-ui.yaml и добавляем в него TemplateStore:
TemplateStore, который указывает на наш шаблон в Git, чтобы Cyclops UI мог использовать его для создания модулей.
apiVersion: cyclops-ui.com/v1alpha1 kind: TemplateStore metadata: annotations: cyclops-ui.com/icon: https://www.postgresql.org/media/img/about/press/elephant.png name: paas-pg spec: path: part-01/paas-tenant-pg repo: https://gitverse.ru/emelianovss/paas-kube-article.git version: master sourceType: git
Точный код манифеста доступен в репозитории.
-
2. Обновление через Helmwave
-
Запускаем
helmwave up -t paas-tenant-1 --build
для применения изменений.
-
-
3. Проверка доступности шаблона
-
Проверяем, что TemplateStore зарегистрирован, с помощью команды
kubectl get templatestores -n paas-tenant-1.
-
Заходим в Cyclops UI и убеждаемся, что шаблон PostgreSQL появился в списке доступных модулей.
-

Теперь у нас есть шаблон PostgreSQL, который мы можем использовать через Cyclops UI для разворачивания базы данных в любом тенанте.
Создаем первое приложение: разворачиваем PostgreSQL
Последний этап — создание первого приложения в нашей PaaS-платформе с использованием PostgreSQL. Мы начнем с настройки модуля PaaS-gateway и добавим новый модуль для базы данных. Вот что нужно сделать:
-
Добавление TCP Listener в модуль PaaS-gateway:
-
Открываем существующий модуль PaaS-gateway в Cyclops UI и добавляем TCP Listener.
-
Задаем ему имя и порт, запоминаем его и нажимаем на кнопку Deploy.
-
После этого на Load Balancer появится новый порт для обработки TCP-трафика.
-

-
2. Создание модуля для PostgreSQL
-
В Cyclops UI создаем новый модуль, указав тип PaaS-pg, и задаем ему имя.
-
Указываем параметры базы данных: имя, пользователь и другие настройки, а также название TCP Listener, добавленного в шаге 1.
-
Нажимаем на кнопку Deploy, и Cyclops UI разворачивает PostgreSQL через шаблон paas-tenant-pg.
-


-
3. Проверка и подключение к базе
-
Дожидаемся успешного развертывания и настройки PostgreSQL, проверяя статус модуля в Cyclops UI.
-
Используем IP-адрес Load Balancer и новый порт для подключения к базе с указанными учетными данными.
-
psql -U admin -h <IP> -p 10000 -d example Password for user admin: psql (12.20 (Debian 12.20-1.pgdg120+1), server 17.2 (Debian 17.2-1.pgdg110+1)) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) Type "help" for help. example=> select 1; ?column? ---------- 1 (1 row)
Теперь у нас работает первое приложение — PostgreSQL, доступное через изолированный трафик для тенанта, что завершает настройку нашей PaaS-платформы.
На этом первая часть нашей серии статей завершена. В следующей статье мы добавим важный компонент — IAM для полноценной авторизации, а также подключим первый общий сервис, чтобы расширить функциональность нашей PaaS-платформы.
ссылка на оригинал статьи https://habr.com/ru/articles/895954/
Добавить комментарий