Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Guide de configuration du ClickHouse Operator

Ce guide explique comment configurer des clusters ClickHouse et Keeper à l’aide du ClickHouse Operator.

Configuration de ClickHouseCluster

Configuration de base

apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: my-cluster
spec:
  replicas: 3           # Number of replicas per shard
  shards: 2             # Number of shards
  keeperClusterRef:
    name: my-keeper     # Reference to KeeperCluster
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 10Gi

Répliques et shards

  • Répliques : nombre d’instances ClickHouse par shard (pour la haute disponibilité)
  • Shards : nombre de partitions horizontales (pour la mise à l’échelle)
spec:
  replicas: 3  # Default: 3
  shards: 2    # Default: 1

Un cluster avec replicas: 3 et shards: 2 créera au total 6 pods ClickHouse.

Intégration de Keeper

Chaque cluster ClickHouse doit faire référence à un KeeperCluster pour la coordination :

spec:
  keeperClusterRef:
    name: my-keeper
    # namespace: keeper-system  # Optional, defaults to the ClickHouseCluster namespace

Lorsque keeperClusterRef.namespace est défini, l’opérateur doit surveiller les deux espaces de noms. Si WATCH_NAMESPACE est configuré, incluez les espaces de noms de ClickHouse et de Keeper dans cette liste.

Configuration de KeeperCluster

apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
  name: my-keeper
spec:
  replicas: 3  # Must be odd: 1, 3, 5, 7, 9, 11, 13, or 15
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 5Gi

Configuration du stockage

Configurez le stockage persistant avec dataVolumeClaimSpec, un PersistentVolumeClaimSpec Kubernetes standard. L’opérateur le convertit en un PersistentVolumeClaim par réplique, monté sur le chemin des données /var/lib/clickhouse :

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

L’ajout de disques supplémentaires dans une configuration multi-disques (JBOD), l’exécution sans volume persistant, l’augmentation de capacité, les politiques de stockage personnalisées, le chiffrement des données au repos ainsi que les règles relatives à ce qui ne peut pas être modifié après la création sont traités dans le guide dédié au stockage et aux volumes.

Domaine du cluster

spec.clusterDomain définit le suffixe DNS Kubernetes que l’opérateur utilise lorsqu’il génère les noms d’hôte complets des pods qu’il inscrit dans la configuration du serveur ClickHouse. La valeur par défaut est cluster.local, et ce champ existe à la fois dans ClickHouseCluster et KeeperCluster.

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

Pour les répliques ClickHouse, l’opérateur crée un Service headless principal <cluster-name>-clickhouse-headless qui gère le trafic client. Il crée également des Services par réplique <cluster-name>-clickhouse-internal-<shard>-<index> qui exposent les pods non prêts au trafic interne et aux requêtes de gestion de l’opérateur. Ils peuvent servir à la récupération d’une réplique si celle-ci ne parvient pas elle-même à devenir prête.

Les nœuds Keeper utilisent les noms de pods via leur Service headless : <pod>.<headless-service>.<namespace>.svc.<clusterDomain>.

Configuration du pod

Répartition topologique et affinité automatiques

Répartissez les pods sur plusieurs zones de disponibilité :

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

Configuration manuelle

Il est possible de définir des règles personnalisées d’affinité/anti-affinité de pods ainsi que des contraintes de répartition topologique.

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

Consultez la Référence de l’API pour voir toutes les options de modèle de pod prises en charge.

Budgets de perturbation des pods

L’opérateur crée un PodDisruptionBudget (PDB) pour chaque cluster afin que les perturbations volontaires — drainage de nœuds, mises à niveau progressives, évictions de l’autoscaler — ne puissent pas mettre hors service suffisamment de pods au point de perdre le quorum ou de compromettre la disponibilité.

Pour les clusters ClickHouse comportant plusieurs shards, un PDB est créé par shard afin qu’une perturbation sur un shard ne soit pas comptabilisée sur un autre.

Valeurs par défaut

L’opérateur choisit des valeurs par défaut sûres en fonction de la taille du cluster, de sorte qu’un apply initial protège déjà contre une perte accidentelle de quorum.

