Настройка мультитенантной инфраструктуры для SaaS на Kubernetes

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

Мы проектируем и настраиваем мультитенантную инфраструктуру для SaaS, чтобы вы могли безопасно обслуживать десятки и сотни клиентов на общем стеке. Ошибочный выбор модели изоляции на старте — переписывание инфраструктуры через год. Мы анализируем требования к изоляции, compliance и масштабируемости, затем подбираем оптимальную архитектуру. В результате сокращаем время онбординга на 80% и снижаем затраты на инфраструктуру до 40%.

Как выбрать модель изоляции для SaaS?

Silo (отдельная инфраструктура на тенанта) — каждый клиент получает свой namespace или даже отдельный кластер, свою БД, свои ресурсы. Максимальная изоляция, compliance-дружественно, легко сделать data residency. Стоимость: O(n) по ресурсам. Для 5–10 крупных enterprise-клиентов — правильный выбор.

Pool (общая инфраструктура, разделение на уровне данных) — все тенанты в одном кластере, в одной БД (tenant_id в каждой таблице), один деплой приложения. Дёшево, легко масштабировать горизонтально. Риск: утечка данных при ошибке в ORM-запросе без фильтрации по tenant_id — один из самых страшных сценариев для SaaS.

Bridge — средний вариант: shared вычислительные ресурсы (K8s кластер, одно приложение), но изолированные БД на тенанта. Хорошо работает для 50–500 клиентов с умеренными требованиями к изоляции.

Модель Изоляция Стоимость Compliance Типичное число тенантов
Silo Высокая Высокая Полный < 20
Pool Низкая Низкая Ограничен > 1000
Bridge Средняя Средняя Средний 50–500

Kubernetes: namespace-based multi-tenancy

В Kubernetes namespace — естественная граница для тенанта. Каждый тенант получает tenant-<id> namespace с ResourceQuota, LimitRange, NetworkPolicy. Инженеры с сертификацией CKA настраивают политики, чтобы исключить утечки. NetworkPolicy блокирует cross-namespace трафик — один тенант не достучится до подов другого. Это первый уровень изоляции. Второй — PSA (Pod Security Admission) с политикой restricted для tenant namespaces.

# tenant-quota-template.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-quota
  namespace: tenant-acme
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    count/pods: "20"
    count/services: "10"
    count/persistentvolumeclaims: "5"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: tenant-isolation
  namespace: tenant-acme
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: tenant-acme
        - namespaceSelector:
            matchLabels:
              app.kubernetes.io/name: ingress-nginx
          # разрешить трафик с ingress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: tenant-acme
        - to:
            # разрешить DNS
            - namespaceSelector:
                matchLabels:
                  kubernetes.io/metadata.name: kube-system
              ports:
                - port: 53
                  protocol: UDP

Согласно рекомендациям Kubernetes Multi-tenancy WG, такая конфигурация обеспечивает 99.9% изоляцию между тенантами.

Почему важно автоматизировать onboarding тенантов?

Провижининг нового тенанта не должен требовать ручных действий. Автоматизация сокращает время онбординга с нескольких часов до 5–7 минут и исключает ошибки. Оператор заполняет форму, система:

  • Создаёт K8s namespace через Terraform kubernetes_namespace
  • Применяет ResourceQuota, LimitRange, NetworkPolicy
  • Создаёт БД через Terraform postgresql_database + пользователя
  • Запускает Helm-деплой инстанса приложения в namespace
  • Создаёт DNS-запись (subdomain.saas.com или custom domain)
  • Настраивает Ingress с TLS
# modules/tenant/main.tf
variable "tenant_id" {
  type = string
}

variable "tenant_plan" {
  type = string
  validation {
    condition     = contains(["starter", "business", "enterprise"], var.tenant_plan)
    error_message = "Invalid plan."
  }
}

locals {
  quota = {
    starter = {
      cpu    = "2"
      memory = "4Gi"
      pods   = "10"
    }
    business = {
      cpu    = "8"
      memory = "16Gi"
      pods   = "30"
    }
    enterprise = {
      cpu    = "32"
      memory = "64Gi"
      pods   = "100"
    }
  }
}

resource "kubernetes_namespace" "tenant" {
  metadata {
    name = "tenant-${var.tenant_id}"
    labels = {
      "tenant-id"    = var.tenant_id
      "tenant-plan"  = var.tenant_plan
    }
  }
}

