ClickHouseCluster 配置
基本配置
副本和分片
- 副本:每个分片中的 ClickHouse 实例数 (用于高可用)
- 分片:水平分片的数量 (用于扩缩容)
replicas: 3、shards: 2 的集群将总共创建 6 个 ClickHouse pod (容器组) 。
Keeper 集成
每个 ClickHouse 集群都需要一个 Keeper ensemble 来进行协调。keeperClusterRef 与 externalKeeper 必须且只能设置其中之一;同时设置两者或均未设置的集群都会被拒绝。
将 keeperClusterRef 指向由该 operator 管理的 KeeperCluster:
keeperClusterRef.namespace 时,operator 必须同时监听这两个命名空间。如果配置了 WATCH_NAMESPACE,请将 ClickHouse 和 Keeper 所在的命名空间都包含在该列表中。
外部管理的 Keeper
使用externalKeeper 可让 ClickHouse 连接到不受该 operator 管理的 Keeper ensemble——
例如由其他 operator 管理、运行在另一个 Kubernetes 集群中、部署在虚拟机或
裸金属服务器上,或由多个系统共享的 Keeper ensemble:
port 默认为 9181。host 可以是 DNS 名称或 IP 地址;IPv6 地址需用方
括号括起来。如需通过 TLS 连接,请设置 tls: Enabled,并将 port 设为 Keeper ensemble 用于安全连接的
监听端口:
caBundle (如有) 来验证 Keeper 证书。
请参阅 ClickHouse 与 Keeper 之间的 TLS 通信。
当多个 ClickHouse 集群共用同一个 Keeper ensemble 时,应通过 settings.extraConfig 为每个集群指定独立的根 znode,
以免各集群的复制元数据、通过 SQL 定义的用户以及命名集合相互冲突。请在 ClickHouse 启动之前创建该 znode,且创建后不要再更改:
zookeeper.root 放在 settings.extraReloadableConfig 中:重新加载会切换正在运行的集群的根路径,导致其复制表变为只读。如果根 znode 配置了 ACL,则必须允许
集群的 keeper-identity 创建子 znode。
operator 不会修改这些服务器,在 reconcile ClickHouse 之前也不会等待它们就绪。
Keeper ensemble 的可用性需由用户自行保障。
身份验证方式与 operator 管理的 Keeper 相同:operator 从集群 Secret 中读取
keeper-identity 键,并将其传递给 ClickHouse。有关 Secret 的结构,请参阅
外部 Secret。
KeeperCluster 配置
终止时的 leader 身份移交
Keeper 容器带有一个默认的preStop hook,它会在副本停止前要求其移交 Raft
leader 身份,并等待移交完成后才允许
容器终止。容器每次正常停止时都会执行该 hook,而不仅限于
operator 发起的滚动发布:descheduler 驱逐、节点排空或 自动扩缩器
操作都会触发同一个 hook,因为它是 kubelet 节点代理级别的 preStop handler,而
不是调和循环中的逻辑。
如果没有该 hook,重启当前 leader 会导致 ensemble 在新一轮选举完成之前
处于无 leader 状态;在高负载下,选举可能需要数秒,在
ClickHouse 侧则表现为 Keeper 连接丢失以及查询延迟升高。该 hook 会要求
副本让出 leader 身份 (通过
http_control 端口发送 Keeper 的 ydld 四字命令) ,然后轮询副本的状态,直到其不再是
leader 为止,而不是发出请求后立即让容器停止。在写入负载下,
发出即忘式的请求仍可能在与 SIGTERM 的竞争中落败,因此
正是这一等待过程确保了无 leader 窗口的时长可控。
该 hook 无需任何配置,并且能够平稳降级:早于
26.3 的 Keeper 版本尚不支持此处使用的 leader 身份相关命令,此时该请求为空操作,
容器会像没有该 hook 时一样停止。该 hook 运行的是 shell 脚本,因此要求镜像中包含
bash;如果您使用的是 distroless 或 scratch 类型的 Keeper 镜像,请通过 containerTemplate.lifecycle 覆盖或移除
该 hook,详见
API 参考文档。
存储配置
dataVolumeClaimSpec (标准 Kubernetes
PersistentVolumeClaimSpec) 配置持久化存储。Operator 会将其转换为每个副本对应的 PersistentVolumeClaim,
并将其挂载到数据路径 /var/lib/clickhouse:
仅当底层存储类支持卷扩容时,Operator 才能修改现有的 PVC。
集群域
spec.clusterDomain 用于设置 operator 在构建并写入 ClickHouse server
配置的 pod (容器组) 完全限定主机名时所使用的 Kubernetes DNS 后缀。默认值为 cluster.local,并且在
ClickHouseCluster 和 KeeperCluster 中都可用。
<cluster-name>-clickhouse-headless。
并为每个副本创建 Service <cluster-name>-clickhouse-internal-<shard>-<index>,用于暴露尚未就绪的 Pod (容器组) ,以处理内部流量
以及来自 operator 的管理请求。如果副本自身无法就绪,这可用于副本恢复。
Keeper 节点会通过其无头 Service 使用 pod 名称:<pod>.<headless-service>.<namespace>.svc.<clusterDomain>。
仅当你的集群中
kubelet 节点代理使用的 --cluster-domain
不是 cluster.local 时,才应覆盖此值。如果该值与实际的集群域不一致,
ClickHouse 将无法解析 Keeper 和副本主机名——协调以及
Distributed 查询都会因 DNS 解析错误而失败。请在
ClickHouseCluster 及其引用的 KeeperCluster 中设置相同的值。pod (容器组) 配置
自动拓扑分散与亲和性
将 Pod (容器组) 分散到各可用区:确保您的 Kubernetes 集群在不同可用区中具备足够的节点,以满足拓扑分布约束条件。
topologyMinDomains 设置为可用区的数量,以强制分散:
topologyMinDomains 需要配合 topologyZoneKey 使用。当可用的可用区数量少于所请求的数量时,Pod (容器组) 会持续处于 Pending 状态,因此请将其控制在集群实际能提供的可用区数量范围内。手动配置
pod (容器组) 中断预算
默认值
apply,也能避免意外丢失仲裁。
对于一个包含 3 个分片且
replicas: 3 的 ClickHouseCluster,operator 会创建 3 个 PDB,每个分片 1 个,且每个都设置为 minAvailable: 1。
覆盖默认设置
spec.podDisruptionBudget 覆盖 minAvailable 或 maxUnavailable (两者只能指定一个) :
maxUnavailable 形式:
unhealthyPodEvictionPolicy 字段传递到生成的 PDB 中——当你需要允许仍处于 NotReady 状态的 pod (容器组) 被驱逐时,这会很有用:
策略
spec.podDisruptionBudget.policy 允许你选择 operator 以多大力度管理 PDB:
示例——在开发集群上完全禁用 PDB 管理:
集群范围内停用
ENABLE_PDB 环境变量,在整个集群范围内停用 PDB 管理。设置 ENABLE_PDB=false 后,无论 spec.podDisruptionBudget.policy 如何,operator 都会跳过 所有 ClickHouseCluster 和 KeeperCluster 的 PDB reconcile 步骤,并且完全不监视 PodDisruptionBudget 资源。因此,operator 的 ServiceAccount 无需具备 poddisruptionbudgets.policy/v1 的 RBAC 权限;当 operator 以受限的 ServiceAccount 运行,且该账户刻意不包含这些权限时,这一点尤其有用。
容器配置
自定义镜像
容器资源
环境变量
卷挂载
可以为同一个
mountPath 指定多个卷挂载。
Operator 会将所有已指定的挂载创建为一个投影卷。健康探针
Operator 会为每个 ClickHouse 和 Keeper 容器配置存活探针 (存活) 和就绪探针 (就绪) 。 默认不配置启动探针 (startup) 。
ClickHouse 和 Keeper 使用相同的默认时间设置:
ClickHouse 会在加载表之前启动服务器间监听器,在加载完成后再启动客户端监听器。因此,即使表加载较慢,存活探针也不会失败;而就绪探针一旦通过,即表示该副本已能够处理查询。
可在任一资源上通过
spec.containerTemplate 覆盖任意探针。例如,自定义 ClickHouse 的存活探针:
启动探针
如果容器启动所需的时间超过存活探针所允许的时长,请使用startupProbe。按默认配置,存活探针允许的时长约为 60 秒初始延迟,外加 10 次间隔 5 秒的失败检查。
在启动探针成功之前,Kubernetes 会暂缓执行存活探针和就绪探针,因此启动缓慢不会导致重启循环。
例如,某个 Keeper 副本需要重放大型快照,可为其预留最多 10 分钟来开始接受连接:
TLS/SSL 配置
配置安全端点
SSL 证书 Secret 格式
tls.crt- PEM 编码的服务器证书tls.key- PEM 编码的私钥
此格式兼容由 cert-manager 生成的证书。
通过 TLS 进行 ClickHouse-Keeper 通信
如果keeperClusterRef 引用的 KeeperCluster 启用了 TLS,ClickHouseCluster 会自动使用与 Keeper 节点的安全连接。
如果使用 externalKeeper,则应改为设置 tls: Enabled,并将每个节点的 port 设置为该 Keeper ensemble 的安全客户端端口 (例如 9281) 。
ClickHouseCluster 会根据系统信任库以及你配置的任何 caBundle 来验证 Keeper 节点证书。
要信任私有 CA (例如自签名 CA 或内部 CA) ,请提供自定义 CA 证书包引用:
外部 Secret
spec.externalSecret 将 operator 指向一个预先创建的 Secret:
这里引用的 Secret 必须与 ClickHouseCluster 位于同一命名空间。该 operator 绝不会删除并非由其创建的 Secret。
必需的键
一个完整的 Secret 如下所示:
策略:Observe 与 Manage
spec.externalSecret.policy 用于控制 Operator 如何处理缺失的必需键:
即使设置了
policy: Manage,该 Secret 也必须已存在于命名空间中——Operator 绝不会自行创建 Secret,它只会将生成的键写入现有的 Secret。 如果引用的 Secret 不存在,则无论采用哪种 policy,协调都会因 ExternalSecretNotFound 而被阻塞。Observe。当你希望实现自给自足的引导,同时仍保留对 Secret 对象本身的所有权 (例如为了备份) 时,请选择 Manage。
状态条件和故障排查
ClickHouseCluster.status.conditions 中暴露 ExternalSecretValid 条件。协调过程看起来卡住时,请检查它:
当 Secret 无效时,operator 会将协调重新入队,因此一旦补齐缺失的键,下一次协调就会自动生效——无需重启 Pod (容器组) 。
所需键的集合取决于当前运行的 ClickHouse 版本。只有在 operator 的版本探测检测到 ClickHouse
25.12 或更高版本后,才会校验 named-collections-key。在较旧版本中,Secret 可以不包含该键。仅当设置了 spec.settings.encryption 时,才需要 disk-encryption-key。附加端口
8123 HTTP、9000 native、9009 interserver、9001/9002 management、9363 Prometheus 指标,以及启用 TLS 时对应的 8443/9440 TLS 端口变体。interserver 和 management 端口还会通过每个副本的内部 Service 暴露,以便副本和 operator 能够在副本就绪前进行通信。若要让 ClickHouse 监听更多协议 (如 MySQL、PostgreSQL、gRPC 或其他自定义端口) ,请在 spec.additionalPorts 中声明:
containerPorts 和公网无头 Service 中。
完整示例见 examples/custom_protocols.yaml。
端到端示例:MySQL wire 协议
9004 上对外暴露 ClickHouse:
字段约束
保留端口和名称
additionalPorts 条目。所有与 TLS 相关的端口都会被无条件保留,以确保后续切换 spec.settings.tls.enabled 时,不会破坏原本有效的集群。
以下名称也会被拒绝——它们是 operator 的内部协议类型标识符 (而非便于人工阅读的别名) :
被拒绝的请求会产生如下错误:
版本探测与升级通道
- 版本报告 — 对于
ClickHouseCluster,一个 KubernetesJob会将容器镜像运行一次,以检测当前运行的 ClickHouse 版本;对于KeeperCluster,operator 会从正在运行的副本中读取由 server 上报的版本。检测到的版本会记录到.status.version中,并用于其他协调步骤 (例如,名为外部 Secret的 named-collections key 仅在 ClickHouse25.12及以上版本中才需要) 。 - 升级通道 — 定期检查公开的 ClickHouse 发布源 (
https://clickhouse.com/data/version_date.tsv) 。operator 会通过VersionUpgradedstatus condition 报告是否有新版本可用。它绝不会自行升级 cluster——镜像标签始终由用户控制。
选择发布渠道
spec.upgradeChannel 用于指定 operator 要对照比较的上游发行版集合。ClickHouseCluster 和 KeeperCluster 都有这个相同的字段。
^(lts|stable|\d+\.\d+)?$ 验证) :
对于生产环境,通常更建议将通道固定为明确的
<major>.<minor> (例如 25.8) 。这样可以把集群锁定在预期的 major 发行线上,并且当某个副本因某种原因漂移到其他 major 版本时,Operator 会显示 WrongReleaseChannel 警告——这一点在镜像通过摘要 (@sha256:...) 而不是便于人类阅读的标签引用时尤其重要。对于不担心 major 版本跳变的开发集群,默认的空值也完全适用。
状态条件
可使用以下方式检查它们:
覆盖版本探测 Job
ClickHouseCluster。KeeperCluster 不再运行版本探测 Job——它的版本会直接从正在运行的 Keeper 副本中读取——因此 spec.versionProbeTemplate 已弃用,在那里不会产生任何效果。
该探测是通过一个常规的 Kubernetes Job 实现的。如果你的集群设置了准入策略,要求指定的 Tolerations、节点选择器或安全上下文,或者你想限制已完成的探测 Job 保留的时间,可以通过 spec.versionProbeTemplate 覆盖该模板:
version-probe 是 operator 的默认名称——containers: 下对应的条目会按名称与其匹配,因此 operator 会在默认配置的基础上,将用户提供的字段深度合并进去。
Operator 级别的控制
在隔离网络环境中,或者不允许访问
clickhouse.com 出站流量时,请设置 --disable-version-update-checks=true。
ClickHouse 设置
默认用户密码
spec.settings.defaultUserPassword 用于为内置 default
用户设置密码。请提供你创建的 Secret (推荐) 或 ConfigMap 中某个键的值,
而不要直接将密码内联写在 CR 中:
secret 或 configMap 其中之一,并且两者都必须同时包含 name (对象)
和 key (保存密码的条目) 。
密码类型
passwordType 用于告知 ClickHouse 如何解析该值。其默认值为
password (明文) ;其他可选项为哈希形式,例如
password_sha256_hex 和 password_double_sha1_hex。建议优先使用哈希类型,以避免
存储 明文。完整列表请参见
ClickHouse user settings。
使用 Secret 的完整示例
使用
passwordType: password 时,pod (容器组) 内的 clickhouse-client 会配置
为使用该密码,这样在调试时会更方便。使用 ConfigMap
password_sha256_hex 摘要:
不要将明文密码放在 ConfigMap 中。任何明文
(
passwordType: password) 值都应使用 Secret。配置中的自定义用户
在配置文件中添加其他用户。 为该用户创建 ConfigMap 和 Secret:数据库同步
clickhouse.com/ReplicaInitialized 就绪门控,因此只有在 Operator 完成初始化后,新副本才会通过公网无头 Service 对外发布:default 数据库会转换为 Replicated 引擎,并同步 schema。在此之前,Operator 和其他副本会通过其内部 Service 访问该副本。使用 enableDatabaseSync: false 时,Operator 会立即将副本标记为已初始化,因此就绪状态仅取决于容器探针。
Operator 绝不会删除已填充数据的非 Replicated default 数据库。此类副本在完成 schema 准备后仍会开始处理客户端流量,但在您自行解决该数据库的问题之前,集群会报告 SchemaInSync=False,原因为 DefaultDatabaseNotReplicated。
在缩容移除副本之前,Operator 会先将客户端流量从该副本卸载,等待其停止对外发布,将其剩余数据复制到存活副本,然后才将其删除。
服务器日志
通过spec.settings.logger 配置 ClickHouse 服务器日志。每个字段都是可选的,并且都有安全的默认值,因此即使你从未改动过,集群也会默认以 information 级别同时将日志输出到容器控制台和磁盘上的轮转文件。
operator 始终会保持控制台日志开启,以确保
kubectl logs 可用;当 logToFile 为 true 时,还会额外启用文件日志。使用默认值的集群会生成如下 logger 块:
spec.settings.logger 块也适用于 KeeperCluster;不过,operator 会改为将日志文件写入 /var/log/clickhouse-keeper/,并将 Raft 日志记录器 (raft_logs_level) 设置为相同的 level。
无论
logToFile 如何设置,控制台日志始终保持开启,因此即使禁用文件日志,kubectl logs 仍可正常使用。将日志发送到可解析 JSON 的结构化日志存储时,请设置 jsonLogs: true。系统日志表
Operator 会启用query_log、part_log、text_log、metric_log 和 asynchronous_metric_log 系统表。由于这些表与您的数据位于同一个卷上,spec.settings.systemLogsTTLDays 会通过表生存时间 (TTL) 限制它们的保留时长。如果创建集群时未指定该字段,defaulting webhook 会将其设为 30。将其设为 0 可显式禁用生存时间 (TTL)。
默认值仅适用于新建集群。在
systemLogsTTLDays 引入之前创建的集群,其系统日志表不会自动设置生存时间 (TTL),需要你手动设置该字段。extraConfig 为各个表单独调整 TTL、调整其他系统日志设置,或使用 @remove 属性彻底禁用某个表:
禁用表并不会删除该表:现有数据会一直保留在磁盘上,直到你手动删除该表。
系统表的生存时间 (TTL) 发生变化时,ClickHouse 会重新创建该系统表,并将旧数据保留在重命名后的表中,例如
system.text_log_0。不再需要历史数据时,请删除这些表。自定义配置
内嵌额外配置
extraConfig 添加自定义的 ClickHouse 配置:
有用链接:
可重新加载的额外配置
对extraConfig 的任何更改都会导致 ClickHouse Pod (容器组) 重启,因为 operator 无法确定哪些设置可在运行时重新加载。对于 ClickHouse 支持动态重新加载的设置 (常见的是 named_collections) ,请改用 extraReloadableConfig。operator 会通过重新加载配置来应用更改,无需重启 Pod (容器组) :
extraConfig 和 extraReloadableConfig 其中一处;如果两者包含相同的配置节,Operator 会发出警告。
使用
extraReloadableConfig 即表示你确认其中的设置可以安全地重新加载。若将必须重启才能生效的设置放在此处,该设置只会在下次重启后生效,且不会报错。嵌入式附加用户配置
extraUsersConfig 指定额外的 ClickHouse 用户配置。这对于直接在集群规范中定义用户、profile、配额和授权非常有用。
extraUsersConfig 存储在 k8s 的 ConfigMap 对象中。请避免在其中以明文形式存放 secret。配置示例
定期重新同步
除了响应 Kubernetes 事件之外,operator 还会按固定时间间隔对每个集群重新执行协调。这样可以让 watch 无法观察到的状态 (如 ClickHouse 副本健康状况、Keeper quorum) 对应的 状态条件 保持最新,并重试诸如清理卡住的 pod (容器组) 等修复操作。 该时间间隔由 operator 的RESYNC_PERIOD environment variable 控制 (默认为 30s) 。它适用于 KeeperCluster 资源,设为 0 即可禁用定期重新同步。ClickHouseCluster 资源每 30 秒轮询一次 ClickHouse 的 system.warnings,这本身就会重新触发协调,因此 RESYNC_PERIOD 目前对其不起作用。
MAX_CONCURRENT_RECONCILES 设置 (默认为 4) 。
暂停协调
在ClickHouseCluster 或 KeeperCluster 上设置 clickhouse.com/pause-reconciliation: "true" 注解,即可让 operator 停止对其进行协调。operator 会在已暂停的资源上报告 ReconcileSucceeded=False,原因为 ReconciliationPaused,除此之外不会对该资源做任何改动。如果 operator 会覆盖您的手动更改,可借此进行人工干预。暂停期间,operator 会将所有状态条件 (包括 Ready 和 Healthy) 报告为 Unknown,原因为 ReconciliationPaused,因为此时它不会观测该集群。移除该注解即可恢复协调;待处理的 spec 变更将在下一次协调时生效。