VK Cloud

Запускаем etcd-кластер для Kubernetes в 2026 году

Обновлено 15 июня 2026 г.
12 марта 2019 г.
_blog_head_135.png

В 2026 году etcd для Kubernetes — это отдельный критичный сервис с собственным lifecycle, регламентами и SLO. В нём критически важно не ошибаться, чтобы один забытый defrag или устаревший сертификат не стали причиной потери контрольной плоскости целого кластера. В этой статье разбираем, как в таких условиях запускать и эксплуатировать etcd-кластер под Kubernetes 1.32–1.33 так, чтобы его можно было обновлять, мониторить, чинить и не бояться ночных алертов.

Мы пройдём путь от выбора топологии (stacked vs external) и ветки etcd до развёртывания через kubeadm и Helm-чарт, настройки mTLS и encryption at rest, регулярных снапшотов и восстановления через etcdutl, а также ключевых метрик и RBAC-сценариев. В конце вас ждёт чек-лист типичных ошибок, на которые чаще всего наступают команды эксплуатации.

Что такое etcd и зачем он Kubernetes

etcd — распределённое key-value-хранилище на основе протокола Raft. Для Kubernetes это единственное место, где хранится состояние кластера: объекты API, Secrets, ConfigMaps, информация о подах и узлах. Если etcd перестает работать, kube-apiserver не может ни читать, ни писать, и кластер фактически паразилуется.

У etcd есть несколько ключевых свойств:

  • Консенсус Raft: в каждый момент времени есть один лидер, остальные — фолловеры.
  • Запись считается зафиксированной только после fsync на диск у кворума узлов.
  • Кворум для N узлов — N/2 + 1 (для 3 — 2, для 5 — 3).
  • WAL (write-ahead log) — журнал записей до применения в основное хранилище.

То есть etcd чувствителен к латентности диска и сети, а количество узлов всегда нечётное — 3 или 5.

Актуальные версии: etcd 3.5.x стабильная ветка, 3.6.x, Kubernetes 1.32–1.33

На 2026 год расклад такой:

  • etcd 3.6.8 — последняя минорная ветка, февраль 2026 года.
  • etcd 3.5.22 — рекомендованная стабильная ветка для production, релиз 22 июля 2025 года. Позже вышла 3.5.24 — 22 октября 2025 года.
  • Kubernetes 1.33 — минимум etcd 3.5.16, kubeadm подтягивает 3.5.24.
  • Kubernetes 1.32 — рекомендовано оставаться на 3.5.x, переход на 3.6.x — после устранения breaking changes.

Для production-кластера Kubernetes 1.32–1.33 берите ветку 3.5.x (минимум 3.5.16, а лучше 3.5.24). На 3.6.x уходите только после полного цикла тестов в staging.

Топология кластера: stacked vs external etcd

kubeadm поддерживает две топологии HA-кластера.:

  • Stacked-топология (значение по умолчанию). etcd запускается как static pod на каждом узле control-plane рядом с kube-apiserver. Конфигурация описана в манифесте /etc/kubernetes/manifests/etcd.yaml, для такой схемы нужно минимум три узла. Главное преимущество — экономия железа и более простое управление, но отказ одного узла одновременно выводит из строя и member etcd, и сам control-plane.
  • External-топология. etcd работает на выделенных серверах. Минимальная конфигурация — три узла etcd и три узла control-plane, всего шесть машин. Эта схема даёт лучшую изоляцию отказов и упрощает горизонтальное масштабирование, но требует больше серверных ресурсов и усложняет автоматизацию.

Когда что выбирать:

  • до 50 узлов worker, ограниченный бюджет — stacked;
  • от 100 узлов worker, требования к доступности 99,95% и выше — external;
  • multi-tenant-кластеры, отдельные SLA на control-plane — external.

Миграция stacked → external нетривиальна: проще поднять новый кластер и перенести данные, чем переключать топологию на лету.

Развёртывание etcd

Разберём три рабочих подхода. Все они дают валидный кластер, и выбор зависит от того, как у вас устроена инфраструктура.

Через kubeadm (static pods)

При kubeadm init с флагом --upload-certs и тремя control-plane-узлами вы автоматически получаете stacked-кластер. Манифест static-pod для etcd kubeadm создаёт сам, версию контейнера подбирает по таблице совместимости (для 1.33 — etcd 3.5.24).

Минимальный фрагмент манифеста /etc/kubernetes/manifests/etcd.yaml: text

