|
Инструментарий etcd-operator, помогающий разворачивать и сопровождать кластеры etcd в Kubernetes, перешёл под управление проекта Cozystack. Вместе с передачей проекта опубликована новая реализация etcd-operator, написанная с нуля и использующая API etcd-operator.cozystack.io/v1alpha2 вместо прежнего etcd.aenix.io/v1alpha1. Новую реализацию написал Тимофей Ларкин, один из мейнтейнеров прежней кодовой базы. Старый вариант сохранён в ветке v1alpha1. Код написан на Go и распространяется под лицензией Apache 2.0. Cozystack является Sandbox-проектом некоммерческой организации CNCF.
Главное изменение в новом etcd-operator - отказ от StatefulSet для управления узлами. Теперь оператор напрямую работает со штатным Membership API etcd (MemberAdd, MemberPromote и MemberRemove) и сам добавляет участников, повышает learner до голосующего узла и выводит узлы из кворума, что даёт оператору полный контроль над составом кластера.
Параллельно разработчики проекта etcd развивают с нуля собственны1 официальный etcd-operator. По функциональности официальный оператор пока уступает etcd-operator от проекта Cozystack. Так как прежняя реализация etcd-operator уже работает в рабочих окружениях и используется в Cozystack и Kamaji, её развитие было продолжено отдельно от официально реализации от проекта etcd.
Развиваемый проектом Cozystack оператор управляет кластерами etcd через два ресурса. EtcdCluster описывает желаемое состояние: число реплик, версию etcd, параметры хранилища, TLS, аутентификацию и настройки etcd. EtcdMember создаётся для каждого узла кластера и владеет его Pod и PVC. В отличие от типовых решений оператор не использует StatefulSet и обслуживает независимо Pod и PVC каждого узла. Состав кластера меняется через API Membership etcd: оператор добавляет новые узлы как learner (MemberAdd), затем повышает их до голосующих участников (MemberPromote). Удаление проходит через MemberRemove, с корректным выводом из кворума. При паузе кластера узлы сохраняют свою идентичность.
Основные возможности:
- развёртывание кластера и масштабирование в обе стороны, по одному узлу за раз: новые узлы стартуют в режиме learner, удаление корректно выводит их из кворума;
- остановка кластера без потери данных (spec.replicas: 0) и возобновление работы с теми же идентификаторами кластера и узлов;
- хранение данных в PVC по умолчанию или в tmpfs, если данные можно восстановить заново; при потере Pod оператор автоматически пересоздаёт узлы с хранилищем в памяти;
- раздельная настройка TLS для клиентских и межузловых соединений: можно подключить свои Secret или поручить оператору выпуск и продление сертификатов через cert-manager;
- аутентификация с единственным пользователем root; его учётные данные задаются через Secret;
- создание снапшотов в S3 или PVC через ресурс EtcdSnapshot и восстановление кластера из снапшота при первом развёртывании;
- автоматический PodDisruptionBudget, который не даёт операциям drain нарушить кворум;
- валидация спецификаций средствами apiserver через CEL-выражения в CRD, без webhook и зависимости от cert-manager;
- подресурс /scale для kubectl scale и VerticalPodAutoscaler, порт метрик 2381, проброс affinity и topologySpreadConstraints;
- плагин kubectl-etcd для повседневных эксплуатационных задач (day-2 operations) после развёртывания кластера.
По сравнению со старой реализацией (v1alpha1) изменилось следующее:
- API-группа сменилась с etcd.aenix.io на etcd-operator.cozystack.io;
- вместо StatefulSet оператор использует отдельный ресурс EtcdMember для каждого узла;
- произвольный словарь spec.options заменён типизированным набором параметров: quota-backend-bytes, режим и интервал автокомпактификации, snapshot-count; свободная map позволяла передавать флаги, которые конфликтовали с логикой оператора;
- ресурс EtcdBackup переименован в EtcdSnapshot, семантика сохранена;
- валидация перенесена с webhook на CEL-правила в CRD;
- сервис кластера переведён в режим headless, чтобы у узлов были стабильные DNS-имена.
Миграция проходит на месте с помощью etcd-migrate. Инструмент адаптирует работающий кластер старого оператора без переноса данных, перезапуска Pod и потери кворума. Он меняет только владельцев объектов, метки и аннотации. После этого новый оператор берёт управление на себя. Клиенты, которые обращаются к кластеру по DNS-имени, продолжают работать без изменений.
Реализация etcd-operator от Cozystack закрывает большинство пунктов плана развития официального etcd-оператора проекта etcd. Статус по пунктам плана:
- Создание нового кластера etcd, например из 3 или 5 узлов, с указанной версией etcd — реализовано.
- Определение состояния здоровья кластера — реализовано.
- Включение TLS-шифрования соединений, включая продление сертификатов — реализовано.
- Обновление в пределах патч-версий или на одну минорную версию — реализовано частично: значение spec.version применяется только к новым узлам.
- Масштабирование в обе стороны, например 1 -> 3 -> 5 узлов и обратно — реализовано.
- Настройка параметров etcd через флаги или переменные окружения — реализовано как закрытый типизированный набор параметров.
- Восстановление одного отказавшего члена кластера, если кворум сохраняется — реализовано частично: автоматической замены членов с повреждённым PVC пока нет.
- Восстановление после отказа нескольких членов кластера и потери кворума — не реализовано, работа запланирована.
- Создание резервной копии кластера по запросу — реализовано.
- Периодическое резервное копирование кластера — сознательно вынесено за рамки оператора: периодические снапшоты предлагается запускать штатным CronJob.
Кроме того, v1alpha2 даёт возможности, которых нет в плане развития официального оператора:
- остановка кластера до нуля реплик, пауза и возобновление с сохранением идентичности кластера и узлов;
- хранилище в памяти (tmpfs) с автоматической заменой узлов силами оператора;
- валидация на стороне apiserver через CEL, без webhook и зависимости от сертификатов;
- автоматический PodDisruptionBudget для голосующих узлов;
- подресурс /scale с заполненным status.selector, чтобы напрямую работали kubectl scale и VerticalPodAutoscaler.targetRef;
- проброс параметров планирования affinity и topologySpreadConstraints, а также объединение additionalMetadata во всех объектах, которые создаёт оператор;
- инструмент миграции с прежнего оператора без остановки кластера;
- плагин kubectl-etcd для эксплуатационных задач.
|