Skip to main content
本指南介绍如何使用该 Operator 配置 ClickHouse 和 Keeper 集群。

ClickHouseCluster 配置

基本配置

副本和分片

  • 副本:每个分片中的 ClickHouse 实例数 (用于高可用)
  • 分片:水平分片的数量 (用于扩缩容)
一个配置为 replicas: 3shards: 2 的集群将总共创建 6 个 ClickHouse pod (容器组) 。

Keeper 集成

每个 ClickHouse 集群都必须引用一个 KeeperCluster,以进行协调:
当设置了 keeperClusterRef.namespace 时,operator 必须同时监听这两个命名空间。如果配置了 WATCH_NAMESPACE,请将 ClickHouse 和 Keeper 所在的命名空间都包含在该列表中。

KeeperCluster 配置

存储配置

使用 dataVolumeClaimSpec (标准 Kubernetes PersistentVolumeClaimSpec) 配置持久化存储。Operator 会将其转换为每个副本对应的 PersistentVolumeClaim, 并将其挂载到数据路径 /var/lib/clickhouse
仅当底层存储类支持卷扩容时,Operator 才能修改现有的 PVC。
关于在多磁盘 (JBOD) 布局中挂载额外磁盘、在没有持久卷的情况下运行、扩展容量、自定义存储策略、静态数据加密,以及创建后哪些内容不能更改的规则,请参阅专门的 存储和卷指南

集群域

spec.clusterDomain 用于设置 operator 在构建并写入 ClickHouse server 配置的 pod (容器组) 完全限定主机名时所使用的 Kubernetes DNS 后缀。默认值为 cluster.local,并且在 ClickHouseClusterKeeperCluster 中都可用。
operator 会通过无头 Service 按如下格式访问每个 pod (容器组) : <pod>.<headless-service>.<namespace>.svc.<clusterDomain>。该后缀会传递到 生成配置的两个部分中:
  • ClickHouseCluster 中,其值会用于 remote_servers 里的副本主机名 (跨副本和 Distributed 查询) 。
  • KeeperCluster 中,其值会用于构建 ClickHouse 用于协调的 Keeper 节点主机名。
仅当你的集群中 kubelet 节点代理使用的 --cluster-domain 不是 cluster.local 时,才应覆盖此值。如果该值与实际的集群域不一致, ClickHouse 将无法解析 Keeper 和副本主机名——协调以及 Distributed 查询都会因 DNS 解析错误而失败。请在 ClickHouseCluster 及其引用的 KeeperCluster 中设置相同的值。

多磁盘 (JBOD) 存储

additionalVolumeClaimTemplates 会为每个 ClickHouse 副本挂载额外磁盘;而要使用这些磁盘,仍必须配置主 dataVolumeClaimSpec。 每一项都是一个 PVC 模板——即一个 metadata.name 加上一个 PVC spec。 这些磁盘的协调方式与主数据磁盘完全相同——都作为 StatefulSet 的 volumeClaimTemplates——因此 StatefulSet 控制器会为每个副本创建并保留一个 PVC,名称为 <name>-<statefulset>-0
operator 会将每个附加卷挂载到 /var/lib/clickhouse/disks/<name>,并将其添加到自动生成的 ClickHouse 存储配置中。 名称中的连字符在 ClickHouse 的磁盘标识符中会转换为下划线;挂载路径则保留原始名称。 主数据磁盘和每个附加磁盘都会被放入 default 存储策略中的同一个卷,因此 ClickHouse 会以轮询方式将新的数据分区片段分布到所有这些磁盘上。 可用容量等于所有磁盘容量之和,且每个未设置自身 storage_policy 的表 (包括 system.* 表) 都会使用这组组合存储。
PVC 名称必须匹配 ^[a-z]([-a-z0-9]*[a-z0-9])?$,并且不得与主数据卷名称冲突。 与主数据磁盘一样,附加磁盘集合在创建时即固定:创建后添加、删除或重命名条目都会被拒绝。 与主数据磁盘一样,删除集群时会保留附加 PVC。 如果存储类支持扩容,则可以扩展现有条目的存储大小。

集群域

spec.clusterDomain 用于设置 operator 在构建并写入 ClickHouse server 配置的 pod (容器组) 完全限定主机名时所使用的 Kubernetes DNS 后缀。默认值为 cluster.local,并且在 ClickHouseClusterKeeperCluster 中都可用。
operator 会通过无头 Service 按如下格式访问每个 pod (容器组) : <pod>.<headless-service>.<namespace>.svc.<clusterDomain>。该后缀会传递到 生成配置的两个部分中:
  • ClickHouseCluster 中,其值会用于 remote_servers 里的副本主机名 (跨副本和 Distributed 查询) 。
  • KeeperCluster 中,其值会用于构建 ClickHouse 用于协调的 Keeper 节点主机名。