Resource Topology Default PDB
ClickHouseCluster replicas: 1 (shard à réplique unique) maxUnavailable: 1 — une perturbation est autorisée pour un cluster à nœud unique afin de ne pas bloquer le drain des nœuds
ClickHouseCluster replicas: 2+ (shard à plusieurs répliques) minAvailable: 1 — au moins une réplique par shard doit rester disponible
KeeperCluster replicas: 1 maxUnavailable: 1 — une perturbation est autorisée pour un cluster à nœud unique afin de ne pas bloquer le drain des nœuds
KeeperCluster replicas: 3+ maxUnavailable: replicas/2 — préserve le quorum RAFT pour un cluster 2F+1 (3 répliques tolèrent 1 indisponibilité, 5 répliques tolèrent 2 indisponibilités)

Pour un ClickHouseCluster de 3 shards avec replicas: 3, l’opérateur crée trois PDB, un par shard, chacun avec minAvailable: 1.

Surcharger les valeurs par défaut

Utilisez spec.podDisruptionBudget pour surcharger minAvailable ou maxUnavailable (un seul) :

spec:
  replicas: 3
  shards: 2
  podDisruptionBudget:
    minAvailable: 2   # keep at least 2 of 3 replicas in every shard up during a disruption

Ou encore la forme maxUnavailable, avec un pourcentage :

spec:
  replicas: 5
  podDisruptionBudget:
    maxUnavailable: 40%

Vous pouvez également transmettre le champ unhealthyPodEvictionPolicy au PDB généré — ce qui est utile lorsque vous devez autoriser l’éviction de pods encore en état NotReady :

spec:
  podDisruptionBudget:
    minAvailable: 2
    unhealthyPodEvictionPolicy: AlwaysAllow

Politiques

spec.podDisruptionBudget.policy vous permet de choisir avec quel degré d’intervention l’opérateur gère les PDB :

Policy Behavior
Enabled (par défaut) L’opérateur crée et met à jour le PDB à chaque réconciliation. Il s’agit du choix sûr par défaut pour la production.
Disabled L’opérateur ne crée pas de PDB et supprime ceux qui existent déjà avec des labels correspondants. Utile pour les clusters de développement où toute perturbation volontaire doit être autorisée.
Ignored L’opérateur ne crée ni ne supprime de PDB. Les PDB existants sont laissés en l’état. Utilisez cette option lorsqu’un autre système (par ex. un contrôle d’admission, un outil GitOps) prend en charge la gestion des PDB à votre place.

Exemple — désactiver complètement la gestion des PDB sur un cluster de développement :

spec:
  podDisruptionBudget:
    policy: Disabled

Exemple — conservez votre PDB défini manuellement à côté du cluster et empêchez l’opérateur d’y toucher :

spec:
  podDisruptionBudget:
    policy: Ignored

Désactivation à l’échelle du cluster

La gestion des PDB peut également être désactivée à l’échelle du cluster via la variable d’environnement ENABLE_PDB de l’opérateur. Avec ENABLE_PDB=false, l’opérateur ignore l’étape de réconciliation des PDB pour chaque ClickHouseCluster et KeeperCluster, quelle que soit la valeur de leur spec.podDisruptionBudget.policy, et ne surveille pas du tout les ressources PodDisruptionBudget. Le ServiceAccount de l’opérateur n’a donc pas besoin d’autorisations RBAC sur poddisruptionbudgets.policy/v1, ce qui est utile lorsque l’opérateur s’exécute avec un ServiceAccount restreint qui exclut volontairement ces autorisations.

# in the operator Deployment spec
env:
- name: ENABLE_PDB
  value: "false"

Ceci est destiné aux environnements qui définissent leurs propres politiques de perturbation (par exemple via Gatekeeper / Kyverno) et qui ne veulent pas que l’opérateur intervienne du tout.

Configuration du conteneur

Image personnalisée

Utilisez une image ClickHouse spécifique :

spec:
  containerTemplate:
    image:
      repository: clickhouse/clickhouse-server
      tag: "25.12"
    imagePullPolicy: IfNotPresent

Ressources des conteneurs

Configurez le CPU et la mémoire des conteneurs ClickHouse :

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

Variables d’environnement

Ajoutez des variables d’environnement personnalisées :

spec:
  containerTemplate:
    env:
    - name: CUSTOM_ENV_VAR
      value: "1"

Points de montage de volumes

Ajoutez des points de montage de volumes supplémentaires :

spec:
  containerTemplate:
    volumeMounts:
    - name: custom-config
      mountPath: /etc/clickhouse-server/config.d/custom.xml
      subPath: custom.xml

Voir la Référence de l’API pour toutes les options prises en charge des modèles de conteneur.

