Configuración de ClickHouseCluster
Configuración básica
Réplicas y segmentos
- Réplicas: Número de instancias de ClickHouse por segmento (para alta disponibilidad)
- Segmentos: Número de particiones horizontales (para el escalado)
replicas: 3 y shards: 2 creará 6 pods de ClickHouse en total.
Integración de Keeper
Cada cluster de ClickHouse necesita un ensemble de Keeper para la coordinación. Establezca exactamente uno dekeeperClusterRef o externalKeeper; se rechaza cualquier cluster que establezca ambos o ninguno.
Haga que keeperClusterRef apunte a un KeeperCluster administrado por este operador:
keeperClusterRef.namespace, el operador debe observar ambos espacios de nombres. Si WATCH_NAMESPACE está configurado, incluya los espacios de nombres de ClickHouse y Keeper en esa lista.
Keeper gestionado externamente
UseexternalKeeper para ejecutar ClickHouse con un ensemble de Keeper que el operador no gestiona,
ya sea uno que pertenezca a otro operador, que se ejecute en otro cluster de Kubernetes, en máquinas virtuales o
en bare metal, o que se comparta entre varios sistemas:
port es 9181. host es un nombre DNS o una dirección IP; las direcciones IPv6 deben ir entre corchetes. Establezca tls: Enabled para conectarse mediante TLS y asigne a port el puerto en el que el ensemble escucha
las conexiones seguras:
caBundle
que configure. Consulte Comunicación entre ClickHouse y Keeper mediante TLS.
Cuando varios clusters de ClickHouse compartan un mismo ensemble, asigne a cada uno su propio znode raíz mediante
settings.extraConfig para que su metadata de replicación, sus usuarios definidos en SQL y sus colecciones con nombre
no entren en conflicto. Cree el znode antes de iniciar ClickHouse y no lo modifique posteriormente:
zookeeper.root en settings.extraReloadableConfig: una recarga cambiaría la raíz de un
cluster en ejecución y dejaría sus tablas replicadas en modo de solo lectura. Si el znode raíz tiene ACL, estas deben permitir
que la keeper-identity del cluster cree znodes hijos.
El operador no modifica estos servidores ni espera a que estén disponibles antes de reconciliar ClickHouse.
Mantener el ensemble disponible es responsabilidad del usuario.
La autenticación funciona igual que con un Keeper gestionado por el operador: el operador lee la
clave keeper-identity del secreto del cluster y se la pasa a ClickHouse. Consulte
Secreto externo para conocer la estructura del secreto.
Configuración de KeeperCluster
Traspaso del liderazgo al finalizar
El contenedor de Keeper incluye un hookpreStop predeterminado que solicita a la réplica que ceda el liderazgo de Raft
antes de detenerse y espera a que el traspaso se complete antes de permitir que el
contenedor finalice. Este hook se ejecuta en cada detención ordenada del contenedor, no solo en
los rollouts iniciados por el operador: un desalojo del descheduler, un drenaje de nodos o una acción del autoscaler
activan el mismo hook, ya que se trata de un handler preStop a nivel del agente kubelet y no
de lógica del bucle de reconciliación.
Sin este mecanismo, reiniciar el líder actual deja al ensemble sin líder hasta que
concluye una nueva elección, lo que puede tardar varios segundos bajo carga y se manifiesta en
ClickHouse como pérdida de conexión con Keeper y un aumento de la latencia de las consultas. El hook solicita a la
réplica que ceda el liderazgo (mediante el comando de cuatro letras ydld de Keeper, enviado a través del
puerto http_control) y luego sondea el estado de la réplica hasta que deja de ser el
líder, en lugar de enviar la solicitud y dejar que el contenedor se detenga de inmediato. Una
solicitud de tipo fire-and-forget todavía puede perder la carrera frente a SIGTERM bajo carga de escritura, por lo que
es precisamente la espera lo que mantiene acotado el intervalo sin líder.
El hook no requiere configuración y se degrada de forma controlada: en versiones de Keeper anteriores a
26.3, que aún no admiten los comandos de liderazgo utilizados aquí, la solicitud no tiene efecto y
el contenedor se detiene igual que lo haría sin el hook. Como ejecuta un script de shell, requiere
bash en la imagen; si utiliza una imagen de Keeper distroless o scratch, sobrescríbalo o elimínelo
mediante containerTemplate.lifecycle. Para más información, consulte la
Referencia de la API.
Configuración de almacenamiento
dataVolumeClaimSpec, un
PersistentVolumeClaimSpec estándar de Kubernetes. El operador lo convierte en un PersistentVolumeClaim por
réplica montado en la ruta de datos /var/lib/clickhouse:
El operador solo puede modificar un PVC existente si la clase de almacenamiento asociada admite la expansión de volúmenes.
Dominio del clúster
spec.clusterDomain establece el sufijo DNS de Kubernetes que usa el operador al generar
los nombres de host completos de los pods de Kubernetes que escribe en la
configuración de servidor ClickHouse. Su valor predeterminado es cluster.local y está disponible tanto en
ClickHouseCluster como en KeeperCluster.
<cluster-name>-clickhouse-headless que atiende el tráfico de los clientes.
También crea servicios por réplica <cluster-name>-clickhouse-internal-<shard>-<index> que exponen Pods no listos para el tráfico interno
y las solicitudes de administración del operador. Esto puede utilizarse para la recuperación de una réplica si no logra estar lista por sí misma.
Los nodos de Keeper usan nombres de pods de Kubernetes a través de su Service headless: <pod>.<headless-service>.<namespace>.svc.<clusterDomain>.
Sobrescriba esto solo cuando el
agente kubelet de su clúster se ejecute con un --cluster-domain
distinto de cluster.local. Si el valor no coincide con el dominio real del clúster,
ClickHouse no podrá resolver los nombres del host de Keeper ni de las réplicas, y la coordinación y
las consultas Distributed fallarán con errores de resolución de DNS. Establezca el mismo valor en el
ClickHouseCluster y en el KeeperCluster al que hace referencia.Configuración del pod de Kubernetes
Distribución topológica y afinidad automáticas
Distribuya los pods entre las zonas de disponibilidad:Asegúrese de que su clúster de Kubernetes tenga suficientes nodos en distintas zonas para cumplir las restricciones de distribución.
topologyMinDomains en el número de zonas de disponibilidad para forzar la distribución:
topologyMinDomains requiere topologyZoneKey. Los pods permanecen en Pending mientras haya menos zonas
disponibles de las solicitadas, así que manténgalo dentro de las zonas que su clúster pueda proporcionar.Configuración manual
Consulta la Referencia de la API para ver todas las opciones compatibles de la plantilla de pod de Kubernetes.
Presupuestos de interrupción de pods
Valores predeterminados
apply inicial ya proteja frente a una pérdida accidental de quorum.
Para un ClickHouseCluster de 3 segmentos con
replicas: 3, el operador crea tres PDB, uno por segmento, cada uno con minAvailable: 1.
Sobrescribir los valores predeterminados
spec.podDisruptionBudget para sobrescribir minAvailable o maxUnavailable (exactamente uno):
maxUnavailable, con un porcentaje:
unhealthyPodEvictionPolicy al PDB generado, lo que resulta útil cuando necesitas permitir la expulsión de pods que aún siguen en NotReady:
Políticas
spec.podDisruptionBudget.policy te permite elegir con qué nivel de agresividad el operador gestiona los PDB:
Ejemplo — deshabilita por completo la gestión de PDB en un clúster de desarrollo:
Desactivación a nivel de clúster
ENABLE_PDB del operador. Con ENABLE_PDB=false, el operador omite el paso de reconciliación de PDB para todos los ClickHouseCluster y KeeperCluster, independientemente de su spec.podDisruptionBudget.policy, y no observa en absoluto los recursos PodDisruptionBudget. Por lo tanto, el ServiceAccount del operador no necesita permisos de RBAC sobre poddisruptionbudgets.policy/v1, lo cual resulta útil cuando el operador se ejecuta con un ServiceAccount restringido que omite intencionadamente esos permisos.
Configuración del contenedor
Imagen personalizada
Recursos de los contenedores
Variables de entorno
Montajes de volúmenes
Se permite especificar varios montajes de volúmenes en el mismo
mountPath.
El operador creará un volumen proyectado con todos los montajes especificados.Sondas de health
El operador configura sondas de liveness y de preparación en cada contenedor de ClickHouse y Keeper. De forma predeterminada, no se configura ninguna sonda de inicio.
ClickHouse y Keeper usan la misma configuración de tiempos predeterminada:
ClickHouse abre el listener entre servidores antes de cargar las tablas, y los listeners de Client, después. Por eso, la sonda de liveness tolera una carga lenta de tablas, mientras que, si la sonda de preparación se supera, la réplica ya está atendiendo consultas.
Puede sobrescribir cualquier sonda mediante
spec.containerTemplate en cualquiera de los dos recursos. Por ejemplo, para personalizar la sonda de liveness de ClickHouse:
Sonda de inicio
UsestartupProbe cuando un contenedor necesite más tiempo para iniciarse del que permite la sonda de liveness: con los valores predeterminados, unos 60 segundos de retraso inicial más 10 comprobaciones fallidas a intervalos de 5 segundos.
Kubernetes no ejecuta las sondas de liveness y de preparación hasta que la sonda de inicio se completa correctamente, de modo que un inicio lento no provoca un bucle de reinicios.
Por ejemplo, para dar a una réplica de Keeper que debe reproducir una instantánea de gran tamaño hasta 10 minutos para empezar a aceptar conexiones:
Consulta la referencia de la API para ver todas las opciones compatibles de la plantilla de contenedor.
Configuración de TLS/SSL
Configurar endpoints seguros
Formato del Secret del certificado SSL
tls.crt- certificado del server codificado en PEMtls.key- private key codificada en PEM
Este formato es compatible con los certificados generados por cert-manager.
Comunicación de ClickHouse-Keeper mediante TLS
Si el KeeperCluster referenciado porkeeperClusterRef tiene TLS habilitado, ClickHouseCluster usará automáticamente una conexión segura a los nodos de Keeper.
Con externalKeeper, establezca en su lugar tls: Enabled y configure el port de cada nodo con el puerto de cliente seguro del ensemble de Keeper (por ejemplo, 9281).
ClickHouseCluster verifica los certificados de los nodos de Keeper con el almacén de confianza del sistema, además de cualquier caBundle que configure.
Para confiar en una CA privada (por ejemplo, una CA autofirmada o interna), proporcione una referencia a un bundle de CA personalizado:
Secret externo
spec.externalSecret:
El Secret referenciado debe estar en el mismo espacio de nombres que el ClickHouseCluster. El operador nunca elimina un Secret que no haya creado.
Claves requeridas
Un Secret completo tiene este aspecto:
Política: Observe vs Manage
spec.externalSecret.policy controla cómo el operador maneja las claves requeridas que faltan:
Incluso con
policy: Manage, el Secret ya debe existir en el espacio de nombres: el operador nunca crea el Secret por sí mismo; solo escribe las claves generadas en uno ya existente. Si el Secret referenciado no existe, la reconciliación se bloquea con el motivo ExternalSecretNotFound, independientemente de la política.Observe cuando un sistema externo (Vault, ESO, sealed-secrets, GitOps) sea la fuente de referencia y quieras que el operador falle claramente ante una configuración incorrecta. Elige Manage cuando quieras un aprovisionamiento inicial autosuficiente, pero también conservar la propiedad del propio objeto Secret (por ejemplo, para hacer una copia de seguridad).
Condición de estado y solución de problemas
ExternalSecretValid en ClickHouseCluster.status.conditions. Revísala cuando parezca que la reconciliación está atascada:
El operador vuelve a encolar la reconciliación mientras el Secret no sea válido, así que, en cuanto agregues las claves faltantes, la siguiente reconciliación las detectará automáticamente; no hace falta reiniciar los pods.
El conjunto de claves requeridas depende de la versión de ClickHouse en ejecución.
named-collections-key solo se valida una vez que la sonda de versión del operador ha detectado ClickHouse 25.12 o una versión posterior. En versiones anteriores, la clave puede no estar presente en el Secret. disk-encryption-key solo es obligatoria cuando se establece spec.settings.encryption.Puertos adicionales
8123 para HTTP, 9000 nativo, 9009 entre servidores, 9001/9002 de administración, 9363 para métricas de Prometheus, y las variantes TLS 8443/9440 cuando TLS está habilitado. Los puertos interserver y de administración también se exponen a través de los Services internos por réplica para que las réplicas y el operador puedan comunicarse antes de que una réplica esté lista. Para que ClickHouse escuche en protocolos adicionales —MySQL, PostgreSQL, gRPC o cualquier puerto personalizado—, declárelos en spec.additionalPorts:
containerPorts del pod de Kubernetes y al Service headless público.
El ejemplo completo se encuentra en examples/custom_protocols.yaml.
Ejemplo completo: MySQL wire protocol
9004:
Restricciones de los campos
Puertos y nombres reservados
additionalPorts que entrarían en conflicto con los puertos en los que el propio operador escucha. Todos los puertos relacionados con TLS están reservados incondicionalmente para que habilitar spec.settings.tls.enabled más adelante no invalide un clúster que antes era válido.
Los siguientes nombres también se rechazan: son los identificadores internos del operador para tipos de protocolo (no los alias legibles para humanos):
Una solicitud rechazada produce un error como:
Sonda de versión y canal de actualización
- Informe de versión — para
ClickHouseCluster, unJobde Kubernetes ejecuta la imagen de contenedor una vez para detectar la versión de ClickHouse en ejecución; paraKeeperCluster, el operador lee la versión informada por el servidor desde las réplicas en ejecución. La versión detectada se registra en.status.versiony se utiliza en otros pasos de reconciliación (por ejemplo, la clave de named collections deExternal Secretsolo es necesaria a partir de ClickHouse25.12). - Canal de actualización — una comprobación periódica del feed público de versiones de ClickHouse (
https://clickhouse.com/data/version_date.tsv). El operador informa si hay una versión más reciente disponible mediante la condición de estadoVersionUpgraded. Nunca actualiza el clúster por sí solo; el usuario controla la etiqueta de la imagen.
Elegir un canal de lanzamientos
spec.upgradeChannel selecciona con qué conjunto de lanzamientos upstream compara el operador. El mismo campo existe tanto en ClickHouseCluster como en KeeperCluster.
^(lts|stable|\d+\.\d+)?$):
Para production, en general se prefiere fijar el canal a un
<major>.<minor> explícito (por ejemplo, 25.8). Esto fija el cluster en la línea de release mayor prevista y permite que el operador mustre una advertencia WrongReleaseChannel si alguna réplica se desvía de algún modo a una major distinta, algo especialmente importante cuando la image se referencia mediante un digest (@sha256:...) en lugar de un tag legible para humanos. El valor predeterminado vacío es adecuado para clusters de Development en los que los saltos entre versiones major no son una preocupación.
Condiciones de estado
Inspecciónalas con:
Sobrescritura del Job de la sonda de versión
ClickHouseCluster. KeeperCluster ya no ejecuta un Job de sonda de versión; su versión se lee directamente de las réplicas de Keeper en ejecución, por lo que spec.versionProbeTemplate está obsoleto y no tiene efecto allí.
La sonda se implementa como un Job estándar de Kubernetes. Si su clúster tiene políticas de admisión que exigen Tolerations específicas, selectores de nodo o contextos de seguridad, o si desea limitar cuánto tiempo permanecen los Jobs de sonda completados, sobrescriba la plantilla mediante spec.versionProbeTemplate:
version-probe es el predeterminado del operador: la entrada en containers: coincide con él por nombre, por lo que el operador aplica una fusión profunda de los campos proporcionados por el usuario sobre los valores predeterminados.
Controles globales del operador
Establece
--disable-version-update-checks=true en entornos aislados de la red o cuando no se permite la salida a clickhouse.com.
Configuración de ClickHouse
Contraseña del usuario default
spec.settings.defaultUserPassword establece la contraseña del usuario default
integrado. Proporcione el valor de una clave de un Secret (recomendado) o de un ConfigMap que
cree, en lugar de incluirlo directamente en el CR:
secret o configMap, y en ambos casos name (el objeto)
y key (la entrada que contiene la contraseña).
Tipos de contraseña
passwordType le indica a ClickHouse cómo interpretar el valor. De forma predeterminada, es
password (texto plano); las alternativas son formas con hash, como
password_sha256_hex y password_double_sha1_hex. Se recomienda usar un tipo con hash para que la
contraseña en texto plano nunca se almacene. Consulte la
configuración de usuarios de ClickHouse
para ver la lista completa.
Ejemplo completo con un Secret
Con
passwordType: password, el clickhouse-client del pod de Kubernetes se configura con
esta contraseña, lo cual resulta práctico para la depuración.Uso de un ConfigMap
password_sha256_hex:
No coloque una contraseña en texto plano en un ConfigMap. Use un Secret para cualquier valor
(
passwordType: password) en texto plano.Usuarios personalizados en la configuración
Configure usuarios adicionales en los archivos de configuración. Cree un ConfigMap y un Secret para el usuario:Sincronización de la base de datos
clickhouse.com/ReplicaInitialized, por lo que una nueva réplica se publica mediante el Service headless público solo después de que el operador complete su inicialización: la base de datos default se convierte al engine Replicated y se sincroniza el esquema. Hasta entonces, el operador y las demás réplicas acceden a ella mediante su Service interno. Con enableDatabaseSync: false, el operador marca las réplicas como inicializadas de inmediato, por lo que la readiness depende únicamente de los probes del contenedor.
El operador nunca elimina una base de datos default no Replicated poblada. Dicha réplica sigue atendiendo tráfico de clientes después de la preparación del esquema, pero el clúster informa SchemaInSync=False con el motivo DefaultDatabaseNotReplicated hasta que resuelva esa base de datos por su cuenta.
Antes de eliminar una réplica durante una reducción de escala, el operador primero retira de ella el tráfico de clientes, espera hasta que deje de publicarse, replica sus datos restantes en las réplicas supervivientes y solo entonces la elimina.
Registro del servidor
Configure el registro del ClickHouse server mediantespec.settings.logger. Todos los campos son opcionales y tienen valores predeterminados seguros, por lo que incluso un cluster que no modifique registrará en information tanto en la consola del contenedor como en un archivo rotado en disco.
El operador siempre mantiene activado el registro en consola para que
kubectl logs funcione, y añade el registro en archivo cuando logToFile es true. Un cluster con los valores predeterminados genera este bloque logger:
spec.settings.logger se aplica a un KeeperCluster; en ese caso, el operador escribe sus archivos en /var/log/clickhouse-keeper/ y establece el logger de Raft (raft_logs_level) en el mismo level.
El registro en consola permanece activado independientemente de
logToFile, por lo que kubectl logs sigue funcionando incluso cuando desactivas el registro en archivos. Establece jsonLogs: true cuando envíes logs a un almacén de logs estructurados que procesa JSON.Tablas de logs del sistema
El operador habilita las tablas del sistemaquery_log, part_log, text_log, metric_log y asynchronous_metric_log. Como comparten volumen con los datos, spec.settings.systemLogsTTLDays limita su tiempo de conservación mediante una TTL de tabla. Si crea un cluster sin especificar ese campo, el webhook que asigna valores predeterminados establece 30. Para desactivar explícitamente la TTL, establezca 0.
El valor predeterminado solo se aplica a los clusters nuevos. Un cluster creado antes de que existiera
systemLogsTTLDays conserva las tablas de logs del sistema sin límite de retención hasta que configure el campo manualmente.@remove — todo mediante extraConfig:
Una tabla deshabilitada no se elimina: los datos existentes permanecen en el disco hasta que usted elimine la tabla.
ClickHouse vuelve a crear las tablas del sistema cuyo TTL ha cambiado y conserva los datos anteriores en tablas con otro nombre, como
system.text_log_0. Elimine esas tablas cuando ya no necesite el historial.Configuración personalizada
Configuración adicional integrada
extraConfig:
Enlaces útiles:
Configuración adicional recargable
Cualquier cambio enextraConfig reinicia los pods de ClickHouse, ya que el operador no puede determinar qué opciones de configuración se aplican en tiempo de ejecución. Para las opciones que ClickHouse recarga sobre la marcha —como named_collections, el caso más habitual—, utilice extraReloadableConfig. El operador aplica los cambios recargando la configuración, sin reiniciar los pods:
extraConfig o en extraReloadableConfig, pero no en ambos; el operador emite una advertencia si la misma sección aparece en los dos.
Al usar
extraReloadableConfig, confirmas que sus opciones de configuración pueden recargarse de forma segura. Si colocas aquí una opción que requiere un reinicio, no surtirá efecto hasta el siguiente reinicio y no se mostrará ningún error.Configuración integrada de usuarios adicionales
extraUsersConfig. Esto es útil para definir usuarios, perfiles, cuotas y privilegios directamente en la especificación del clúster.
La
extraUsersConfig se almacena en el objeto ConfigMap de k8s. Evite incluir secretos en texto plano allí.Consulta la documentación para ver todas las opciones de configuración de usuarios de ClickHouse admitidas.
Ejemplo de configuración
Resincronización periódica
Además de reaccionar a los eventos de Kubernetes, el operador vuelve a reconciliar cada cluster en un intervalo fijo. Esto mantiene actualizadas las condiciones de estado del state que ningún watch puede observar —la health de las réplicas de ClickHouse o el quorum de Keeper— y reintenta acciones de remediación como la limpieza de pods de Kubernetes bloqueados. El intervalo se controla con la environment variableRESYNC_PERIOD del operador (valor predeterminado: 30s), y se aplica a los recursos KeeperCluster, donde 0 deshabilita la resincronización periódica. Los recursos ClickHouseCluster consultan mediante poll la tabla system.warnings de ClickHouse cada 30 segundos, lo que ya vuelve a activar la reconciliación, de modo que RESYNC_PERIOD no tiene actualmente ningún efecto sobre ellos.
MAX_CONCURRENT_RECONCILES (valor predeterminado: 4).
Pausar la reconciliación
Añada la anotaciónclickhouse.com/pause-reconciliation: "true" a un ClickHouseCluster o KeeperCluster para que el operador deje de reconciliarlo. El operador informa ReconcileSucceeded=False con el motivo ReconciliationPaused en el recurso pausado y no realiza ninguna otra acción sobre él. Esto resulta útil cuando necesita intervenir manualmente y el operador podría revertir sus cambios. Mientras la reconciliación esté pausada, el operador informa todas las condiciones de estado (incluidas Ready y Healthy) como Unknown con el motivo ReconciliationPaused, ya que no observa el cluster. Elimine la anotación para reanudar la reconciliación; los cambios pendientes en la especificación se aplicarán en la siguiente reconciliación.