仅当你的集群中 kubelet 节点代理使用的 --cluster-domain 不是 cluster.local 时,才应覆盖此值。如果该值与实际的集群域不一致, ClickHouse 将无法解析 Keeper 和副本主机名——协调以及 Distributed 查询都会因 DNS 解析错误而失败。请在 ClickHouseCluster 及其引用的 KeeperCluster 中设置相同的值。

pod (容器组) 配置

自动拓扑分散与亲和性

将 Pod (容器组) 分散到各可用区:
确保您的 Kubernetes 集群在不同可用区中具备足够的节点,以满足分布约束要求。

手动配置

可以指定任意的 pod (容器组) 亲和性/反亲和性规则以及拓扑分布约束条件。

所有受支持的 pod (容器组) 模板选项,请参见 API 参考文档

pod (容器组) 中断预算

Operator 会为每个集群创建一个 PodDisruptionBudget (PDB) ,以确保自愿中断 (如节点排空、滚动升级、自动扩缩容驱逐) 不会导致过多 pod (容器组) 下线,从而失去仲裁或影响可用性。 对于拥有多个分片的 ClickHouse 集群,每个分片都会创建一个 PDB,这样一个分片中的中断就不会计入另一个分片。

默认值

operator 会根据集群规模选择安全的默认值,因此即使首次执行 apply,也能避免意外丢失仲裁。 对于一个包含 3 个分片且 replicas: 3 的 ClickHouseCluster,operator 会创建 3 个 PDB,每个分片 1 个,且每个都设置为 minAvailable: 1

覆盖默认设置

使用 spec.podDisruptionBudget 覆盖 minAvailable maxUnavailable (两者只能指定一个) :
或者使用按百分比设置的 maxUnavailable 形式:
同时设置 minAvailablemaxUnavailable 会被验证 webhook 拒绝。请选择其一——Kubernetes 本身也不允许同时设置这两项。
你也可以将 unhealthyPodEvictionPolicy 字段传递到生成的 PDB 中——当你需要允许仍处于 NotReady 状态的 pod (容器组) 被驱逐时,这会很有用:

策略

spec.podDisruptionBudget.policy 允许你选择 operator 以多大力度管理 PDB: 示例——在开发集群上完全禁用 PDB 管理:
示例 — 将你手动编写的 PDB 与集群放在一起,并阻止 operator 触碰它:

集群范围内停用

也可以通过 operator 的 ENABLE_PDB 环境变量,在整个集群范围内停用 PDB 管理。设置 ENABLE_PDB=false 后,无论 spec.podDisruptionBudget.policy 如何,operator 都会跳过 所有 ClickHouseCluster 和 KeeperCluster 的 PDB reconcile 步骤,并且完全不监视 PodDisruptionBudget 资源。因此,operator 的 ServiceAccount 无需具备 poddisruptionbudgets.policy/v1 的 RBAC 权限;当 operator 以受限的 ServiceAccount 运行,且该账户刻意不包含这些权限时,这一点尤其有用。
这适用于自行实施中断策略 (例如通过 Gatekeeper / Kyverno) 的环境,并希望将 operator 完全排除在外。

容器配置

自定义镜像

使用指定的 ClickHouse 镜像:

容器资源

为 ClickHouse 容器配置 CPU 和内存:

环境变量

添加自定义的环境变量:

卷挂载

添加更多卷挂载:
可以为同一个 mountPath 指定多个卷挂载。 Operator 会将所有已指定的挂载创建为一个投影卷。

有关所有受支持的容器模板选项,请参见 API 参考文档

TLS/SSL 配置

配置安全端点

引用包含 TLS 证书的 Kubernetes Secret,以启用安全端点

SSL 证书 Secret 格式

该 Secret 应包含服务器密钥对:
  • tls.crt - PEM 编码的服务器证书
  • tls.key - PEM 编码的私钥
此格式兼容由 cert-manager 生成的证书。

通过 TLS 进行 ClickHouse-Keeper 通信

如果 KeeperCluster 启用了 TLS,ClickHouseCluster 会自动使用与 Keeper 节点的安全连接。 ClickHouseCluster 会根据系统信任存储以及你配置的任何 caBundle 来验证 Keeper 节点证书。 要信任私有 CA (例如自签名 CA 或内部 CA) ,请提供自定义 CA 证书包引用:

外部 Secret

