Kubernetes как PaaS: максимум возможностей без разработки. Часть 1

от автора

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 же справляется с этим чище и быстрее.

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

Архитектура PaaS на Kubernetes

Архитектура PaaS на Kubernetes

Схема делит нашу платформу на три основных блока, чтобы показать, как все работает вместе:

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 для нашей платформы по следующим причинам:

  1. Просто захотелось попробовать. Стало любопытно опробовать новейший Kubernetes Gateway API и мощь Envoy, раньше его не «крутил».

  2. Kubernetes Gateway API (свежий стандарт Envoy Gateway) — одна из лучших реализаций нового Kubernetes Gateway API (выйти в GA 1.0 в 2023 году), который заменяет устаревший Ingress. Это дает гибкую декларативную маршрутизацию и управление трафиком для нашей платформы.

Архитектура PaaS на Kubernetes

Архитектура PaaS на Kubernetes

Устанавливаем 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 для tenant

Gateway для tenant

Когда мы добавляем Gateway и HTTPRoute в неймспейс тенанта (например, paas-tenant-1), это триггерит Envoy-Gateway-контроллер в неймспейсе PaaS-system. Контроллер:

  1. Создает Load Balancer для внешнего доступа.

  2. Разворачивает Deployment, которое следит за конфигурацией Gateway и направляет трафик:

    • через HTTPRoute к PaaS UI;

    • через TCPRoute к другим сервисам тенанта. Это обеспечивает гибкую маршрутизацию трафика внутрь кластера для каждого тенанта.

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

Точный код манифестов доступен в репозитории.

PaaS UI

Выбираем PaaS UI для создания приложений

Пришло время выбрать PaaS UI, который позволит нам создавать приложения для наших тенантов. Мы остановились на Cyclops UI по нескольким причинам. Во-первых, его интерфейс интуитивно понятен, а во-вторых, он прост в использовании. Cyclops UI позволяет разворачивать и управлять приложениями в Kubernetes без написания манифестов вручную, что идеально соответствует нашей цели — создать простой PaaS.

Архитектура PaaS на Kubernetes

Архитектура PaaS на Kubernetes

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

Cyclops UI состоит из двух ключевых компонентов, которые обеспечивают его функциональность:

  1. Module: Это единица управления, которая объединяет все необходимые Kubernetes-ресурсы для работы приложения, такие как Deployment, Service или Ingress. Мы используем Module, чтобы упрощенно создавать, обновлять или удалять приложения через интерфейс, избегая ручной работы с манифестами.

  2. 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. Вот что нужно сделать:

  1. Создание Helm-чарта

    • Инициализируем чарт с помощью helm create paas-tenant.

  2. Добавление ресурсов в 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 и можем посмотреть, какие объекты он в себя включает.

Cyclops UI

Cyclops UI

Выбираем первый сервис для PaaS: PostgreSQL

Теперь нам нужно выбрать первый сервис, который мы будем предоставлять в нашей PaaS-платформе. Мы остановились на PostgreSQL, потому что «база — это база». PostgreSQL универсален, надежен и может использоваться как для других общих сервисов, так и для хранения данных приложений.

В CloudNative Landscape есть несколько операторов для PostgreSQL, из которых мы рассматривали два варианта: CloudNativePG и Percona. Мы выбрали CloudNativePG по следующим причинам:

  • Percona нам уже знакома, я с ней работал ранее, но она не показалась достаточно интересной для эксперимента.

  • CloudNativePG, напротив, это новый для меня инструмент, который я решил попробовать, чтобы изучить его возможности и подходы к управлению PostgreSQL в Kubernetes.

Этот выбор позволяет нам добавить PostgreSQL как ключевой сервис для тенантов, а использование CloudNativePG дает возможность протестировать современный оператор в нашей PaaS-платформе. Конечная схема первой части будет выглядит следующим образом:

Архитектура PaaS на Kubernetes

Архитектура PaaS на Kubernetes

Устанавливаем оператор 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. Вот что нужно сделать:

  1. Создание Helm-чарта

    • Инициализируем чарт с помощью команды helm create paas-tenant-pg.

  2. Добавление ресурсов в postgres.yaml
    В папке paas-tenant-pg/templates создаем файл postgres.yaml, который включает:

    • Cluster — ресурс для настройки PostgreSQL с помощью CloudNativePG;

    • Pooler — CRD для создания пулов подключений к PostgreSQL через CloudNativePG;

    • TCPRoute — для маршрутизации трафика в Pooler, обеспечивающий доступ к базе данных;

    • Secret с паролем для PostgreSQL — чтобы защитить доступ.

Шаблон Postgres

Шаблон Postgres

Точный код манифестов доступен в репозитории.

  • 3. Отправка в Git

    • После создания чарта и шаблона отправляем его в репозиторий Git для дальнейшего использования.

На этом этапе мы только создаем и сохраняем шаблон, чтобы затем зарегистрировать его в Cyclops UI через TemplateStore.

Добавляем TemplateStore в чарт paas-tenant

Теперь, когда чарт готов и сохранен в Git, нам нужно зарегистрировать его в Cyclops UI, чтобы он стал доступен как модуль для разворачивания PostgreSQL. Для этого мы добавим CR TemplateStore в чарт paas-tenant и обновим его.

  1. Добавление 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 появился в списке доступных модулей.

Cyclops UI Templates

Cyclops UI Templates

Теперь у нас есть шаблон PostgreSQL, который мы можем использовать через Cyclops UI для разворачивания базы данных в любом тенанте.

Создаем первое приложение: разворачиваем PostgreSQL

Последний этап — создание первого приложения в нашей PaaS-платформе с использованием PostgreSQL. Мы начнем с настройки модуля PaaS-gateway и добавим новый модуль для базы данных. Вот что нужно сделать:

  1. Добавление TCP Listener в модуль PaaS-gateway:

    • Открываем существующий модуль PaaS-gateway в Cyclops UI и добавляем TCP Listener.

    • Задаем ему имя и порт, запоминаем его и нажимаем на кнопку Deploy.

    • После этого на Load Balancer появится новый порт для обработки TCP-трафика.

Paas Gateway module

Paas Gateway module
  • 2. Создание модуля для PostgreSQL

    • В Cyclops UI создаем новый модуль, указав тип PaaS-pg, и задаем ему имя.

    • Указываем параметры базы данных: имя, пользователь и другие настройки, а также название TCP Listener, добавленного в шаге 1.

    • Нажимаем на кнопку Deploy, и Cyclops UI разворачивает PostgreSQL через шаблон paas-tenant-pg.

PG module

G module
PG module

PG module
  • 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/