Yandex Cloud Managed Kubernetes: особенности по сравнению с on-prem k3s

Published: 2026-04-26

В инфраструктуре работают два типа Kubernetes-кластеров: on-prem k3s (dev, test) и Yandex Cloud Managed k8s (sre, loadgds, demo). Они используют одну конфигурацию Flux, но на нескольких уровнях есть различия.


Что берёт на себя YC

Компонент k3s (on-prem) YC Managed k8s
Control plane self-hosted, управляется Ansible управляется YC, HA
etcd на master-ноде управляется YC, вне кластера
Сертификаты k3s auto управляется YC, auto-rotate
Обновления OS нод вручную auto-upgrade группы нод
Cloud controller Cilium L2 YC CCM (встроенный)
LoadBalancer Cilium L2 + ARP YC Network Load Balancer (авто)
Хранилище local-path (hostPath) yc-network-ssd, yc-network-hdd
IP для Ingress статический из Cilium-пула назначается YC NLB
Сетевой плагин Flannel / Cilium Calico (по умолчанию)

YC Managed k8s берёт на себя самые болезненные задачи: резервное копирование etcd, ротацию сертификатов и патчинг ОС на master-нодах.


StorageClass

YC из коробки предоставляет два StorageClass:

bashkubectl get storageclass
# NAME                  PROVISIONER
# yc-network-hdd        disk-csi-driver.mks.ycloud.io
# yc-network-ssd        disk-csi-driver.mks.ycloud.io

Оба используют сетевое блочное хранилище, а не локальные диски. Из этого следует:

  • Тома переживают замену нод (безопасно при auto-upgrade).
  • Пропускная способность ограничена по сравнению с локальным NVMe.
  • Тома привязаны к зоне — PVC в ru-central1-a может примонтироваться только к поду в той же зоне.

SSD для баз данных и Prometheus:

yamlstorageSpec:
  volumeClaimTemplate:
    spec:
      storageClassName: yc-network-ssd
      resources:
        requests:
          storage: 20Gi

HDD для логов и архивного хранения:

yamlpersistence:
  storageClass: yc-network-hdd
  size: 100Gi

Группы нод

Кластеры YC оперируют группами нод, а не одиночными нодами:

bashyc managed-kubernetes node-group create \
  --cluster-name sre \
  --name default \
  --platform-id standard-v3 \
  --memory 16 \
  --cores 4 \
  --disk-type network-ssd \
  --disk-size 100 \
  --fixed-size 3 \
  --location zone=ru-central1-a

Для автоскейлинга (Cluster Autoscaler предустановлен на кластерах YC):

bash  --auto-scale min=2,max=6,initial=2

Auto-upgrade группы нод заменяет ноды поочерёдно в окно обслуживания. Поды не замечают этого благодаря автоматическому повторному подключению PVC.


Service account для cloud controller

На YC service account назначается при создании кластера. YC CCM использует его для:

  • Создания/удаления Network Load Balancer при применении Service type: LoadBalancer.
  • Управления лейблами и taint нод.
  • Управления таблицами маршрутов для сетевой связности подов.
bashyc iam service-account create k8s-ccm
yc iam role-assignment add \
  --role editor \
  --service-account-name k8s-ccm \
  --folder-id ${YC_FOLDER_ID}

yc iam key create \
  --service-account-name k8s-ccm \
  --output k8s-ccm-key.json

Ключ монтируется в под CCM автоматически самим YC — на managed-кластерах вручную этим управлять не нужно.


Нет Cilium L2 на YC

На кластерах YC CiliumLoadBalancerIPPool и CiliumL2AnnouncementPolicy не разворачиваются. YC создаёт реальные сетевые балансировщики при создании Service типа type: LoadBalancer.

Kustomize-патчи для YC-окружений исключают Cilium LB-ресурсы:

yaml# projects/sre/kustomization/spoke/kustomization.yaml
resources:
  - ../../../../base/...
# cilium-lb-pool.yaml здесь не добавляется

On-prem кластеры включают:

yamlresources:
  - ../../../../base/...
  - cilium-lb-pool.yaml        # IP-пул для Cilium L2
  - cilium-l2-policy.yaml      # политика ARP-анонсирования

kubeconfig и контекст

Для YC-кластеров kubeconfig запрашивается через YC CLI:

bashyc managed-kubernetes cluster get-credentials sre --external
kubectl config rename-context yc-sre sre-k8s

Флаг --external использует внешний эндпоинт (требует добавить IP управляющей машины в белый список группы безопасности). Для CI/CD используйте --internal и запускайте из той же VPC:

bashyc managed-kubernetes cluster get-credentials sre --internal

Для автоматизированных пайплайнов — аутентификация через ключ service account:

bashyc config set service-account-key sa-key.json
yc managed-kubernetes cluster get-credentials sre --external

Различия в Flux-патчах

YC-специфичные патчи в projects/sre/kustomization/hub/patches/:

yaml# apisix-int.yaml — статический IP не нужен, YC назначит сам
spec:
  values:
    service:
      type: LoadBalancer
      # loadBalancerIP не указывается

# kube-prom-stack.yaml — SSD-хранилище
spec:
  values:
    prometheus:
      prometheusSpec:
        storageSpec:
          volumeClaimTemplate:
            spec:
              storageClassName: yc-network-ssd
    alertmanager:
      alertmanagerSpec:
        storage:
          volumeClaimTemplate:
            spec:
              storageClassName: yc-network-ssd

В on-prem патчах используются local-path и статический IP из Cilium-пула.


Расходы

На YC Managed k8s вы платите за:

  • Control plane: фиксированная почасовая ставка.
  • Ноды: за vCPU и ГБ RAM в час.
  • Network Load Balancer: за каждый балансировщик + трафик.
  • Хранилище: за ГБ в час (SSD примерно в 3 раза дороже HDD).

Для снижения расходов:

  • Использовать services.loadbalancers: "0" в ResourceQuota dev-namespace.
  • Использовать HDD для некритичного к задержкам хранилища.
  • Прерываемые (spot) ноды для некритичных рабочих нагрузок.

Создание кластера через Terraform

hclresource "yandex_kubernetes_cluster" "sre" {
  name       = "sre"
  network_id = yandex_vpc_network.main.id

  master {
    version = "1.28"
    zonal {
      zone      = "ru-central1-a"
      subnet_id = yandex_vpc_subnet.main.id
    }
    public_ip = true
  }

  service_account_id      = yandex_iam_service_account.k8s.id
  node_service_account_id = yandex_iam_service_account.k8s_nodes.id
}

resource "yandex_kubernetes_node_group" "default" {
  cluster_id = yandex_kubernetes_cluster.sre.id
  name       = "default"

  instance_template {
    platform_id = "standard-v3"
    resources {
      memory = 16
      cores  = 4
    }
    boot_disk {
      type = "network-ssd"
      size = 100
    }
  }

  scale_policy {
    fixed_scale { size = 3 }
  }

  allocation_policy {
    location { zone = "ru-central1-a" }
  }
}