Wellcake: Kubernetes-оператор для Valkey

Kubernetes-оператор (operator) для Valkey. Управляет Valkey в четырёх топологиях — Standalone, Replication, Sentinel и Cluster — с управляемым оператором переключением (failover), опережающими перезапусками без простоя (zero-downtime rolling restart), начальным развёртыванием (bootstrap) / масштабированием / перераспределением слотов (reshard) кластера, резервным копированием в S3, репликацией между регионами и ротацией секретов без перезапуска.

wellcake включает контроллер valkey-operator и Helm-чарты для оператора и отдельных кластеров. Это независимый проект; его цель — заменить вручную написанные StatefulSet-манифесты и чарты для Redis/Valkey единственным декларативным CRD, который понимает семантику отказов и масштабирования Valkey.

Примечание

Статус: ранняя / экспериментальная версия. API — v1alpha1 (обслуживаемый) и v1beta1 (hub/storage). Сначала запустите в некритичной среде.

Документация

Зачем это нужно

Грамотно запустить Valkey на Kubernetes — значит закодировать его операционные правила (кворум, переключение, владение слотами, безопасность перераспределения) прямо в контур управления, а не в runbook-и. Универсальные чарты с StatefulSet оставляют эти правила на откуп людям. Цели wellcake:

  • охватить все четыре распространённые конфигурации развёртывания через один CRD, причём кластерный режим является полноценной топологией, а не надстройкой;

  • сделать failover и rolling restart безопасными по умолчанию — повысить здоровую реплику до мастера до остановки текущего мастера, а не реагировать после инцидента;

  • сохранять атомарность и идемпотентность путей к данным (bootstrap, масштабирование, reshard, восстановление), включая Atomic Slot Migration (ASM) в Valkey 9.1+;

  • трактовать персистентность, TLS, ACL, резервное копирование и ротацию секретов как декларативную спецификацию, а не внешние процедуры.

Топологии

Топология Статус Failover

Standalone

✅

нет

Replication

✅

управляется оператором через REPLICAOF

Sentinel

✅

кворум Sentinel

Cluster

✅

нативный gossip + восстановление оператором при потере большинства мастеров

CRD

Вид Назначение

ValkeyCluster

Развёртывание Valkey в одной из четырёх топологий.

ValkeyACL

Декларативные ACL-пользователи на ValkeyCluster.

Возможности

  • Все четыре топологии: Standalone, Replication, Sentinel, Cluster

  • Два профиля: Cache (allkeys-lru, персистентность отключена, PVC 1Gi) и Durable (noeviction, RDB+AOF, PVC 10Gi)

  • Failover под управлением оператора для Replication: TCP-опрос каждые 15 с, повышение реплики с максимальным оффсетом, защита от split-brain после перезапуска pod-0

  • Раздельные сервисы чтения/записи для Replication: сервис <cluster>-primary, указывающий только на текущий мастер (для записи), и сервис <cluster>-replicas, охватывающий только реплики (для чтения); маршрутизация реализована через метку пода valkey.wellcake.io/role, которую оператор перемещает при failover — отдельно от балансирующего сервиса <cluster> для всего кластера

  • Опережающий rolling restart (ADR 0004, включается аннотацией valkey.wellcake.io/proactive-rollout: "true", по умолчанию ВЫКЛЮЧЕНО) для Replication / Cluster / Sentinel: StatefulSet переводится в режим OnDelete, оператор перезапускает поды по одному и выполняет передачу лидерства (promote реплики / CLUSTER FAILOVER / SENTINEL FAILOVER) до перезапуска старого мастера — окно простоя ~0 вместо реактивных ~15–20 с

  • Начальное развёртывание кластера (bootstrap) через одноразовый Job с valkey-cli --cluster create

  • Масштабирование кластера вверх и вниз через add-node / reshard-away + del-node; autoReshard (по умолчанию) автоматически перебалансирует слоты, так что изменение shards сходится без ручных шагов; в Valkey 9.1+ перераспределение использует Atomic Slot Migration (ASM, с проверкой версии, ADR 0001) — атомарно, без открытых слотов при прерывании

  • Воркнагрузка на шард (spec.perShardWorkload, opt-in / неизменяемо / только Cluster, экспериментально): отдельный StatefulSet + Service на каждый шард — позволяет настраивать anti-affinity по шардам и корректно масштабировать шарды вниз (удаление StatefulSet уходящего шарда)

  • Восстановление кластера при потере большинства мастеров (ADR 0006): если Cluster теряет более половины мастеров одновременно — то есть происходит тот самый инцидент, через который gossip не может провести failover голосованием, — оператор ограждает (fence) упавшие мастера (через k8s liveness и проверку пути к данным) и выполняет CLUSTER FAILOVER TAKEOVER на выжившей реплике каждого шарда. Автоматически для Cache, opt-in для Durable (valkey.wellcake.io/quorum-takeover)

  • Sentinel со своим StatefulSet, ConfigMap и Service на порту 26379 (26380 с TLS)

  • ValkeyACL — отдельный CRD для управления пользователями через ACL SETUSER …​ reset (идемпотентно благодаря токену reset); для Cluster применяется ко всем узлам шарда

  • Пользователь репликации с минимальными привилегиями: реплики аутентифицируются к мастеру как выделенный пользователь replicator (+psync +replconf +ping, без доступа к ключам), а не как полноправный дефолтный пользователь — утечка учётных данных репликации не позволит ни читать, ни писать данные (зарезервировано для ValkeyACL)

  • Резервное копирование в S3 (CronJob с valkey-cli --rdb, хранение, SSE, по шардам для Cluster) и восстановление через spec.restoreFrom

  • Репликация между регионами (async) между кластерами через spec.replicateFrom (включая replicateFrom.caSecret — оператор объединяет локальный CA и CA исходного кластера в единый trust bundle для cross-CA mTLS)

  • Ротация секретов без перезапуска: смена пароля на лету через аннотацию valkey.wellcake.io/rotate-password (живой ACL SETUSER, без разрыва репликации); автоматическая перезагрузка TLS-сертификата при обновлении cert-manager (живой CONFIG SET tls-cert-file)

  • Метрики Prometheus + опциональные ServiceMonitor и PrometheusRule с алертами

  • Плагин kubectl valkey (status / cli / backup / restart / reshard / failover / hibernate / certificate / report)

  • TLS через Issuer cert-manager или существующий Secret

  • PDB + TopologySpreadConstraints по зонам доступности по умолчанию

  • NetworkPolicy (опционально): default-deny + same-namespace + valkey-to-valkey

  • CEL XValidation: неизменяемые topology / profile / storageClassName, только расширение storage.size, условные shards / sentinel

  • Хеш конфига → rolling restart: sha256 от ConfigMap.Data в шаблоне пода

  • Автоматическое maxmemory = 60% от resources.limits.memory

  • Директивы устойчивости версии 9.x с проверкой версии в renderValkeyConf (по версии образа): cluster-allow-replica-migration no (Cluster), shutdown-on-sigterm failover (≥9.0), tls-auto-reload-interval 3600 (TLS + ≥9.1) — переопределяются через spec.config

  • InitContainer для генерации конфигурации во время выполнения (никаких скриптов, зашитых в CM)

  • Всегда PVC, никогда emptyDir — давление на эфемерное хранилище может вызвать вытеснение (eviction), что для in-memory сервиса означает простой

  • Финализатор удаления с топологически-осведомлённым хуком очистки

