Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Руководство по настройке ClickHouse Operator

В этом руководстве рассказывается, как настроить кластеры 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.

Интеграция с Keeper

Для координации в каждом кластере 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

Конфигурация хранилища

Настройте постоянное хранилище с помощью dataVolumeClaimSpec — стандартного Kubernetes PersistentVolumeClaimSpec. Оператор преобразует его в отдельный PersistentVolumeClaim для каждой реплики, смонтированный по пути /var/lib/clickhouse:

spec:
  dataVolumeClaimSpec:
    storageClassName: fast-ssd  # Optional: consider your storage class based on the installed CSI
    resources:
      requests:
        storage: 100Gi

Подключение дополнительных дисков в конфигурации с несколькими дисками (JBOD), работа без постоянного тома, увеличение емкости, пользовательские политики хранения, шифрование данных при хранении и правила, определяющие, что нельзя изменить после создания, рассматриваются в отдельном руководстве по хранилищу и томам.

Домен кластера

spec.clusterDomain задаёт DNS-суффикс Kubernetes, который оператор использует при формировании полных доменных имён подов, записываемых в конфигурацию сервера ClickHouse. По умолчанию используется cluster.local; этот параметр есть как в ClickHouseCluster, так и в KeeperCluster.

spec:
  clusterDomain: cluster.local   # default; override only for a custom domain

Для реплик ClickHouse оператор создаёт управляющий headless Service <cluster-name>-clickhouse-headless, обслуживающий клиентский трафик. А также сервисы для каждой реплики <cluster-name>-clickhouse-internal-<shard>-<index>, которые публикуют неготовые поды для внутреннего трафика и запросов управления от оператора. Это можно использовать для восстановления реплики, если она не может перейти в состояние готовности самостоятельно.

Узлы Keeper используют имена подов через свой headless Service: <pod>.<headless-service>.<namespace>.svc.<clusterDomain>.

Настройка пода

Автоматическое топологическое распределение и аффинность

Распределите поды по зонам доступности:

spec:
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname

Ручная конфигурация

Можно указать произвольные правила affinity/anti-affinity для подов и ограничения на распределение по топологии.

spec:
  podTemplate:
    affinity:
      <your-affinity-rules-here>
    topologySpreadConstraints:
      <your-topology-spread-constraints-here>

Все поддерживаемые параметры шаблона пода см. в справочнике по API.

Бюджеты сбоев подов

Оператор создает 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%

Вы также можете передать поле 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:

# default values
spec:
  containerTemplate:
    resources:
      requests:
        cpu: "250m"
        memory: "512Mi"
      limits:
        cpu: "1"
        memory: "512Mi"

Переменные окружения

Добавьте пользовательские переменные окружения:

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

Все поддерживаемые параметры шаблона контейнера см. в справочнике по API.

Конфигурация TLS/SSL

Настройка защищённых конечных точек

Укажите ссылку на Secret Kubernetes с TLS-сертификатами, чтобы включить защищённые конечные точки

spec:
  settings:
    tls:
      enabled: true
      required: true # Незащищённые порты отключаются при установке этого параметра
      serverCertSecret:
        name: <certificate-secret-name>

Формат Secret с SSL-сертификатом

Предполагается, что Secret содержит серверную пару ключей:

  • tls.crt - серверный сертификат в PEM-формате
  • tls.key - приватный ключ в PEM-формате

Взаимодействие ClickHouse-Keeper по TLS

Если в KeeperCluster включен TLS, ClickHouseCluster будет автоматически использовать защищенное соединение с узлами Keeper.

ClickHouseCluster проверяет сертификаты узлов Keeper по системному хранилищу доверенных сертификатов, а также по любому настроенному вами caBundle.

Чтобы доверять частному CA (например, самоподписанному или внутреннему CA), укажите ссылку на пользовательский набор CA:

spec:
    settings:
        tls:
          caBundle:
            name: <ca-certificate-secret-name>
            key: <ca-certificate-key>

External Secret

По умолчанию оператор создает Secret с внутренними учетными данными кластера и управляет им (межсерверный пароль, пароль управления, идентификатор Keeper, секрет кластера, ключ named-collections). Secret получает имя кластера и находится в его пространстве имен.

Если вы хотите управлять этими учетными данными самостоятельно — например, получать их из HashiCorp Vault, AWS Secrets Manager или External Secrets Operator — укажите оператору уже существующий Secret с помощью spec.externalSecret:

apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: sample
spec:
  replicas: 2
  keeperClusterRef:
    name: sample
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 10Gi
  externalSecret:
    name: my-clickhouse-credentials
    policy: Observe

Обязательные ключи

Secret должен содержать следующие ключи:

Ключ Формат Когда требуется
interserver-password пароль в открытом виде Всегда
management-password пароль в открытом виде Всегда
keeper-identity clickhouse:<password> Всегда
cluster-secret пароль в открытом виде Всегда
named-collections-key 16-байтный ключ AES в шестнадцатеричном виде (32 шестнадцатеричных символа) Только для ClickHouse >= 25.12
disk-encryption-key 16-байтный ключ AES в шестнадцатеричном виде (32 шестнадцатеричных символа) Только если задан параметр settings.encryption

Полный Secret выглядит так:

apiVersion: v1
kind: Secret
metadata:
  name: my-clickhouse-credentials
  namespace: sample
type: Opaque
stringData:
  interserver-password: "a-strong-random-password"
  management-password: "another-strong-password"
  keeper-identity: "clickhouse:keeper-auth-password"
  cluster-secret: "cluster-internal-secret"
  named-collections-key: "0123456789abcdef0123456789abcdef"   # 32 hex chars = 16 bytes
  disk-encryption-key: "00112233445566778899aabbccddeeff"     # only when settings.encryption is set

Политика: Observe или Manage

spec.externalSecret.policy определяет, как оператор обрабатывает отсутствие обязательных ключей:

Политика Поведение при отсутствии ключей
Observe (по умолчанию) Реконсиляция блокируется, пока не появятся все обязательные ключи. Оператор сообщает о каждом отсутствующем ключе — и подсказке по его формату — через условие ExternalSecretValid (с причиной ExternalSecretInvalid) и событие Warning.
Manage Оператор генерирует все отсутствующие обязательные ключи и записывает их обратно в тот же Secret. Полезно для начальной инициализации: создайте пустой Secret, позвольте оператору заполнить его, а затем при необходимости ограничьте доступ. При этом оператор по-прежнему никогда не удаляет Secret.

Выбирайте Observe, если внешний источник (Vault, ESO, sealed-secrets, GitOps) является источником истины и вы хотите, чтобы оператор явно сигнализировал об ошибке конфигурации. Выбирайте Manage, если вам нужна самодостаточная начальная инициализация, но при этом вы хотите сохранить контроль над самим объектом Secret (например, чтобы делать его резервную копию).

Условие состояния и устранение неполадок

Оператор выставляет условие ExternalSecretValid в ClickHouseCluster.status.conditions. Проверьте его, если кажется, что реконсиляция зависла:

# Plain kubectl — works out of the box
kubectl describe clickhousecluster sample | sed -n '/Conditions:/,$p'

# Same data as YAML
kubectl get clickhousecluster sample -o yaml | sed -n '/conditions:/,/^[^ ]/p'

# Pretty-printed JSON (requires jq)
kubectl get clickhousecluster sample -o jsonpath='{.status.conditions}' | jq

Возможные причины:

reason Значение Исправление
ExternalSecretNotFound Указанный Secret не существует в пространстве имен. Создайте Secret или исправьте spec.externalSecret.name.
ExternalSecretInvalid Secret существует, но в нем отсутствуют обязательные ключи (только при Observe). В сообщении перечислены все отсутствующие ключи и ожидаемый для них формат. Добавьте отсутствующие ключи или переключитесь на policy: Manage.
ExternalSecretValid Все обязательные ключи присутствуют, и оператор использует этот Secret.

Пока Secret недействителен, оператор повторно ставит реконсиляцию в очередь, поэтому после добавления отсутствующих ключей следующая реконсиляция автоматически их подхватит — перезапускать поды не нужно.

Дополнительные порты

Оператор предоставляет фиксированный набор портов на каждом поде ClickHouse и в его публичном headless Service: 8123 HTTP, 9000 нативный, 9009 interserver, 9001/9002 management, 9363 метрики Prometheus, а также варианты с TLS 8443/9440, если TLS включен. Порты interserver и management дополнительно предоставляются через внутренние Service каждой реплики, чтобы реплики и оператор могли взаимодействовать до того, как реплика станет готовой. Чтобы ClickHouse прослушивал дополнительные протоколы — MySQL, PostgreSQL, gRPC — или любой пользовательский порт, объявите их в spec.additionalPorts:

spec:
  additionalPorts:
    - name: mysql
      port: 9004
    - name: postgres
      port: 9005
    - name: grpc
      port: 9100

Оператор добавляет эти порты в containerPorts пода и в публичный headless Service. Полный пример приведён в examples/custom_protocols.yaml.

Полный пример: протокол MySQL

Чтобы предоставить доступ к ClickHouse по протоколу MySQL на порту 9004:

apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: sample
spec:
  replicas: 1
  keeperClusterRef:
    name: sample
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 2Gi

  # 1) Open the port on the Pod and the public headless Service.
  additionalPorts:
    - name: mysql
      port: 9004

  # 2) Tell ClickHouse server to actually listen on it.
  settings:
    extraConfig:
      protocols:
        mysql:
          type: mysql
          port: 9004
          description: "MySQL wire protocol"

После применения проверьте, находясь внутри кластера:

kubectl exec sample-clickhouse-0-0-0 -- \
  clickhouse-client --port 9004 --query "SELECT 1"

Ограничения для полей

Поле Правило
name Должно соответствовать шаблону регулярного выражения DNS_LABEL ^[a-z]([-a-z0-9]*[a-z0-9])?$; максимальная длина — 63 символа. Уникальность обеспечивается CRD за счёт ключа list-map.
port Целое число в диапазоне [1, 65535]. вебхук отклоняет повторяющиеся номера портов в пределах списка.

Зарезервированные порты и имена

Валидирующий вебхук отклоняет записи additionalPorts, которые пересекаются с портами, используемыми самим оператором. Все порты, связанные с TLS, зарезервированы безусловно, чтобы последующее включение spec.settings.tls.enabled не нарушило работу ранее корректного кластера.

Порт Зарезервирован для
8123 HTTP
8443 HTTPS
9000 нативный TCP
9440 нативный TLS
9009 interserver
9001 management
9363 метрики Prometheus

Следующие имена также отклоняются — это внутренние идентификаторы типов протоколов оператора (а не человекочитаемые псевдонимы):

Имя
http
http-secure
tcp
tcp-secure
interserver
management
prometheus

Отклонённый запрос приводит к ошибке вида:

spec.additionalPorts[0].port: 8123 is reserved for the operator-managed HTTP port
spec.additionalPorts[0].name: "http" is reserved by the operator

Проверка версии и канал обновления