apiVersion: v1 kind: Pod metadata: name: etcd namespace: kube-system spec: hostNetwork: true containers: - name: etcd image: registry.k8s.io/etcd:3.5.24-0 command: - etcd - --name=master-1 - --data-dir=/var/lib/etcd - --listen-client-urls=https://0.0.0.0:2379 - --advertise-client-urls=https://10.0.0.11:2379 - --listen-peer-urls=https://0.0.0.0:2380 - --initial-advertise-peer-urls=https://10.0.0.11:2380 - --initial-cluster=master-1=https://10.0.0.11:2380,master-2=https://10.0.0.12:2380,master-3=https://10.0.0.13:2380 - --client-cert-auth=true - --peer-client-cert-auth=true - --cert-file=/etc/kubernetes/pki/etcd/server.crt - --key-file=/etc/kubernetes/pki/etcd/server.key - --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt - --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt - --peer-key-file=/etc/kubernetes/pki/etcd/peer.key - --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt volumeMounts: - name: etcd-data mountPath: /var/lib/etcd - name: etcd-certs mountPath: /etc/kubernetes/pki/etcd volumes: - name: etcd-data hostPath: path: /var/lib/etcd - name: etcd-certs hostPath: path: /etc/kubernetes/pki/etcd

Точный тег образа для конкретной патч-версии 1.33.x можно получить командой: bash

kubeadm config images list --kubernetes-version v1.33.x

Для external-топологии используйте kubeadm init --config kubeadm-config.yaml, где в ClusterConfiguration указываете etcd.external.endpoints и пути к сертификатам.

Через Helm-чарт Bitnami/etcd

Для external-топологии вне control-plane удобно использовать Helm-чарт Bitnami/etcd. Актуальная версия чарта — 12.0.20 (appVersion etcd 3.6.4), мажорная серия 12.x, установка через OCI-репозиторий: bash

helm install my-etcd \ oci://registry-1.docker.io/bitnamicharts/etcd \ --version 12.0.20 \ -f values.yaml

Минимальный values.yaml для production: text

replicaCount: 3 auth: rbac: create: true rootPassword: "<strong-password>" client: secureTransport: true useAutoTLS: false existingSecret: etcd-client-certs peer: secureTransport: true useAutoTLS: false existingSecret: etcd-peer-certs persistence: enabled: true size: 20Gi storageClass: vk-cloud-ssd-nvme resourcesPreset: large metrics: enabled: true serviceMonitor: enabled: true logLevel: info updateStrategy: type: RollingUpdate

Важные детали:

  • replicaCount: 3 — кворум на отказ одного узла;
  • auth.rbac.create: true включает RBAC etcd; rootPassword хранится в Secret;
  • auth.client.secureTransport и auth.peer.secureTransport обязательны для production;
  • persistence.storageClass указывайте на NVMe/SSD-диск, иначе etcd упрётся в fsync;
  • metrics.enabled: true поднимает Prometheus-экспортёр.

Manual: для справки

Есть вариант бинарной установки с etcd --listen-client-urls ... и systemd-юнитом. Ее стоить оставить для bare-metal-стендов и lab-окружений. Но для production-кластеров Kubernetes в 2026 году выбор сводится к kubeadm или Helm-чарту: оба варианта дают воспроизводимую конфигурацию и понятный путь обновления.

TLS, mTLS и шифрование данных

CIS Kubernetes Benchmark v1.10–v1.11 (релизы 2025 года) требует mTLS на всех соединениях etcd, шифрование Secrets at rest и сетевую сегментацию etcd.

Обязательные флаги etcd для mTLS:

  • --client-cert-auth=true, --peer-client-cert-auth=true — клиент и peer должны предъявить сертификат;
  • --cert-file, --key-file — серверный сертификат для клиентских подключений;
  • --peer-cert-file, --peer-key-file — сертификат для peer-to-peer-трафика между members;
  • --trusted-ca-file, --peer-trusted-ca-file — CA для проверки.

При установке через kubeadm все сертификаты создаются автоматически в /etc/kubernetes/pki/etcd/. Ротация — одной командой:

bash

kubeadm certs renew etcd-server etcd-peer \ etcd-healthcheck-client apiserver-etcd-client

После ротации перезапустите static pod etcd на каждом control-plane-узле. Сертификаты по умолчанию выпускаются на год — закладывайте ротацию в регламент.

Encryption at rest для Secrets настраивается в kube-apiserver через --encryption-provider-config. Минимальная EncryptionConfiguration с провайдером aescbc:

text

apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: <base64-32-byte-key> - identity: {}

Для production-окружения с требованиями по соответствию используйте провайдер kms с внешним хранилищем ключей. После включения шифрования прогоните:

bash

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

Это позволит перешифровать существующие Secrets. Перед прогоном сделайте резервную копию снапшота etcd. На больших кластерах безопаснее обрабатывать по неймспейсам.

