В этом руководстве рассказывается, как настроить кластеры ClickHouse и Keeper с помощью оператора.
Конфигурация ClickHouseCluster
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
name: my-cluster
spec:
replicas: 3 # Количество реплик на сегмент
shards: 2 # Количество сегментов
keeperClusterRef:
name: my-keeper # Ссылка на KeeperCluster
dataVolumeClaimSpec:
resources:
requests:
storage: 10Gi
- Реплики: Количество экземпляров ClickHouse в каждом сегменте (для высокой доступности)
- Сегменты: Количество горизонтальных сегментов (для масштабирования)
spec:
replicas: 3 # По умолчанию: 3
shards: 2 # По умолчанию: 1
Кластер с replicas: 3 и shards: 2 создаст всего 6 подов ClickHouse.
Для координации в каждом кластере ClickHouse должен быть указан KeeperCluster:
spec:
keeperClusterRef:
name: my-keeper
# namespace: keeper-system # Необязательно, по умолчанию используется пространство имён ClickHouseCluster
Когда задан keeperClusterRef.namespace, оператор должен отслеживать оба пространства имен. Если настроена переменная WATCH_NAMESPACE, включите в этот список пространства имен ClickHouse и Keeper.
Конфигурация KeeperCluster
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
name: my-keeper
spec:
replicas: 3 # Должно быть нечётным: 1, 3, 5, 7, 9, 11, 13 или 15
dataVolumeClaimSpec:
resources:
requests:
storage: 5Gi
Настройте постоянное хранилище:
spec:
dataVolumeClaimSpec:
storageClassName: fast-ssd # Необязательно: укажите класс хранилища в соответствии с установленным CSI
resources:
requests:
storage: 100Gi
Оператор может изменять существующий PVC, только если используемый класс хранилища поддерживает расширение томов.
Автоматическое топологическое распределение и аффинность
Распределите поды по зонам доступности:
spec:
podTemplate:
topologyZoneKey: topology.kubernetes.io/zone
nodeHostnameKey: kubernetes.io/hostname
Убедитесь, что в вашем кластере Kubernetes достаточно узлов в разных зонах, чтобы выполнить требования к распределению.
Можно указать произвольные правила affinity/anti-affinity для подов и ограничения на распределение по топологии.
spec:
podTemplate:
affinity:
<your-affinity-rules-here>
topologySpreadConstraints:
<your-topology-spread-constraints-here>
Оператор создает PodDisruptionBudget (PDB) для каждого кластера, чтобы плановые нарушения работы — дренирование узлов, поэтапные обновления, вытеснение автоскейлером — не могли вывести из строя достаточно подов, чтобы потерять кворум или нарушить доступность.
Для кластеров ClickHouse с более чем одним сегментом создается один PDB на каждый сегмент, чтобы сбой в одном сегменте не учитывался в другом.
Оператор выбирает безопасные значения по умолчанию с учётом размера кластера, чтобы уже после первого apply защитить его от случайной потери кворума.
| Ресурс | Топология | PDB по умолчанию |
|---|
ClickHouseCluster | replicas: 1 (сегмент с одной репликой) | maxUnavailable: 1 — для кластера из одного узла прерывание допускается, чтобы не блокировать дренирование узлов |
ClickHouseCluster | replicas: 2+ (сегмент с несколькими репликами) | minAvailable: 1 — в каждом сегменте должна оставаться доступной как минимум одна реплика |
KeeperCluster | replicas: 1 | maxUnavailable: 1 — для кластера из одного узла прерывание допускается, чтобы не блокировать дренирование узлов |
KeeperCluster | replicas: 3+ | maxUnavailable: replicas/2 — сохраняет кворум RAFT для кластера 2F+1 (3 реплики допускают отказ 1, 5 реплик допускают отказ 2) |
Для ClickHouseCluster с 3 сегментами и replicas: 3 оператор создаёт три PDB — по одному на каждый сегмент, каждый с minAvailable: 1.
Переопределение значений по умолчанию
Используйте spec.podDisruptionBudget, чтобы переопределить либо minAvailable, либо maxUnavailable (ровно одно из них):
spec:
replicas: 3
shards: 2
podDisruptionBudget:
minAvailable: 2 # сохранять не менее 2 из 3 реплик в каждом сегменте работоспособными во время сбоя
Или вариант maxUnavailable с указанием в процентах:
spec:
replicas: 5
podDisruptionBudget:
maxUnavailable: 40%
Одновременная установка minAvailable и maxUnavailable отклоняется валидирующим вебхуком. Выберите что-то одно — сам Kubernetes тоже не разрешает задавать оба параметра одновременно.
Вы также можете передать поле unhealthyPodEvictionPolicy в сгенерированный PDB — это полезно, если нужно разрешить вытеснение подов, которые всё ещё находятся в состоянии NotReady:
spec:
podDisruptionBudget:
minAvailable: 2
unhealthyPodEvictionPolicy: AlwaysAllow
spec.podDisruptionBudget.policy позволяет выбрать, насколько активно оператор управляет PDB:
| Policy | Behavior |
|---|
Enabled (по умолчанию) | Оператор создает и обновляет PDB при каждой сверке. Это безопасный вариант по умолчанию для production-сред. |
Disabled | Оператор не создает PDB и удаляет все существующие PDB с совпадающими метками. Полезно для кластеров разработки, где должны быть разрешены любые плановые прерывания. |
Ignored | Оператор не создает и не удаляет PDB. Существующие PDB остаются без изменений. Используйте это, если управлением PDB занимается другая система (например, admission policy или инструмент GitOps). |
Пример — полностью отключить управление PDB в кластере разработки:
spec:
podDisruptionBudget:
policy: Disabled
Пример — оставьте созданный вручную PDB рядом с кластером и не позволяйте оператору его затрагивать:
spec:
podDisruptionBudget:
policy: Ignored
Отключение на уровне всего кластера
Управление PDB также можно отключить на уровне всего кластера через переменную окружения оператора ENABLE_PDB. При ENABLE_PDB=false оператор пропускает шаг сверки PDB для всех ClickHouseCluster и KeeperCluster независимо от их spec.podDisruptionBudget.policy и вообще не отслеживает ресурсы PodDisruptionBudget. Поэтому ServiceAccount оператора не нужны разрешения RBAC на poddisruptionbudgets.policy/v1, что полезно, если оператор запускается с ограниченным ServiceAccount, в котором эти разрешения намеренно отсутствуют.
# в спецификации Развертывания оператора
env:
- name: ENABLE_PDB
value: "false"
Это предназначено для сред, где используются собственные политики disruption (например, через Gatekeeper / Kyverno) и где оператор должен быть полностью исключён из процесса.
Используйте конкретный образ ClickHouse:
spec:
containerTemplate:
image:
repository: clickhouse/clickhouse-server
tag: "25.12"
imagePullPolicy: IfNotPresent
Настройте CPU и память для контейнеров ClickHouse:
# значения по умолчанию
spec:
containerTemplate:
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1"
memory: "1Gi"
Добавьте пользовательские переменные окружения:
spec:
containerTemplate:
env:
- name: CUSTOM_ENV_VAR
value: "1"
Добавьте дополнительные точки монтирования томов:
spec:
containerTemplate:
volumeMounts:
- name: custom-config
mountPath: /etc/clickhouse-server/config.d/custom.xml
subPath: custom.xml
Допускается указывать несколько подключений томов к одному и тому же mountPath.
Оператор создаст projected volume со всеми указанными подключениями.
Укажите ссылку на Secret Kubernetes с TLS-сертификатами, чтобы включить защищённые конечные точки
spec:
settings:
tls:
enabled: true
required: true # Незащищённые порты отключаются при установке этого параметра
serverCertSecret:
name: <certificate-secret-name>
Предполагается, что Secret содержит следующие ключи:
tls.crt - серверный сертификат в PEM-формате
tls.key - приватный ключ в PEM-формате
ca.crt - цепочка CA‑сертификатов в PEM-формате
Этот формат совместим с сертификатами, созданными cert-manager.
Взаимодействие ClickHouse-Keeper по TLS
Если в KeeperCluster включен TLS, ClickHouseCluster будет автоматически использовать защищенное соединение с узлами Keeper.
ClickHouseCluster должен иметь возможность проверять сертификаты узлов Keeper.
Если в ClickHouseCluster включен TLS, для проверки используется комплект ca.crt. В противном случае используется комплект CA по умолчанию.
Пользователь может указать ссылку на пользовательский комплект CA:
spec:
settings:
tls:
caBundle:
name: <ca-certificate-secret-name>
key: <ca-certificate-key>
Пароль пользователя по умолчанию
Задайте пароль пользователя по умолчанию:
spec:
settings:
defaultUserPassword:
passwordType: <password-type> # По умолчанию: password
<secret|configMap>:
name: <resource name>
key: <password>
Не рекомендуется использовать ConfigMap для хранения паролей в открытом виде.
Создайте secret:
kubectl create secret generic clickhouse-password --from-literal=password='your-secure-password'
Использование ConfigMap для паролей пользователей
Вы также можете использовать ConfigMap для паролей по умолчанию, не содержащих конфиденциальных данных:
spec:
settings:
defaultUserPassword:
passwordType: password_sha256_hex
configMap:
name: clickhouse-config
key: default_password
Дополнительные пользователи в конфигурации
Настройте дополнительных пользователей в файлах конфигурации.
Создайте ConfigMap и Secret для пользователя:
apiVersion: v1
kind: ConfigMap
metadata:
name: user-config
data:
reader.yaml: |
users:
reader:
password:
- '@from_env': READER_PASSWORD
profile: default
grants:
- query: "GRANT SELECT ON *.*"
---
apiVersion: v1
kind: Secret
metadata:
name: reader-password
data:
password: "c2VjcmV0LXBhc3N3b3Jk" # base64("secret-password")
Добавьте пользовательскую конфигурацию в ClickHouseCluster:
spec:
podTemplate:
volumes:
- name: reader-user
configMap:
name: user-config
containerTemplate:
env:
- name: READER_PASSWORD
valueFrom:
secretKeyRef:
name: reader-password
key: password
volumeMounts:
- mountPath: /etc/clickhouse-server/users.d/
name: reader-user
readOnly: true
Синхронизация базы данных
Включите автоматическую синхронизацию базы данных для новых реплик:
spec:
settings:
enableDatabaseSync: true # По умолчанию: true
Когда эта настройка включена, оператор синхронизирует таблицы Replicated и интеграционные таблицы на новые реплики.
Пользовательская конфигурация
Вместо подключения пользовательских файлов конфигурации можно напрямую указать дополнительные параметры конфигурации ClickHouse.
Добавьте пользовательскую конфигурацию ClickHouse с помощью extraConfig:
spec:
settings:
extraConfig:
background_pool_size: 20
Вы также можете указать дополнительную конфигурацию пользователей ClickHouse с помощью extraUsersConfig. Это удобно, если нужно определить пользователей, профили, квоты и привилегии прямо в спецификации кластера.
spec:
settings:
extraUsersConfig:
users:
analyst:
password:
- '@from_env': ANALYST_PASSWORD
profile: "readonly"
quota: "default"
profiles:
readonly:
readonly: 1
max_memory_usage: 10000000000
quotas:
default:
interval:
duration: 3600
queries: 1000
errors: 100
extraUsersConfig хранится в объекте ConfigMap в k8s. Не храните там секретные данные в открытом виде.
См. документацию с полным перечнем поддерживаемых параметров конфигурации пользователей ClickHouse.
Полный пример конфигурации:
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
name: sample
spec:
replicas: 3
dataVolumeClaimSpec:
storageClassName: <storage-class-name>
resources:
requests:
storage: 10Gi
podTemplate:
topologyZoneKey: topology.kubernetes.io/zone
nodeHostnameKey: kubernetes.io/hostname
containerTemplate:
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
cpu: "4"
memory: "8Gi"
settings:
tls:
enabled: true
required: true
serverCertSecret:
name: <keeper-certificate-secret>
---
apiVersion: v1
kind: ConfigMap
metadata:
name: default-user-password
data:
# секретный-пароль
password: "..." # sha256 hex пароля
---
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
name: sample
spec:
replicas: 2
dataVolumeClaimSpec:
storageClassName: <storage-class-name>
resources:
requests:
storage: 200Gi
keeperClusterRef:
name: sample
podTemplate:
topologyZoneKey: topology.kubernetes.io/zone
nodeHostnameKey: kubernetes.io/hostname
settings:
tls:
enabled: true
required: true
serverCertSecret:
name: clickhouse-cert
defaultUserPassword:
passwordType: password_sha256_hex
configMap:
key: password
name: default-password
Последнее изменение 10 июня 2026 г.