Configuration du TLS/SSL

Configurer des endpoints sécurisés

Fournissez une référence à un Secret Kubernetes contenant des certificats TLS pour activer des endpoints sécurisés

spec:
  settings:
    tls:
      enabled: true
      required: true # Insecure ports are disabled if set
      serverCertSecret:
        name: <certificate-secret-name>

Format du Secret pour le certificat SSL

Le Secret doit contenir la paire de clés du serveur :

  • tls.crt - certificat serveur encodé en PEM
  • tls.key - clé privée encodée en PEM

Communication de ClickHouse Keeper via TLS

Si TLS est activé pour KeeperCluster, ClickHouseCluster utilisera automatiquement une connexion sécurisée vers les nœuds Keeper.

ClickHouseCluster vérifie les certificats des nœuds Keeper à l’aide du trust store du système, ainsi que de tout caBundle que vous configurez.

Pour faire confiance à une CA privée (par exemple, une CA auto-signée ou interne), fournissez une référence vers un CA bundle personnalisé :

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

External Secret

Par défaut, l’opérateur crée et gère un Secret contenant les identifiants internes du cluster (mot de passe interserver, mot de passe d’administration, identité Keeper, secret du cluster, clé named-collections). Le Secret porte le nom du cluster et se trouve dans l’espace de noms du cluster.

Si vous souhaitez gérer ces identifiants vous-même — par exemple en les récupérant depuis HashiCorp Vault, AWS Secrets Manager ou External Secrets Operator — configurez l’opérateur pour qu’il utilise un Secret préexistant via 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

Clés requises

Le Secret doit contenir les clés suivantes :

Clé Format Quand requis
interserver-password mot de passe en clair Toujours
management-password mot de passe en clair Toujours
keeper-identity clickhouse:<password> Toujours
cluster-secret mot de passe en clair Toujours
named-collections-key clé AES de 16 octets encodée en hexadécimal (32 caractères hexadécimaux) ClickHouse >= 25.12 uniquement
disk-encryption-key clé AES de 16 octets encodée en hexadécimal (32 caractères hexadécimaux) Uniquement lorsque settings.encryption est défini

Voici à quoi ressemble un Secret complet :

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

Politique : Observe ou Manage

spec.externalSecret.policy contrôle la façon dont l’opérateur gère les clés requises manquantes :

Politique Comportement en cas de clés manquantes
Observe (par défaut) La réconciliation est bloquée jusqu’à ce que chaque clé requise soit présente. L’opérateur signale chaque clé manquante — ainsi que l’indication de format correspondante — via la condition ExternalSecretValid (avec la raison ExternalSecretInvalid) et un événement Warning.
Manage L’opérateur génère toute clé requise manquante et la réécrit dans le même secret. Utile pour l’initialisation : créez un secret vide, laissez l’opérateur le remplir, puis restreignez éventuellement l’accès. L’opérateur ne supprime toutefois jamais le secret.

Choisissez Observe lorsqu’un système externe (Vault, ESO, sealed-secrets, GitOps) fait office de source de vérité et que vous voulez que l’opérateur échoue clairement en cas de mauvaise configuration. Choisissez Manage si vous voulez une initialisation autonome tout en conservant la maîtrise de l’objet secret lui-même (par exemple, pour le sauvegarder).

Condition d’état et dépannage

L’opérateur expose la condition ExternalSecretValid dans ClickHouseCluster.status.conditions. Consultez-la lorsque la réconciliation semble bloquée :

# 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

Raisons possibles :

reason Signification Correctif
ExternalSecretNotFound Le Secret référencé n'existe pas dans l'espace de noms. Créez le Secret ou corrigez spec.externalSecret.name.
ExternalSecretInvalid Le Secret existe, mais il ne contient pas toutes les clés requises (uniquement avec Observe). Le message liste chaque clé manquante avec le format attendu. Ajoutez les clés manquantes ou passez à policy: Manage.
ExternalSecretValid Toutes les clés requises sont présentes et l'opérateur utilise le Secret.

L'opérateur remet la réconciliation en file d'attente tant que le Secret est invalide. Ainsi, dès que vous ajoutez les clés manquantes, la réconciliation suivante les prend automatiquement en compte : inutile de redémarrer les pods.

Ports supplémentaires