Сетевая сегментация: etcd — в выделенной подсети, доступ открыт только control-plane-узлам по портам 2379 (клиент) и 2380 (peer). Никакого 0.0.0.0/0.

etcdctl и etcdutl: что использовать в 2026 году

Начиная с etcd 3.5 у etcd две административные утилиты. Кратко:

Команда etcdctl etcdutl
Работа с живым кластером (get, put, watch) да нет
Управление членами (member add/remove) да нет
snapshot save да нет
snapshot status deprecated в 3.5, удаление в 3.6 да
snapshot restore deprecated в 3.5, удаление в 3.6 да
defrag --data-dir (офлайн) нет да
hashkv, миграция между версиями нет да
Доступ к данным по сети напрямую к файлам

Правило простое: всё, что про живой кластер, — etcdctl; всё, что про файлы данных (status, restore, офлайн-defrag), — etcdutl. При вызове etcdctl snapshot restore вы увидите предупреждение Deprecated: Use 'etcdutl snapshot restore' instead — его игнорировать нельзя: в 3.6 команды из etcdctl уберут.

Стоит учитывать, что etcdutl не включён в официальный container image etcd, поэтому для офлайн-операций его придётся доставлять отдельно или копировать бинарник из релиза.

Бэкап и восстановление

Алгоритм бэкапа в 2026 году — etcdctl snapshot save на живом кластере, etcdutl snapshot restore при восстановлении.

Снапшот:

bash

ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snap-$(date +%Y%m%d-%H%M).db \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key

Проверка снапшота: bash

etcdutl snapshot status /backup/etcd-snap-20260227-0300.db --write-out=table

Восстановление в новый_ data-dir_:

bash

etcdutl snapshot restore /backup/etcd-snap-20260227-0300.db \ --data-dir /var/lib/etcd-new

После этого останавливаете старый etcd, подменяете data-dir в манифесте static pod и поднимаете кластер.

Рекомендуемый регламент для production:

  • снапшот — раз в 6 часов;
  • хранить 10 последних снапшотов;
  • выгружать в S3-совместимый бакет вне кластера;
  • раз в неделю — тестовое восстановление в staging.

Defrag и compaction — это отдельная регулярная процедура обслуживания etcd. У метрики etcd_mvcc_db_total_size_in_bytes есть значение quota-backend-bytes. По умолчанию 2 ГиБ, в production его обычно поднимают до рекомендованного максимума 8 ГиБ, выше etcd при старте выдаёт предупреждение. Когда метрика приближается к этому значению, запускайте etcdctl defrag последовательно на каждом member и добавляйте etcdctl compact для очистки старых ревизий. Во время defrag узел блокируется и не обслуживает запросы, поэтому такие операции нужно выполнять по одному члену кластера, а не одновременно на всех.

Подробнее про сборку метрик и алертов — в статье про мониторинг Kubernetes с Prometheus и Grafana.

Мониторинг etcd: ключевые Prometheus-метрики и пороги

Шесть метрик, на которые ориентируются ранбуки etcd и prometheus-operator:

  • etcd_server_has_leader — 0 означает, что member не видит лидера. Критический алерт, page немедленно.
  • etcd_disk_wal_fsync_duration_seconds — p99 должно быть меньше 10 мс. Выше — диск не справляется, растёт риск перевыборов лидера.
  • etcd_disk_backend_commit_duration_seconds — p99 меньше 25 мс.
  • etcd_server_leader_changes_seen_total — частые изменения говорят о проблемах с диском или сетью.
  • etcd_network_peer_round_trip_time_seconds — латентность между members.
  • etcd_mvcc_db_total_size_in_bytes — размер БД, триггер для defrag.

Пример PrometheusRule для fsync:

text

apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: etcd-disk-latency namespace: monitoring spec: groups: - name: etcd.rules rules: - alert: EtcdHighFsyncDuration expr: histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) > 0.01 for: 10m labels: severity: warning annotations: summary: "etcd member {{ $labels.instance }}: p99 fsync > 10 ms" description: "Диск под WAL не успевает. Проверьте storage class и нагрузку соседей." - alert: EtcdNoLeader expr: etcd_server_has_leader == 0 for: 1m labels: severity: critical annotations: summary: "etcd member {{ $labels.instance }} не видит лидера"

Вот более плавный и связный вариант: Дисковая латентность остаётся основной проблемой для etcd. На обычных HDD и сетевом блочном хранилище без гарантированных IOPS кластер рано или поздно упрётся в медленный fsync и начнёт нестабильно работать. Для каталога данных etcd в production используйте локальный NVMe- или SSD-диск и держите p99 etcd_disk_wal_fsync_duration_seconds в пределах 10 мс.

RBAC в etcd и RBAC в Kubernetes