Оператор выполняет две независимые функции, связанные с версиями кластера:

  1. Проверка версии — для ClickHouseCluster Kubernetes задача однократно запускает контейнерный образ, чтобы определить запущенную версию ClickHouse; для KeeperCluster оператор считывает версию, сообщаемую сервером, с работающих реплик. Определённая версия записывается в .status.version и используется другими этапами реконсиляции (например, ключ named-collections для External Secret требуется только начиная с ClickHouse 25.12).
  2. Канал обновления — периодическая проверка публичной ленты релизов ClickHouse (https://clickhouse.com/data/version_date.tsv). Оператор сообщает о наличии более новой версии через условие состояния VersionUpgraded. Самостоятельно кластер он никогда не обновляет — тег образа контролирует пользователь.

Выбор канала обновления

spec.upgradeChannel задаёт, с каким набором апстримных релизов сверяется оператор. Такое же поле есть и в ClickHouseCluster, и в KeeperCluster.

spec:
  upgradeChannel: lts   # or "stable", or "25.8", or omitted

Допустимые значения (проверяются CRD по шаблону ^(lts|stable|\d+\.\d+)?$):

Значение Поведение
empty (default) Оператор предлагает только минорные обновления в пределах текущей ветки major.minor. Кластеру на 25.8.3.1 будет предложено 25.8.4.x, но не 25.9.x.
stable Отслеживает вышестоящий канал stable — последний релиз, который ClickHouse Inc. помечает как стабильный в основной ветке релизов. Получает мажорные обновления раньше, чем канал lts.
lts Отслеживает вышестоящий канал lts — релизы с долгосрочной поддержкой. Получает мажорные обновления реже, а окна поддержки у них дольше.
25.8 (или любой <major>.<minor>) Закрепляет канал за конкретной веткой major.minor. Мажорные обновления за её пределами не предлагаются, даже если вышестоящая версия новее.

Для продакшн обычно предпочтительнее явно закрепить канал на значении <major>.<minor> (например, 25.8). Это фиксирует кластер на нужной ветке мажорных релизов и позволяет оператору выдавать предупреждение WrongReleaseChannel, если какая-либо реплика по какой-то причине перейдёт на другой мажорный релиз, — что особенно важно, когда image указан по дайджесту (@sha256:...), а не по человекочитаемому тегу. Пустое значение по умолчанию подходит для Development-clusters, где переходы между мажорными версиями не критичны.

Условия

Два условия показывают результат проверки версии и проверки обновления:

Условие Причина Значение
VersionInSync VersionMatch Все реплики сообщают одну и ту же версию
VersionInSync VersionMismatch Реплики работают на разных версиях. Предупреждающее событие подавляется во время запланированного поэтапного обновления. Обычно это происходит, когда закреплён изменяемый тег образа (например, latest или просто мажорная версия, такая как 26.3), а содержимое в реестре между загрузками изменилось, поэтому разные реплики оказались на разных патч-версиях одного и того же тега.
VersionInSync VersionPending Задача проверки версии ещё не завершилась, или версия реплики Keeper ещё не была обнаружена
VersionInSync VersionProbeFailed Задача probe ClickHouse завершилась с ошибкой; оператор не может определить запущенную версию
VersionUpgraded UpToDate Кластер использует последнюю версию, доступную в выбранном канале
VersionUpgraded MinorUpdateAvailable В той же ветке major.minor доступен более новый патч
VersionUpgraded MajorUpdateAvailable В рамках выбранного канала доступна более новая версия major.minor
VersionUpgraded VersionOutdated Запущенная версия устарела и больше не будет получать исправления из выбранного канала — обычно потому, что эта мажорная ветка больше не поддерживается в upstream lts или stable
VersionUpgraded WrongReleaseChannel Запущенный образ не относится к выбранному upgradeChannel. Пример: кластер работает на 26.5 с upgradeChannel: lts, поскольку 26.5 не входит в upstream-ветку lts.
VersionUpgraded UpgradeCheckFailed Оператор не смог получить доступ к upstream-источнику сведений о релизах

Проверьте их с помощью:

kubectl get clickhousecluster sample -o yaml | sed -n '/conditions:/,/^[^ ]/p'

Переопределение задачи проверки версии

Это относится только к ClickHouseCluster. KeeperCluster больше не запускает задачу проверки версии — его версия считывается напрямую с работающих реплик Keeper, — поэтому spec.versionProbeTemplate устарел и там не действует.

Проверка реализована как обычная Kubernetes задача. Если в вашем кластере действуют политики допуска, требующие определённых Tolerations, селекторов узлов или контекстов безопасности, либо вы хотите ограничить время, в течение которого завершённые задачи проверки остаются в системе, переопределите шаблон через spec.versionProbeTemplate:

spec:
  versionProbeTemplate:
    spec:
      ttlSecondsAfterFinished: 600   # delete completed probe Jobs 10 minutes after completion
      template:
        spec:
          nodeSelector:
            kubernetes.io/arch: amd64
          tolerations:
            - key: dedicated
              operator: Equal
              value: clickhouse
              effect: NoSchedule
          containers:
            - name: version-probe
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi

Имя контейнера version-probe задано в операторе по умолчанию — запись в containers: совпадает с ним по имени, поэтому оператор выполняет глубокое слияние пользовательских полей со значениями по умолчанию.

Глобальные настройки оператора

Два флага в менеджере оператора глобально управляют циклом проверки обновлений:

Флаг По умолчанию Эффект
--version-update-interval 24h Как часто оператор повторно получает список версий из внешнего источника
--disable-version-update-checks false Полностью отключает проверку обновлений. Условие VersionUpgraded не устанавливается, и исходящий HTTP-трафик на clickhouse.com не создаётся

Установите --disable-version-update-checks=true в полностью изолированных средах или если исходящий трафик на clickhouse.com не разрешён.

Настройки ClickHouse

Пароль пользователя default

spec.settings.defaultUserPassword задаёт пароль для встроенного пользователя default. Укажите значение из ключа в Secret (рекомендуется) или в ConfigMap, который вы создадите, вместо того чтобы задавать его напрямую в CR:

spec:
  settings:
    defaultUserPassword:
      passwordType: password   # default; see "Password types" below
      secret:                  # exactly one of secret or configMap
        name: clickhouse-password   # name of the Secret/ConfigMap
        key: password               # the key inside it, not the password value

Укажите ровно одно из secret или configMap; при этом должны быть заданы и name (объект), и key (запись, в которой хранится пароль).

Типы паролей

passwordType указывает ClickHouse, как интерпретировать значение. По умолчанию используется password (plaintext); альтернативные варианты — это хешированные формы, например password_sha256_hex и password_double_sha1_hex. Рекомендуется использовать хешированный тип, чтобы plaintext никогда не хранился. Полный список см. в разделе настроек пользователей ClickHouse.

Полный пример с объектом Secret

Создайте объект Secret, затем укажите его ключ:

kubectl create secret generic clickhouse-password \
  --from-literal=password='your-secure-password'
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: my-cluster
spec:
  settings:
    defaultUserPassword:
      passwordType: password
      secret:
        name: clickhouse-password
        key: password

Для пароля в виде хеша сохраните хеш вместо незашифрованного текста:

echo -n 'your-secure-password' | sha256sum   # use the hex digest as the value
kubectl create secret generic clickhouse-password \
  --from-literal=password='<sha256-hex-digest>'
spec:
  settings:
    defaultUserPassword:
      passwordType: password_sha256_hex
      secret:
        name: clickhouse-password
        key: password

Использование ConfigMap

ConfigMap работает так же, но его содержимое не защищено так, как содержимое Secret. Используйте его только для неконфиденциальных или уже хешированных значений, например дайджеста password_sha256_hex:

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  # Default: true

Когда эта настройка включена, оператор синхронизирует таблицы Replicated и интеграционные таблицы на новые реплики.

Каждый под реплики имеет шлюз готовности clickhouse.com/ReplicaInitialized, поэтому новая реплика публикуется через публичный headless Service только после того, как оператор завершит ее инициализацию: база данных default преобразуется в движок Replicated, а схема синхронизируется. До этого оператор и другие реплики обращаются к ней через ее внутренний Service. При enableDatabaseSync: false оператор сразу помечает реплики как инициализированные, поэтому готовность определяется только проверками контейнера.

Оператор никогда не удаляет заполненную нереплицируемую базу данных default. Такая реплика все равно начинает обслуживать клиентский трафик после подготовки схемы, но кластер сообщает SchemaInSync=False с причиной DefaultDatabaseNotReplicated, пока вы самостоятельно не устраните проблему с этой базой данных.

Перед удалением реплики при масштабировании вниз оператор сначала перенаправляет клиентский трафик с нее, ожидает, пока она перестанет публиковаться, реплицирует оставшиеся данные на оставшиеся реплики и только затем удаляет ее.

Логирование сервера

Настройте логирование сервера ClickHouse через spec.settings.logger. Все поля необязательны и имеют безопасные значения по умолчанию, поэтому даже кластер, который вы ни разу не изменяли, уже пишет журналы уровня trace и в консоль контейнера, и в ротируемый файл на диске.

spec:
  settings:
    logger:
      logToFile: true   # Default: true. Set false to log only to the console
      jsonLogs: false   # Default: false. Set true for structured JSON log lines
      level: trace      # Default: trace
      size: 1000M       # Default: 1000M. Rotate a log file once it reaches this size
      count: 50         # Default: 50. Number of rotated files to keep
Поле По умолчанию Описание
logToFile true Если false, оператор отключает вывод в файлы, и сервер пишет журнал только в консоль контейнера.
jsonLogs false Если true, оператор добавляет formatting.type: json, так что каждая строка становится объектом JSON.
level trace Уровень подробности журнала. Один из test, trace, debug, information, notice, warning, error, critical, fatal.
size 1000M Максимальный размер одного файла журнала до ротации.
count 50 Количество файлов журнала после ротации, которые сервер сохраняет.

Оператор всегда оставляет логирование в консоль включённым, чтобы работал kubectl logs, а при logToFile со значением true дополнительно включает файловый журнал. В кластере с настройками по умолчанию получается такой блок logger:

logger:
  console: true
  level: trace
  log: /var/log/clickhouse-server/clickhouse-server.log
  errorlog: /var/log/clickhouse-server/clickhouse-server.err.log
  size: 1000M
  count: 50

Тот же блок spec.settings.logger применяется и к KeeperCluster; в этом случае оператор записывает файлы в каталог /var/log/clickhouse-keeper/.

Пользовательская конфигурация

Встроенная дополнительная конфигурация

Вместо подключения пользовательских файлов конфигурации можно напрямую указать дополнительные параметры конфигурации 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

См. документацию с полным перечнем поддерживаемых параметров конфигурации пользователей 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
Navigation