L’opérateur expose un ensemble fixe de ports sur chaque pod ClickHouse et sur son Service headless public : 8123 HTTP, 9000 natif, 9009 inter-serveur, 9001/9002 gestion, 9363 métriques Prometheus, ainsi que les variantes TLS 8443/9440 lorsque TLS est activé. Les ports interserveur et de gestion sont également exposés via les Services internes de chaque réplique afin que les répliques et l’opérateur puissent communiquer avant qu’une réplique soit prête. Pour que ClickHouse écoute sur des protocoles supplémentaires — MySQL, PostgreSQL, gRPC ou tout autre port personnalisé — déclarez-les dans spec.additionalPorts :

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

L’opérateur ajoute ces ports aux containerPorts du pod ainsi qu’au Service headless public. L’exemple complet se trouve dans examples/custom_protocols.yaml.

Exemple complet : protocole MySQL wire

Pour exposer ClickHouse via le protocole MySQL wire sur le port 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"

Une fois appliqué, vérifiez depuis l’intérieur du cluster :

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

Contraintes sur les champs

Champ Règle
name Doit correspondre au motif DNS_LABEL ^[a-z]([-a-z0-9]*[a-z0-9])?$, avec un maximum de 63 caractères. L'unicité est imposée par la CRD en tant que clé de list-map.
port Entier compris dans [1, 65535]. Le webhook rejette les numéros de port dupliqués dans la liste.

Ports et noms réservés

Le webhook de validation rejette les entrées additionalPorts qui entreraient en conflit avec des ports que l’opérateur utilise lui-même. Tous les ports liés à TLS sont réservés systématiquement afin que l’activation ultérieure de spec.settings.tls.enabled ne puisse pas invalider un cluster auparavant valide.

Port Réservé pour
8123 HTTP
8443 HTTPS
9000 native TCP
9440 TLS natif
9009 interserver
9001 gestion
9363 métriques Prometheus

Les noms suivants sont également rejetés — il s’agit des identifiants internes de type de protocole de l’opérateur (et non des alias lisibles par l’humain) :

Nom
http
http-secure
tcp
tcp-secure
interserver
management
prometheus

Une requête rejetée produit une erreur du type :

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

Sonde de version et canal de mise à niveau

