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

В 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
Подробнее про сборку метрик и алертов — в статье про мониторинг 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.
Чек-лист ошибок эксплуатации
- Дисковая латентность WAL. NVMe/SSD с p99 fsync меньше 10 мс — обязательное требование. На сетевых дисках без гарантий IOPS etcd сыпется на ровном месте.
- Забытый defrag. База упирается в quota-backend-bytes (по умолчанию 2 ГиБ), кластер переходит в read-only. Поднимайте quota до рекомендованного максимума 8 ГиБ и регламентируйте defrag.
- Снапшоты без проверки восстановления. Снапшот есть, а etcdutl snapshot restore падает. Раз в неделю — тестовое восстановление.
- etcdctl snapshot restore вместо etcdutl. В 3.5 — warning, в 3.6 команду удалят. Переписывайте плейбуки сейчас.
- Отсутствие ротации сертификатов. Через год после kubeadm init сертификаты протухают, кластер встаёт. Календарь и kubeadm certs renew.
- 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-совместимое хранилище вне кластера и обязательная проверка восстановления хотя бы раз в неделю.
Оставьте заявку, чтобы получить консультацию
Наши специалисты свяжутся с вами в ближайшее время и ответят на все вопросы.

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


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


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