默认情况下,operator 会创建并管理一个 Secret,其中包含集群的内部凭据 (interserver 密码、管理密码、Keeper 身份、集群 secret、named-collections 密钥) 。该 Secret 以集群名称命名,并位于集群所在的命名空间中。 如果你想自行管理这些凭据——例如从 HashiCorp Vault、AWS Secrets Manager 或 External Secrets Operator 获取——可以使用 spec.externalSecret 将 operator 指向一个预先创建的 Secret:
这里引用的 Secret 必须与 ClickHouseCluster 位于同一命名空间。该 operator 绝不会删除并非由其创建的 Secret。

必需的键

Secret 必须包含以下键: 一个完整的 Secret 如下所示:

策略:Observe 与 Manage

spec.externalSecret.policy 用于控制 Operator 如何处理缺失的必需键:
即使设置了 policy: Manage,该 Secret 也必须已存在于命名空间中——Operator 绝不会自行创建 Secret,它只会将生成的键写入现有的 Secret。 如果引用的 Secret 不存在,则无论采用哪种 policy,协调都会因 ExternalSecretNotFound 而被阻塞。
当外部系统 (Vault、ESO、sealed-secrets、GitOps) 是事实来源,且你希望 Operator 在配置错误时明确报错时,请选择 Observe。当你希望实现自给自足的引导,同时仍保留对 Secret 对象本身的所有权 (例如为了备份) 时,请选择 Manage

状态条件和故障排查

Operator 会在 ClickHouseCluster.status.conditions 中暴露 ExternalSecretValid 条件。协调过程看起来卡住时,请检查它:
可能的原因: 当 Secret 无效时,operator 会将协调重新入队,因此一旦补齐缺失的键,下一次协调就会自动生效——无需重启 Pod (容器组) 。
所需键的集合取决于当前运行的 ClickHouse 版本。只有在 operator 的版本探测检测到 ClickHouse 25.12 或更高版本后,才会校验 named-collections-key。在较旧版本中,Secret 可以不包含该键。仅当设置了 spec.settings.encryption 时,才需要 disk-encryption-key

附加端口

该 Operator 会在每个 ClickHouse pod (容器组) 及其无头 Service 上暴露一组固定端口:8123 HTTP、9000 native、9009 interserver、9001 management、9363 Prometheus 指标,以及启用 TLS 时对应的 8443/9440 TLS 端口变体。若要让 ClickHouse 监听更多协议 (如 MySQL、PostgreSQL、gRPC 或其他自定义端口) ,请在 spec.additionalPorts 中声明:
operator 会将这些端口添加到 Pod 的 containerPorts 和无头 Service 中。完整示例见 examples/custom_protocols.yaml
additionalPorts 只会在 Kubernetes 这一侧开放端口。它不会配置 ClickHouse 服务器 在这些端口上监听。你还需要在 spec.settings.extraConfig.protocols 中启用对应的协议。否则,虽然 Service 上的端口已开放,但 pod (容器组) 内部不会有任何程序响应。

端到端示例:MySQL wire 协议

要通过 MySQL wire 协议在端口 9004 上对外暴露 ClickHouse:
应用完成后,在集群内部验证:

字段约束

保留端口和名称

validating webhook 会拒绝与 operator 自身绑定端口发生冲突的 additionalPorts 条目。所有与 TLS 相关的端口都会被无条件保留,以确保后续切换 spec.settings.tls.enabled 时,不会破坏原本有效的集群。 以下名称也会被拒绝——它们是 operator 的内部协议类型标识符 (而非便于人工阅读的别名) : 被拒绝的请求会产生如下错误:

版本探测与升级通道