В Kubernetes доступ к данным etcd проходит через kube-apiserver, и обычные пользователи или компоненты кластера не обращаются к хранилищу напрямую. Права на работу с объектами API настраиваются средствами Kubernetes RBAC — через Roles, RoleBindings и ClusterRoles, которые описывают, кто и какие действия может выполнять в кластере. Подробный разбор таких политик есть в отдельной статье VK Cloud про управление доступом в Kubernetes через RBAC.

Встроенный RBAC самого etcd нужен в другой ситуации: когда вы используете отдельный кластер etcd как самостоятельное KV-хранилище для приложений — например, для service discovery, механизма выбора лидера или хранения конфигурации.

Базовая настройка через etcdctl API v3:

bash

ETCDCTL_API=3 etcdctl user add root ETCDCTL_API=3 etcdctl role add app-reader ETCDCTL_API=3 etcdctl role add app-reader ETCDCTL_API=3 etcdctl role grant-permission app-reader read /app/ --prefix ETCDCTL_API=3 etcdctl user add app ETCDCTL_API=3 etcdctl user grant-role app app-reader ETCDCTL_API=3 etcdctl auth enable

Без root-пользователя auth enable не сработает. В Bitnami-чарте root создаётся автоматически при auth.rbac.create: true с паролем из auth.rbac.rootPassword.

Чек-лист ошибок эксплуатации

  1. Дисковая латентность WAL. NVMe/SSD с p99 fsync меньше 10 мс — обязательное требование. На сетевых дисках без гарантий IOPS etcd сыпется на ровном месте.
  2. Забытый defrag. База упирается в quota-backend-bytes (по умолчанию 2 ГиБ), кластер переходит в read-only. Поднимайте quota до рекомендованного максимума 8 ГиБ и регламентируйте defrag.
  3. Снапшоты без проверки восстановления. Снапшот есть, а etcdutl snapshot restore падает. Раз в неделю — тестовое восстановление.
  4. etcdctl snapshot restore вместо etcdutl. В 3.5 — warning, в 3.6 команду удалят. Переписывайте плейбуки сейчас.
  5. Отсутствие ротации сертификатов. Через год после kubeadm init сертификаты протухают, кластер встаёт. Календарь и kubeadm certs renew.
  6. Stacked-топология на 100+ узлов. Латентность kube-apiserver растёт, перевыборы лидера учащаются. Переезжайте на external.

Что в итоге

Для production-кластера Kubernetes 1.32–1.33 в 2026 году имеет смысл остановиться на ветке etcd 3.5.x: минимально — 3.5.16, оптимально — 3.5.24, особенно если дальше планируете обновление до 3.6.x после полного цикла тестов в staging. Развёртывать кластер удобнее всего через kubeadm в stacked-топологии или через Helm-чарт Bitnami/etcd версии 12.0.20 для external-схемы. Для бэкапов используйте etcdctl snapshot save, а для восстановления — etcdutl snapshot restore, так как команда etcdctl snapshot restore уже помечена как устаревшая и в ветке 3.6 будет удалена.

Базовый набор требований к безопасности включает mTLS для client и peer-подключений, шифрование Secrets at rest и жёсткую сетевую сегментацию узлов etcd. Для каталога данных закладывайте локальный NVMe- или SSD-диск и контролируйте p99 etcd_disk_wal_fsync_duration_seconds на уровне до 10 мс, иначе на нагрузке получите постоянные перевыборы лидера и деградацию API

На дашборде мониторинга каждый день должны быть видны как минимум шесть ключевых метрик: etcd_server_has_leader, etcd_disk_wal_fsync_duration_seconds, etcd_disk_backend_commit_duration_seconds, etcd_server_leader_changes_seen_total, etcd_network_peer_round_trip_time_seconds и etcd_mvcc_db_total_size_in_bytes. Регламент по бэкапам выглядит так: снапшот каждые 6 часов, хранение последних 10 снимков, выгрузка в S3-совместимое хранилище вне кластера и обязательная проверка восстановления хотя бы раз в неделю.

Оставьте заявку, чтобы получить консультацию

Наши специалисты свяжутся с вами в ближайшее время и ответят на все вопросы.

section-subscribe_2x.png

            Узнавайте о выходе новых статей в блоге первыми!

            Будем держать в курсе новостей и облачных трендов

            section-subscribe_2x.png
              section-subscribe_2x.png
              Теги: Разработка, etcd
              Ссылка скопирована
              Поделиться

              Почитать по теме

              _blog_head_158.png
              24 июля

              External Secrets Operator в Managed Kubernetes: безопасное управление секретами без ручной работы

              _blog_head_100.png
              24 июля

              S3-CSI в Managed Kubernetes: масштабирование приложений без потери общих файлов

              40+ готовых сервисов