Установка оператора (одна команда)

make deploy-operator

Устанавливает или обновляет оператор через Helm в пространстве имён valkey-system (создаётся автоматически): CRD + RBAC + Deployment, образ берётся из ghcr.io/melancholictheory/wellcake:latest. Параметры переопределения: OPERATOR_TAG=git-<sha>, OPERATOR_NAMESPACE=<ns>, HELM_ARGS="--set webhooks.enabled=true". Удалить: make undeploy-operator.

Эквивалентно напрямую через Helm:

helm upgrade --install valkey-operator charts/valkey-operator \
  --namespace valkey-system --create-namespace --set image.tag=latest

Helm-чарты (valkey-operator и valkey-cluster) также публикуются в GitHub Container Registry как OCI-артефакты по адресу ghcr.io/melancholictheory/charts, поэтому устанавливать их можно без клонирования репозитория:

helm upgrade --install valkey-operator \
  oci://ghcr.io/melancholictheory/charts/valkey-operator
Примечание

Вебхуки (validating / mutating / conversion) подключаются по желанию (--set webhooks.enabled=true, требуют cert-manager) и по умолчанию отключены.

Опции оператора:

  • rbac.scope=namespace или watchNamespace=<ns> — режим одного пространства имён

  • metrics.serviceMonitor.enabled=true — для Prometheus Operator

  • --skip-crds — пропустить CRD при управлении ими через GitOps

Развёртывание кластера (Helm)

helm upgrade --install my-cache charts/valkey-cluster -n apps \
  --set topology=Replication --set profile=Cache --set replicas=3

Быстрый старт (вне кластера)

make manifests generate
make install
make run
kubectl apply -f config/samples/cache_v1alpha1_valkeycluster.yaml

Подробнее — в docs/development.md.

Структура проекта

api/v1beta1/                   — типы CRD (hub/storage версия — редактировать здесь)
api/v1alpha1/                  — обслуживаемый spoke + конвертация в hub
cmd/
  main.go                      — точка входа менеджера
  kubectl-valkey/              — плагин kubectl (status/cli/backup/…)
internal/controller/
  valkeycluster_controller.go  — Reconcile + диспетчеризация по топологии + финализатор + hibernate
  resources.go                 — строители Service/CM/STS/Secret/PDB/NP
  cluster.go                   — топология Cluster: Jobs bootstrap/scale/reshard
  sentinel.go                  — топология Sentinel
  failover.go                  — управляемый оператором + ручной failover (go-redis)
  backup.go                    — CronJob резервного копирования в S3
  metrics.go                   — пользовательские метрики Prometheus
  valkeyacl_controller.go      — реконсилер ValkeyACL
docs/                          — документация
charts/                        — Helm-чарты (operator, cluster)
config/                        — манифесты kustomize (kubebuilder)

Лицензия

© 2026 meganuke