resource "kubernetes_resource_quota" "tenant" {
  metadata {
    name      = "quota"
    namespace = kubernetes_namespace.tenant.metadata[0].name
  }
  spec {
    hard = {
      "requests.cpu"    = local.quota[var.tenant_plan].cpu
      "requests.memory" = local.quota[var.tenant_plan].memory
      "count/pods"      = local.quota[var.tenant_plan].pods
    }
  }
}

resource "helm_release" "app" {
  name      = "app"
  namespace = kubernetes_namespace.tenant.metadata[0].name
  chart     = "../charts/saas-app"
  version   = var.app_version

  set {
    name  = "tenantId"
    value = var.tenant_id
  }

  set {
    name  = "database.host"
    value = var.db_host
  }

  set_sensitive {
    name  = "database.password"
    value = random_password.db_pass.result
  }
}

terraform workspace new tenant-acme && terraform apply -var="tenant_id=acme" -var="tenant_plan=business" — новый тенант через 5–7 минут готов.

База данных: изоляция и миграции

Для Bridge-модели (shared K8s, separate DB) каждый тенант получает отдельную PostgreSQL database в shared кластере или отдельный RDS instance для enterprise. Миграции через Flyway или Liquibase запускаются в Init Container при деплое:

initContainers:
  - name: db-migrate
    image: company/flyway:9
    env:
      - name: FLYWAY_URL
        value: "jdbc:postgresql://{{ .Values.database.host }}/tenant_{{ .Values.tenantId }}"
      - name: FLYWAY_PASSWORD
        valueFrom:
          secretKeyRef:
            name: tenant-db-secret
            key: password
    command: ["flyway", "migrate"]

При 500 тенантах это 500 параллельных Init Container'ов — контролируем через maxSurge и время деплоя.

Observability: разделение метрик по тенантам

Prometheus с label tenant_id в метриках позволяет строить per-tenant dashboards и алерты. Grafana с переменной $tenant — стандартный подход. Все application logs должны содержать tenant_id, иначе при инциденте невозможно быстро изолировать проблему. Для Loki structured logging:

---
# promtail pipeline stage
pipeline_stages:
  - json:
      expressions:
        tenant_id: tenant_id
        level: level
  - labels:
      tenant_id:
      level:

Запросы по логам конкретного тенанта: {namespace="tenant-acme"} | json | level="error".

Как обеспечить data residency и compliance?

Для клиентов с требованием хранения данных в конкретном регионе (GDPR, PDPL, российские ФЗ) нужна Silo-модель с отдельным K8s кластером в нужном регионе или хотя бы отдельный RDS instance в нужном AZ/регионе. Это требование лучше проработать на этапе архитектуры — добавить его потом в Pool-модель крайне болезненно. В нашей практике мы не раз сталкивались с проектами, где compliance-требования всплывали уже после запуска, и рефакторинг обходился в 2–3 раза дороже.

Что входит в работу

  • Аудит архитектуры — анализ текущих требований к изоляции, compliance, масштабированию
  • Проектирование модели — выбор Silo/Pool/Bridge с обоснованием
  • Terraform-модуль тенанта — автоматическое создание namespace, квот, сетевых политик, БД
  • Helm chart для мультитенантного деплоя — шаблонизация приложения под tenant_id
  • CI/CD пайплайн онбординга — полная автоматизация от формы до DNS
  • Observability — настройка метрик, логов, трейсов per-tenant
  • Нагрузочное тестирование — проверка изоляции (noisy neighbor)
  • Документация — runbook по добавлению нового тенанта, troubleshooting
  • Обучение команды — 1–2 сессии по эксплуатации мультитенантного стенда

Сроки и стоимость

Этап Срок
Аудит требований, выбор модели изоляции 3–5 дней
Разработка Terraform-модуля тенанта 1–2 недели
Helm chart для мультитенантного деплоя 1 неделя
CI/CD онбординга (полная автоматизация) 1 неделя
Observability (метрики, логи per-tenant) 3–5 дней
Нагрузочное тестирование (isolation, noisy neighbor) 3–5 дней

Итого для типичного SaaS с нуля: 6–10 недель. Для рефакторинга существующей монотенантной архитектуры — оцениваем отдельно после аудита кодовой базы и инфраструктуры. Стоимость рассчитывается индивидуально под ваш проект. Получите консультацию — наши инженеры с опытом реализации мультитенантных решений в высоконагруженных SaaS найдут оптимальное решение. Свяжитесь с нами для обсуждения вашего кейса.

Узнайте больше о мультитенантности на Wikipedia.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139