operator 会针对 cluster 版本执行两项彼此独立的操作:
  1. 版本报告 — 对于 ClickHouseCluster,一个 Kubernetes Job 会将容器镜像运行一次,以检测当前运行的 ClickHouse 版本;对于 KeeperCluster,operator 会从正在运行的副本中读取由 server 上报的版本。检测到的版本会记录到 .status.version 中,并用于其他协调步骤 (例如,名为 外部 Secret 的 named-collections key 仅在 ClickHouse 25.12 及以上版本中才需要) 。
  2. 升级通道 — 定期检查公开的 ClickHouse 发布源 (https://clickhouse.com/data/version_date.tsv) 。operator 会通过 VersionUpgraded status condition 报告是否有新版本可用。它绝不会自行升级 cluster——镜像标签始终由用户控制。

选择发布渠道

spec.upgradeChannel 用于指定 operator 要对照比较的上游发行版集合。ClickHouseClusterKeeperCluster 都有这个相同的字段。
允许的值 (由 CRD 按模式 ^(lts|stable|\d+\.\d+)?$ 验证) : 对于生产环境,通常更建议将通道固定为明确的 <major>.<minor> (例如 25.8) 。这样可以把集群锁定在预期的 major 发行线上,并且当某个副本因某种原因漂移到其他 major 版本时,Operator 会显示 WrongReleaseChannel 警告——这一点在镜像通过摘要 (@sha256:...) 而不是便于人类阅读的标签引用时尤其重要。对于不担心 major 版本跳变的开发集群,默认的空值也完全适用。

状态条件

两个 conditions 会体现探测和升级检查的结果: 可使用以下方式检查它们:

覆盖版本探测 Job

这仅适用于 ClickHouseClusterKeeperCluster 不再运行版本探测 Job——它的版本会直接从正在运行的 Keeper 副本中读取——因此 spec.versionProbeTemplate 已弃用,在那里不会产生任何效果。 该探测是通过一个常规的 Kubernetes Job 实现的。如果你的集群设置了准入策略,要求指定的 Tolerations、节点选择器或安全上下文,或者你想限制已完成的探测 Job 保留的时间,可以通过 spec.versionProbeTemplate 覆盖该模板:
容器名称 version-probe 是 operator 的默认名称——containers: 下对应的条目会按名称与其匹配,因此 operator 会在默认配置的基础上,将用户提供的字段深度合并进去。

Operator 级别的控制

Operator 管理器上的两个标志可在全局范围内控制升级检查循环: 在隔离网络环境中,或者不允许访问 clickhouse.com 出站流量时,请设置 --disable-version-update-checks=true

ClickHouse 设置

默认用户密码

spec.settings.defaultUserPassword 用于为内置 default 用户设置密码。请提供你创建的 Secret (推荐) 或 ConfigMap 中某个键的值, 而不要直接将密码内联写在 CR 中:
只能提供 secretconfigMap 其中之一,并且两者都必须同时包含 name (对象) 和 key (保存密码的条目) 。

密码类型

passwordType 用于告知 ClickHouse 如何解析该值。其默认值为 password (明文) ;其他可选项为哈希形式,例如 password_sha256_hexpassword_double_sha1_hex。建议优先使用哈希类型,以避免 存储 明文。完整列表请参见 ClickHouse user settings

使用 Secret 的完整示例

先创建 Secret,再引用其中的键:
使用 passwordType: password 时,pod (容器组) 内的 clickhouse-client 会配置 为使用该密码,这样在调试时会更方便。
对于哈希密码,请存储哈希值而非明文:

使用 ConfigMap

ConfigMap 的作用方式与 Secret 相同,但其内容不像 Secret 那样受到保护。 仅应用于非敏感或已哈希的值,例如 password_sha256_hex 摘要:
不要将明文密码放在 ConfigMap 中。任何明文 (passwordType: password) 值都应使用 Secret。

配置中的自定义用户

在配置文件中添加其他用户。 为该用户创建 ConfigMap 和 Secret:
向 ClickHouseCluster 添加自定义配置:

数据库同步

为新副本启用数据库自动同步:
启用后,该 Operator 会将 Replicated 表和集成表同步到新副本。

服务器日志

通过 spec.settings.logger 配置 ClickHouse 服务器日志。每个字段都是可选的,并且都有安全的默认值,因此即使你从未改动过,集群也会默认以 trace 级别同时将日志输出到容器控制台和磁盘上的轮转文件。
operator 始终会保持控制台日志开启,以确保 kubectl logs 可用;当 logToFiletrue 时,还会额外启用文件日志。使用默认值的集群会生成如下 logger 块:
同样的 spec.settings.logger 块也适用于 KeeperCluster;不过,operator 会改为将日志文件写入 /var/log/clickhouse-keeper/
无论 logToFile 如何设置,控制台日志始终保持开启,因此即使禁用文件日志,kubectl logs 仍可正常使用。将日志发送到可解析 JSON 的结构化日志存储时,请设置 jsonLogs: true

自定义配置

内嵌额外配置

无需挂载自定义配置文件,也可以直接指定额外的 ClickHouse 配置选项。 使用 extraConfig 添加自定义的 ClickHouse 配置:

嵌入式附加用户配置

你也可以使用 extraUsersConfig 指定额外的 ClickHouse 用户配置。这对于直接在集群规范中定义用户、profile、配额和授权非常有用。
extraUsersConfig 存储在 k8s 的 ConfigMap 对象中。请避免在其中以明文形式存放 secret。

有关所有受支持的 ClickHouse 用户配置选项,请参阅文档

配置示例

完整配置示例:
最后修改于 2026年7月23日