Конфигурация ClickHouseCluster
Базовая конфигурация
Реплики и сегменты
- Реплики: Количество экземпляров ClickHouse в каждом сегменте (для высокой доступности)
- Сегменты: Количество горизонтальных сегментов (для масштабирования)
replicas: 3 и shards: 2 создаст всего 6 подов ClickHouse.
Интеграция с Keeper
Для координации каждому кластеру ClickHouse требуется ансамбль Keeper. Задайте ровно один из параметров:keeperClusterRef или externalKeeper; кластер, в котором заданы оба параметра или не задан ни один, будет отклонён.
Укажите в keeperClusterRef ссылку на KeeperCluster, которым управляет этот оператор:
keeperClusterRef.namespace, оператор должен отслеживать оба пространства имен. Если настроена переменная WATCH_NAMESPACE, включите в этот список пространства имен ClickHouse и Keeper.
Keeper с внешним управлением
ИспользуйтеexternalKeeper, чтобы подключить ClickHouse к ансамблю Keeper, которым оператор не управляет, —
например, к ансамблю, принадлежащему другому оператору, работающему в другом кластере Kubernetes, на виртуальных машинах или
физических серверах (bare metal) либо совместно используемому несколькими системами:
port равен 9181. host — это DNS-имя или IP-адрес; IPv6-адреса заключайте в квадратные
скобки. Чтобы подключаться по TLS, задайте tls: Enabled, а в port укажите порт, на котором ансамбль принимает
защищённые соединения:
caBundle, если вы его настроили.
См. раздел Взаимодействие ClickHouse и Keeper по TLS.
Если несколько кластеров ClickHouse используют один ансамбль Keeper, задайте для каждого из них собственный корневой znode через
settings.extraConfig, чтобы их метаданные репликации, пользователи, созданные через SQL, и именованные коллекции
не конфликтовали между собой. Создайте znode до запуска ClickHouse и в дальнейшем не изменяйте его:
zookeeper.root в settings.extraReloadableConfig: при перезагрузке конфигурации корень работающего кластера изменится, а его реплицируемые таблицы перейдут в режим только для чтения. Если для корневого znode заданы ACL, они должны разрешать
keeper-identity кластера создавать дочерние znode.
Оператор не изменяет эти серверы и не ожидает их готовности, прежде чем выполнять сверку ClickHouse.
За доступность ансамбля отвечает пользователь.
Аутентификация выполняется так же, как и для Keeper под управлением оператора: оператор считывает
ключ keeper-identity из Secret кластера и передаёт его в ClickHouse. Структура Secret описана в разделе
External Secret.
Конфигурация KeeperCluster
Передача лидерства при завершении работы
В контейнере Keeper по умолчанию настроен хукpreStop, который перед остановкой просит реплику передать Raft-лидерство
и дожидается завершения передачи, прежде чем позволить
контейнеру завершиться. Хук срабатывает при каждой корректной остановке контейнера, а не только
при развертываниях, инициированных оператором: вытеснение descheduler-ом, дренирование узлов (drain) или действие
автомасштабировщика запускают один и тот же хук, поскольку это обработчик preStop уровня Кубелета, а
не логика цикла сверки (reconcile loop).
Без этого хука перезапуск текущего лидера оставляет ансамбль без лидера до завершения
новых выборов, что под нагрузкой может занимать несколько секунд и проявляется в
ClickHouse как потеря соединения с Keeper и рост задержки запросов. Хук просит
реплику уступить лидерство (четырёхбуквенная команда Keeper ydld, отправляемая через
порт http_control), а затем опрашивает статус реплики, пока она не перестанет быть
лидером, вместо того чтобы отправить запрос и сразу позволить контейнеру остановиться: запрос
в режиме fire-and-forget при высокой нагрузке на запись всё равно может проиграть гонку с SIGTERM, поэтому
именно ожидание гарантирует, что период без лидера будет ограничен.
Хук не требует настройки и корректно деградирует: в версиях Keeper ниже
26.3, где используемые здесь команды управления лидерством ещё не поддерживаются, запрос не имеет эффекта, и
контейнер останавливается так же, как без хука. Хук запускает shell-скрипт, поэтому в образе
должен быть bash; если вы используете distroless- или scratch-образ Keeper, переопределите или удалите
хук через containerTemplate.lifecycle — см.
справочник по API.
Конфигурация хранилища
dataVolumeClaimSpec — стандартного Kubernetes
PersistentVolumeClaimSpec. Оператор преобразует его в отдельный PersistentVolumeClaim для каждой реплики,
смонтированный по пути /var/lib/clickhouse:
Оператор может изменять существующий PVC, только если используемый класс хранилища поддерживает расширение томов.
Домен кластера
spec.clusterDomain задаёт DNS-суффикс Kubernetes, который оператор использует при формировании
полных доменных имён подов, записываемых в конфигурацию
сервера ClickHouse. По умолчанию используется cluster.local; этот параметр есть как в
ClickHouseCluster, так и в KeeperCluster.
<cluster-name>-clickhouse-headless, обслуживающий клиентский трафик.
А также сервисы для каждой реплики <cluster-name>-clickhouse-internal-<shard>-<index>, которые публикуют неготовые поды для внутреннего трафика
и запросов управления от оператора. Это можно использовать для восстановления реплики, если она не может перейти в состояние готовности самостоятельно.
Узлы Keeper используют имена подов через свой headless Service: <pod>.<headless-service>.<namespace>.svc.<clusterDomain>.
Переопределяйте это только в том случае, если
kubelet в вашем кластере запущен с параметром --cluster-domain,
отличным от cluster.local. Если значение не совпадает с фактическим доменом кластера,
ClickHouse не сможет разрешить имена хостов Keeper и реплик — координация и
запросы Distributed будут завершаться ошибками DNS resolution. Установите одно и то же значение в
ClickHouseCluster и в KeeperCluster, на который он ссылается.Настройка пода
Автоматическое топологическое распределение и аффинность
Распределите поды по зонам доступности:Убедитесь, что в вашем кластере Kubernetes достаточно узлов в разных зонах, чтобы выполнить требования к распределению.
topologyMinDomains равным количеству зон доступности, чтобы принудительно обеспечить распределение:
Для
topologyMinDomains требуется topologyZoneKey. Поды остаются в состоянии Pending, пока
доступно меньше зон, чем запрошено, поэтому указывайте значение в пределах числа зон, которое может предоставить ваш кластер.Ручная конфигурация
Все поддерживаемые параметры шаблона пода см. в справочнике по API.
Бюджеты сбоев подов
Значения по умолчанию
apply защитить его от случайной потери кворума.
Для ClickHouseCluster с 3 сегментами и
replicas: 3 оператор создаёт три PDB — по одному на каждый сегмент, каждый с minAvailable: 1.
Переопределение значений по умолчанию
spec.podDisruptionBudget, чтобы переопределить либо minAvailable, либо maxUnavailable (ровно одно из них):
maxUnavailable с указанием в процентах:
unhealthyPodEvictionPolicy в сгенерированный PDB — это полезно, если нужно разрешить вытеснение подов, которые всё ещё находятся в состоянии NotReady:
Политики
spec.podDisruptionBudget.policy позволяет выбрать, насколько активно оператор управляет PDB:
Пример — полностью отключить управление PDB в кластере разработки:
Отключение на уровне всего кластера
ENABLE_PDB. При ENABLE_PDB=false оператор пропускает шаг сверки PDB для всех ClickHouseCluster и KeeperCluster независимо от их spec.podDisruptionBudget.policy и вообще не отслеживает ресурсы PodDisruptionBudget. Поэтому ServiceAccount оператора не нужны разрешения RBAC на poddisruptionbudgets.policy/v1, что полезно, если оператор запускается с ограниченным ServiceAccount, в котором эти разрешения намеренно отсутствуют.
Настройка контейнера
Собственный образ
Ресурсы контейнеров
Переменные окружения
Подключение томов
Допускается указывать несколько подключений томов к одному и тому же
mountPath.
Оператор создаст projected volume со всеми указанными подключениями.Проверки состояния
Оператор настраивает проверки работоспособности (liveness) и готовности (readiness) для каждого контейнера ClickHouse и Keeper. Проверка запуска (startup) по умолчанию не задаётся.
ClickHouse и Keeper используют одинаковые временные параметры по умолчанию:
ClickHouse начинает принимать межсерверные подключения ещё до загрузки таблиц, а клиентские — только после неё. Поэтому медленная загрузка таблиц не приводит к сбою проверки работоспособности, а успешная проверка готовности означает, что реплика уже обслуживает запросы.
Любую проверку можно переопределить через
spec.containerTemplate в любом из этих ресурсов. Например, вот как настроить проверку работоспособности ClickHouse:
Проверка запуска (startup probe)
ИспользуйтеstartupProbe, если контейнеру для запуска нужно больше времени, чем допускает проверка работоспособности (liveness probe): при значениях по умолчанию это около 60 секунд начальной задержки плюс 10 неудачных проверок с интервалом 5 секунд.
Kubernetes не запускает проверки работоспособности и готовности, пока проверка запуска не завершится успешно, поэтому медленный запуск не вызывает бесконечного цикла перезапусков.
Например, можно дать реплике Keeper, которая воспроизводит большой снимок, до 10 минут, прежде чем она начнёт принимать соединения:
Все поддерживаемые параметры шаблона контейнера см. в справочнике по API.
Конфигурация TLS/SSL
Настройка защищённых конечных точек
Формат Secret с SSL-сертификатом
tls.crt- серверный сертификат в PEM-форматеtls.key- приватный ключ в PEM-формате
Этот формат совместим с сертификатами, созданными cert-manager.
Взаимодействие ClickHouse-Keeper по TLS
Если в KeeperCluster, на который ссылаетсяkeeperClusterRef, включен TLS, ClickHouseCluster будет автоматически использовать защищенное соединение с узлами Keeper.
При использовании externalKeeper вместо этого укажите tls: Enabled, а в поле port каждого узла задайте защищенный клиентский порт ансамбля (например, 9281).
ClickHouseCluster проверяет сертификаты узлов Keeper по системному хранилищу доверенных сертификатов, а также по любому настроенному вами caBundle.
Чтобы доверять частному CA (например, самоподписанному или внутреннему CA), укажите ссылку на пользовательский набор CA:
External Secret
spec.externalSecret:
Указанный Secret должен находиться в том же пространстве имен, что и ClickHouseCluster. Оператор никогда не удаляет Secret, если не создавал его сам.
Обязательные ключи
Полный Secret выглядит так:
Политика: Observe или Manage
spec.externalSecret.policy определяет, как оператор обрабатывает отсутствие обязательных ключей:
Даже при
policy: Manage Secret уже должен существовать в пространстве имен — оператор никогда не создает сам Secret, а только записывает сгенерированные ключи в уже существующий. Если указанный Secret отсутствует, реконсиляция блокируется с причиной ExternalSecretNotFound независимо от политики.Observe, если внешний источник (Vault, ESO, sealed-secrets, GitOps) является источником истины и вы хотите, чтобы оператор явно сигнализировал об ошибке конфигурации. Выбирайте Manage, если вам нужна самодостаточная начальная инициализация, но при этом вы хотите сохранить контроль над самим объектом Secret (например, чтобы делать его резервную копию).
Условие состояния и устранение неполадок
ExternalSecretValid в ClickHouseCluster.status.conditions. Проверьте его, если кажется, что реконсиляция зависла:
Пока Secret недействителен, оператор повторно ставит реконсиляцию в очередь, поэтому после добавления отсутствующих ключей следующая реконсиляция автоматически их подхватит — перезапускать поды не нужно.
Набор обязательных ключей зависит от запущенной версии ClickHouse.
named-collections-key проверяется только после того, как проверка версии оператора обнаружит ClickHouse 25.12 или новее. В более старых версиях этот ключ может отсутствовать в Secret. disk-encryption-key требуется только если задано spec.settings.encryption.Дополнительные порты
8123 HTTP, 9000 нативный, 9009 interserver, 9001/9002 management, 9363 метрики Prometheus, а также варианты с TLS 8443/9440, если TLS включен. Порты interserver и management дополнительно предоставляются через внутренние Service каждой реплики, чтобы реплики и оператор могли взаимодействовать до того, как реплика станет готовой. Чтобы ClickHouse прослушивал дополнительные протоколы — MySQL, PostgreSQL, gRPC — или любой пользовательский порт, объявите их в spec.additionalPorts:
containerPorts пода и в публичный headless Service.
Полный пример приведён в examples/custom_protocols.yaml.
Полный пример: протокол MySQL
9004:
Ограничения для полей
Зарезервированные порты и имена
additionalPorts, которые пересекаются с портами, используемыми самим оператором. Все порты, связанные с TLS, зарезервированы безусловно, чтобы последующее включение spec.settings.tls.enabled не нарушило работу ранее корректного кластера.
Следующие имена также отклоняются — это внутренние идентификаторы типов протоколов оператора (а не человекочитаемые псевдонимы):
Отклонённый запрос приводит к ошибке вида:
Проверка версии и канал обновления
- Проверка версии — для
ClickHouseClusterKubernetesзадачаоднократно запускает контейнерный образ, чтобы определить запущенную версию ClickHouse; дляKeeperClusterоператор считывает версию, сообщаемую сервером, с работающих реплик. Определённая версия записывается в.status.versionи используется другими этапами реконсиляции (например, ключ named-collections дляExternal Secretтребуется только начиная с ClickHouse25.12). - Канал обновления — периодическая проверка публичной ленты релизов ClickHouse (
https://clickhouse.com/data/version_date.tsv). Оператор сообщает о наличии более новой версии через условие состоянияVersionUpgraded. Самостоятельно кластер он никогда не обновляет — тег образа контролирует пользователь.
Выбор канала обновления
spec.upgradeChannel задаёт, с каким набором апстримных релизов сверяется оператор. Такое же поле есть и в ClickHouseCluster, и в KeeperCluster.
^(lts|stable|\d+\.\d+)?$):
Для продакшн обычно предпочтительнее явно закрепить канал на значении
<major>.<minor> (например, 25.8). Это фиксирует кластер на нужной ветке мажорных релизов и позволяет оператору выдавать предупреждение WrongReleaseChannel, если какая-либо реплика по какой-то причине перейдёт на другой мажорный релиз, — что особенно важно, когда image указан по дайджесту (@sha256:...), а не по человекочитаемому тегу. Пустое значение по умолчанию подходит для Development-clusters, где переходы между мажорными версиями не критичны.
Условия
Проверьте их с помощью:
Переопределение задачи проверки версии
ClickHouseCluster. KeeperCluster больше не запускает задачу проверки версии — его версия считывается напрямую с работающих реплик Keeper, — поэтому spec.versionProbeTemplate устарел и там не действует.
Проверка реализована как обычная Kubernetes задача. Если в вашем кластере действуют политики допуска, требующие определённых Tolerations, селекторов узлов или контекстов безопасности, либо вы хотите ограничить время, в течение которого завершённые задачи проверки остаются в системе, переопределите шаблон через spec.versionProbeTemplate:
version-probe задано в операторе по умолчанию — запись в containers: совпадает с ним по имени, поэтому оператор выполняет глубокое слияние пользовательских полей со значениями по умолчанию.
Глобальные настройки оператора
Установите
--disable-version-update-checks=true в полностью изолированных средах или если исходящий трафик на clickhouse.com не разрешён.
Настройки ClickHouse
Пароль пользователя default
spec.settings.defaultUserPassword задаёт пароль для встроенного
пользователя default. Укажите значение из ключа в Secret
(рекомендуется) или в ConfigMap, который вы создадите, вместо того чтобы
задавать его напрямую в CR:
secret или configMap; при этом должны быть заданы и name (объект),
и key (запись, в которой хранится пароль).
Типы паролей
passwordType указывает ClickHouse, как интерпретировать значение. По умолчанию
используется password (plaintext); альтернативные варианты — это
хешированные формы, например password_sha256_hex и password_double_sha1_hex. Рекомендуется использовать
хешированный тип, чтобы plaintext никогда не хранился. Полный список см. в разделе
настроек пользователей ClickHouse.
Полный пример с объектом Secret
При
passwordType: password клиент ClickHouse внутри пода настраивается с
этим паролем, что удобно для отладки.Использование ConfigMap
password_sha256_hex:
Не храните пароль в открытом виде в ConfigMap. Для любого значения в открытом виде
(
passwordType: password) используйте Secret.Дополнительные пользователи в конфигурации
Настройте дополнительных пользователей в файлах конфигурации. Создайте ConfigMap и Secret для пользователя:Синхронизация базы данных
clickhouse.com/ReplicaInitialized, поэтому новая реплика публикуется через публичный headless Service только после того, как оператор завершит ее инициализацию: база данных default преобразуется в движок Replicated, а схема синхронизируется. До этого оператор и другие реплики обращаются к ней через ее внутренний Service. При enableDatabaseSync: false оператор сразу помечает реплики как инициализированные, поэтому готовность определяется только проверками контейнера.
Оператор никогда не удаляет заполненную нереплицируемую базу данных default. Такая реплика все равно начинает обслуживать клиентский трафик после подготовки схемы, но кластер сообщает SchemaInSync=False с причиной DefaultDatabaseNotReplicated, пока вы самостоятельно не устраните проблему с этой базой данных.
Перед удалением реплики при масштабировании вниз оператор сначала перенаправляет клиентский трафик с нее, ожидает, пока она перестанет публиковаться, реплицирует оставшиеся данные на оставшиеся реплики и только затем удаляет ее.
Логирование сервера
Настройте логирование сервера ClickHouse черезspec.settings.logger. Все поля необязательны и имеют безопасные значения по умолчанию, поэтому даже кластер, который вы ни разу не изменяли, уже пишет журналы уровня information и в консоль контейнера, и в ротируемый файл на диске.
Оператор всегда оставляет логирование в консоль включённым, чтобы работал
kubectl logs, а при logToFile со значением true дополнительно включает файловый журнал. В кластере с настройками по умолчанию получается такой блок logger:
spec.settings.logger применяется и к KeeperCluster; в этом случае оператор записывает файлы в каталог /var/log/clickhouse-keeper/ и задаёт для логгера Raft (raft_logs_level) тот же уровень level.
Вывод в консоль остается включенным независимо от
logToFile, поэтому kubectl logs продолжает работать, даже если вы отключите логирование в файл. Установите jsonLogs: true, если отправляете журналы в систему хранения структурированных журналов, которая разбирает JSON.Системные таблицы логов
Оператор включает системные таблицыquery_log, part_log, text_log, metric_log и asynchronous_metric_log. Они хранятся на том же томе, что и данные, поэтому spec.settings.systemLogsTTLDays задаёт для них срок хранения с помощью TTL на уровне таблицы. Если при создании кластера это поле не указано, вебхук устанавливает значение 30 по умолчанию. Чтобы явно отключить TTL, укажите 0.
Значение по умолчанию применяется только к новым кластерам. Для кластера, созданного до появления
systemLogsTTLDays, срок хранения данных в системных таблицах логов остаётся неограниченным, пока вы не зададите значение этого поля вручную.extraConfig можно задать отдельный TTL для каждой таблицы, изменить другие настройки системных журналов или полностью отключить таблицу с помощью атрибута @remove:
При отключении таблица не удаляется: данные остаются на диске, пока вы не удалите таблицу вручную.
При изменении TTL системной таблицы ClickHouse создаёт её заново, а прежние данные сохраняет в таблице с другим именем, например
system.text_log_0. Удалите такие таблицы, когда хранящаяся в них история больше не понадобится.Пользовательская конфигурация
Встроенная дополнительная конфигурация
extraConfig:
Полезные ссылки:
Дополнительная конфигурация, обновляемая без перезапуска
При любом измененииextraConfig поды ClickHouse перезапускаются: оператор не может определить, какие настройки можно применить без перезапуска. Для настроек, которые ClickHouse может обновлять на лету, например named_collections, используйте extraReloadableConfig. Изменения в ней оператор применяет путём повторной загрузки конфигурации, не перезапуская поды:
extraConfig, либо в extraReloadableConfig. Если один и тот же раздел указан в обоих параметрах, оператор выдаст предупреждение.
Используя
extraReloadableConfig, вы подтверждаете, что содержащиеся в нём настройки можно безопасно применять при перезагрузке конфигурации. Настройка, требующая перезапуска, начнёт действовать только после следующего перезапуска, и никакой ошибки при этом не возникнет.Встроенная конфигурация дополнительных пользователей
extraUsersConfig. Это удобно, если нужно определить пользователей, профили, квоты и привилегии прямо в спецификации кластера.
extraUsersConfig хранится в объекте ConfigMap в k8s. Не храните там секретные данные в открытом виде.См. документацию с полным перечнем поддерживаемых параметров конфигурации пользователей ClickHouse.
Пример конфигурации
Периодическая ресинхронизация
Помимо реакции на события Kubernetes, оператор повторно выполняет реконсиляцию каждого кластера через фиксированный интервал. Это поддерживает актуальность условий состояния для тех аспектов, которые не отслеживаются ни одним наблюдением, — работоспособности реплик ClickHouse, кворума Keeper — и позволяет повторять попытки исправления, например очистку зависших подов. Интервал задаётся переменной окружения оператораRESYNC_PERIOD (по умолчанию 30s). Она применяется к ресурсам KeeperCluster, где значение 0 отключает периодическую ресинхронизацию. Ресурсы ClickHouseCluster опрашивают system.warnings в ClickHouse каждые 30 секунд, что и так повторно запускает реконсиляцию, поэтому RESYNC_PERIOD на них в настоящее время не влияет.
MAX_CONCURRENT_RECONCILES (по умолчанию 4).
Приостановка реконсиляции
Добавьте аннотациюclickhouse.com/pause-reconciliation: "true" к ClickHouseCluster или KeeperCluster, чтобы оператор перестал выполнять реконсиляцию ресурса. Для приостановленного ресурса оператор указывает ReconcileSucceeded=False с причиной ReconciliationPaused и больше не вносит в него изменений. Это полезно, когда нужно вручную изменить ресурс, а оператор мог бы отменить ваши изменения. Пока реконсиляция приостановлена, оператор указывает Unknown с причиной ReconciliationPaused для всех условий состояния (включая Ready и Healthy), поскольку не отслеживает кластер. Чтобы возобновить реконсиляцию, удалите аннотацию: накопившиеся изменения в spec будут применены при следующей реконсиляции.