L’opérateur gère deux aspects indépendants des versions du cluster :

  1. Signalement de version — pour ClickHouseCluster, un Job Kubernetes exécute une fois l’image de conteneur afin de détecter la version de ClickHouse en cours d’exécution ; pour KeeperCluster, l’opérateur lit la version signalée par le serveur à partir des répliques en cours d’exécution. La version détectée est enregistrée dans .status.version et utilisée par d’autres étapes de réconciliation (par exemple, la clé named-collections External Secret n’est requise qu’à partir de ClickHouse 25.12).
  2. Canal de mise à niveau — une vérification périodique du flux public des versions de ClickHouse (https://clickhouse.com/data/version_date.tsv). L’opérateur indique si une version plus récente est disponible via la condition d’état VersionUpgraded. Il ne met jamais lui-même le cluster à niveau — l’utilisateur garde le contrôle du tag de l’image.

Choisir un canal de publication

spec.upgradeChannel sélectionne l’ensemble des versions amont avec lesquelles l’opérateur effectue la comparaison. Le même champ existe sur ClickHouseCluster et KeeperCluster.

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

Valeurs autorisées (validées par la CRD avec le pattern ^(lts|stable|\d+\.\d+)?$) :

Value Behavior
vide (par défaut) L’opérateur propose uniquement des mises à jour mineures au sein de la ligne major.minor actuellement utilisée. Un cluster en 25.8.3.1 se verra proposer 25.8.4.x, mais pas 25.9.x.
stable Suit le canal stable du projet source — la dernière release que ClickHouse Inc. signale comme stable sur la ligne de release principale. Reçoit les mises à niveau majeures plus tôt que le canal lts.
lts Suit le canal lts du projet source — les releases avec support à long terme. Reçoit les mises à niveau majeures moins souvent, avec des fenêtres de support plus longues.
25.8 (ou tout <major>.<minor>) Fixe le canal sur une ligne major.minor précise. Les mises à niveau majeures au-delà de celle-ci ne sont pas proposées, même si une version plus récente existe dans le projet source.

En production, il est généralement préférable de fixer le canal sur un <major>.<minor> explicite (par ex. 25.8). Cela verrouille le cluster sur la ligne de release majeure prévue et permet à l’opérateur de signaler un avertissement WrongReleaseChannel si une réplique dérive d’une manière ou d’une autre vers une autre version majeure — ce qui est particulièrement important lorsque l’image est référencée par un digest (@sha256:...) plutôt que par un tag lisible par l’humain. La valeur vide par défaut convient aux clusters de développement pour lesquels les sauts de version majeure ne posent pas de problème.

Conditions d’état

Deux conditions reflètent le résultat de la sonde et de la vérification de mise à niveau :

Condition Raison Signification
VersionInSync VersionMatch Toutes les répliques signalent la même version
VersionInSync VersionMismatch Les répliques exécutent des versions différentes. Cette raison est masquée lors d’une mise à niveau progressive planifiée. Elle apparaît généralement lorsqu’un tag d’image mutable a été épinglé (par exemple latest ou une version majeure seule comme 26.3) et que le registre sous-jacent a changé entre deux pulls, de sorte que différentes répliques se retrouvent sur des patchs différents pour un même tag.
VersionInSync VersionPending Le Job de sonde de version n’est pas encore terminé, ou aucune version de réplique Keeper n’a encore été observée
VersionInSync VersionProbeFailed Le Job de sonde ClickHouse a échoué ; l’opérateur ne peut pas déterminer la version en cours d’exécution
VersionUpgraded UpToDate Le cluster exécute la dernière version disponible dans le canal sélectionné
VersionUpgraded MinorUpdateAvailable Un patch plus récent est disponible dans la même branche major.minor
VersionUpgraded MajorUpdateAvailable Une version major.minor plus récente est disponible dans le canal choisi
VersionUpgraded VersionOutdated La version en cours d’exécution est obsolète et ne recevra plus de correctifs du canal sélectionné — généralement parce que la branche majeure a été retirée de lts ou stable en amont
VersionUpgraded WrongReleaseChannel L’image en cours d’exécution n’appartient pas à l’upgradeChannel sélectionné. Exemple : un cluster exécutant 26.5 avec upgradeChannel: lts, car 26.5 ne fait pas partie de la branche lts amont.
VersionUpgraded UpgradeCheckFailed L’opérateur n’a pas pu joindre le flux des versions en amont

Inspectez-les avec :

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

Redéfinition du Job de sonde de version

Cela s’applique uniquement à ClickHouseCluster. KeeperCluster n’exécute plus de Job de sonde de version — sa version est lue directement à partir des répliques Keeper actives —, donc spec.versionProbeTemplate est déprécié et n’y a aucun effet.

La sonde est implémentée sous la forme d’un Job Kubernetes standard. Si votre cluster applique des politiques d’admission qui exigent des Tolerations spécifiques, des sélecteurs de nœuds, des contextes de sécurité, ou si vous souhaitez limiter la durée de présence des Jobs de sonde terminés, redéfinissez le template via 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

Le nom du conteneur version-probe est le nom par défaut de l’opérateur — l’entrée sous containers: porte le même nom, donc l’opérateur applique une fusion profonde des champs fournis par l’utilisateur par-dessus les valeurs par défaut.

Contrôles globaux de l’opérateur

Deux options du manager de l’opérateur contrôlent globalement la boucle de vérification des mises à niveau :

Option Par défaut Effet
--version-update-interval 24h Fréquence à laquelle l’opérateur récupère à nouveau la liste des versions amont
--disable-version-update-checks false Désactive entièrement la vérification des mises à niveau. La condition VersionUpgraded n’est pas définie et aucun trafic HTTP sortant vers clickhouse.com n’est généré

Définissez --disable-version-update-checks=true dans les environnements isolés du réseau ou lorsque le trafic sortant vers clickhouse.com n’est pas autorisé.

Paramètres de ClickHouse

Mot de passe de l’utilisateur default

spec.settings.defaultUserPassword définit le mot de passe du compte intégré default. Fournissez la valeur à partir d’une clé d’un Secret (recommandé) ou d’une ConfigMap que vous créez, plutôt que de l’indiquer directement dans la 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

Indiquez exactement l’un de secret ou configMap, chacun avec name (l’objet) et key (l’entrée qui contient le mot de passe).

Types de mot de passe

passwordType indique à ClickHouse comment interpréter la valeur. Par défaut, il est défini sur password (texte en clair) ; les alternatives sont des formes hachées comme password_sha256_hex et password_double_sha1_hex. Préférez un type haché afin que le texte en clair ne soit jamais stocké. Consultez les paramètres utilisateur de ClickHouse pour la liste complète.

Exemple complet avec un Secret

Créez le Secret, puis référencez sa clé :

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

Pour un mot de passe haché, stockez le hachage au lieu du texte en clair :

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

Utiliser un ConfigMap

Un ConfigMap fonctionne de la même manière, mais son contenu n'est pas protégé comme celui d'un Secret. Utilisez-le uniquement pour des valeurs non sensibles ou déjà hachées, telles qu'une empreinte password_sha256_hex :

spec:
  settings:
    defaultUserPassword:
      passwordType: password_sha256_hex
      configMap:
        name: clickhouse-config
        key: default_password

Utilisateurs personnalisés dans la configuration

Configurez des utilisateurs supplémentaires dans les fichiers de configuration.

Créez une ConfigMap et un Secret pour l'utilisateur :

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")

Ajoutez une configuration personnalisée à 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

Synchronisation de la base de données

Activez la synchronisation automatique de la base de données pour les nouvelles répliques :

spec:
  settings:
    enableDatabaseSync: true  # Default: true

Lorsqu’il est activé, l’opérateur synchronise les tables Replicated ainsi que les tables d’intégration sur les nouvelles répliques.

Chaque pod de réplique comporte la barrière de disponibilité clickhouse.com/ReplicaInitialized. Une nouvelle réplique n’est donc publiée via le Service headless public qu’une fois son initialisation terminée par l’opérateur : la base de données default est convertie au moteur Replicated et le schéma est synchronisé. Jusque-là, l’opérateur et les autres répliques y accèdent via son Service interne. Avec enableDatabaseSync: false, l’opérateur marque immédiatement les répliques comme initialisées, de sorte que leur disponibilité ne dépend que des sondes de conteneur.

L’opérateur ne supprime jamais une base de données default non-Replicated contenant des données. Une telle réplique commence tout de même à servir le trafic client après la préparation du schéma, mais le cluster signale SchemaInSync=False avec la raison DefaultDatabaseNotReplicated jusqu’à ce que vous résolviez vous-même ce problème de base de données.

Avant qu’une réplique soit supprimée lors d’une réduction d’échelle, l’opérateur retire d’abord le trafic client de celle-ci, attend qu’elle cesse d’être publiée, réplique ses données restantes vers les répliques survivantes, puis la supprime.

Journalisation du serveur

Configurez le journal du serveur ClickHouse via spec.settings.logger. Chaque champ est facultatif et possède une valeur par défaut sûre ; ainsi, même si vous n’y touchez jamais, un cluster journalise déjà au niveau trace, à la fois dans la console du conteneur et dans un fichier avec rotation sur disque.

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
Champ Par défaut Description
logToFile true Lorsque la valeur est false, l’opérateur supprime les destinations de fichier et le server n’écrit les logs que dans la console du conteneur.
jsonLogs false Lorsque la valeur est true, l’opérateur ajoute formatting.type: json pour que chaque ligne soit un objet JSON.
level trace Niveau de verbosité des logs. Valeurs possibles : test, trace, debug, information, notice, warning, error, critical, fatal.
size 1000M Taille maximale d’un fichier de log avant rotation.
count 50 Nombre de fichiers de log après rotation que le server conserve.

L’opérateur conserve toujours la journalisation vers la console afin que kubectl logs fonctionne, et ajoute par-dessus une journalisation dans des fichiers lorsque logToFile vaut true. Un cluster avec les valeurs par défaut génère ce bloc 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

Le même bloc spec.settings.logger s’applique à un KeeperCluster ; l’opérateur écrit alors ses fichiers dans /var/log/clickhouse-keeper/.

Configuration personnalisée

Configuration supplémentaire intégrée

Au lieu de monter des fichiers de configuration personnalisés, vous pouvez définir directement des options de configuration supplémentaires pour ClickHouse.

Ajoutez une configuration ClickHouse personnalisée avec extraConfig :

spec:
  settings:
    extraConfig:
      background_pool_size: 20

Configuration intégrée d’utilisateurs supplémentaires

Vous pouvez également spécifier une configuration supplémentaire d’utilisateurs ClickHouse à l’aide de extraUsersConfig. Cela permet de définir directement des utilisateurs, des profils, des quotas et des privilèges dans la spécification du cluster.

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

Consultez la documentation pour connaître toutes les options de configuration prises en charge pour les utilisateurs ClickHouse.

Exemple de configuration

Exemple complet de configuration :

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:
  # secret-password
  password: "..." # sha256 hex of the password
---
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