
ClickHouse Operator 的 ClickHouseKeeper 引用指南通过 KeeperRef 在 CHI 中自动解析 Keeper 拓扑【免费下载链接】clickhouse-operatorAltinity Kubernetes Operator for ClickHouse creates, configures and manages ClickHouse® clusters running on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/cl/clickhouse-operator本指南讲解 Altinity ClickHouse Operator 中spec.configuration.zookeeper.keeperKeeperRef的完整用法如何在ClickHouseInstallationCHI中通过名称引用ClickHouseKeeperInstallationCHK资源由 Operator 在协调reconcile期间自动解析出 ZooKeeper 节点地址。读完本文你将掌握 KeeperRef 的字段语义、replicas与service两种端点发现模式、TLS 自动检测、就绪等待与超时配置、CHK 变更自动触发 CHI 协调以及基于真实源码的故障排查方法。为什么需要 Keeper 引用KeeperRef在 ClickHouse 复制拓扑中副本间的元数据同步依赖 ZooKeeper 兼容服务。传统写法是在spec.configuration.zookeeper.nodes中逐个显式写出host:portzookeeper: nodes: - host: zookeeper-0.zookeepers.zoo3ns.svc.cluster.local port: 2181 - host: zookeeper-1.zookeepers.zoo3ns.svc.cluster.local port: 2181 - host: zookeeper-2.zookeepers.zoo3ns.svc.cluster.local port: 2181这种方式要求运维人员预先知道 ZooKeeper/Keeper 的完整地址清单且当 Keeper 扩缩容时必须手工同步维护 CHI 清单极易出错。KeeperRef 的引入正是为了解决这个问题不再显式指定端点而是通过名称引用一个ClickHouseKeeperInstallationCHK资源由 Operator 在协调周期中自动解析出实际的 Keeper 节点地址并写入 ClickHouse 配置。从源码看KeeperRef类型定义于 pkg/apis/clickhouse.altinity.com/v1/type_keeper_ref.go它挂在ZookeeperConfig上pkg/apis/clickhouse.altinity.com/v1/type_zookeeper.go与显式Nodes是同一层级的两条可选路径。基本用法最简单的引用方式如下完整可运行示例见 docs/chi-examples/04-replication-zookeeper-07-keeper-ref.yamlapiVersion: clickhouse.altinity.com/v1 kind: ClickHouseInstallation metadata: name: my-chi spec: configuration: zookeeper: keeper: name: my-keeper clusters: - name: default layout: shardsCount: 1 replicasCount: 2当 CHI 提交后Operator 会通过 CHK 名称与命名空间定位对应的ClickHouseKeeperInstallation资源发现该 CHK 暴露的所有 Keeper 副本服务或 CR 级服务取决于serviceType将解析出的节点地址按zookeepernodehost.../hostport.../port/node结构渲染进 ClickHouse 配置使 ClickHouse 获得正确的 ZooKeeper 节点列表。这条解析链路在源码中对应 pkg/controller/chi/controller-keeper-resolver.go 中的resolveKeeperNodes它按serviceType分派到resolveKeeperByReplicas按副本发现或resolveKeeperByService按 CR 级服务发现最终返回一个api.ZookeeperNodes列表。值得注意的实现细节是当副本发现失败或返回 0 个节点时replicas模式会自动回退到 CR 级服务提升了解析的健壮性。KeeperRef 字段详解下表完整列出KeeperRef支持的字段与 type_keeper_ref.go 中的结构定义一一对应字段类型默认值说明namestring必填ClickHouseKeeperInstallation资源的名称namespacestringCHI 所在命名空间CHK 资源所在命名空间跨命名空间引用时需显式指定serviceTypestringreplicas端点发现模式见下文在类型层面KeeperRef提供了几个 nil 安全的访问器HasName()判断引用是否有效、GetNamespace(defaultNamespace)在未指定时回落到 CHI 命名空间、GetServiceType()在未指定时默认返回replicas。这也解释了文档中namespace 省略则默认同命名空间、serviceType默认replicas的行为。另外ZookeeperConfig.IsEmpty()的语义值得注意只有当nodes为空且没有keeper引用时该配置才被视为空。也就是说只要填了keeper即使不写任何nodes也能正常驱动解析逻辑。ServiceType两种端点发现模式serviceType控制 Keeper 端点如何被发现两种模式的常量定义见 type_keeper_ref.goreplicas默认发现每个 Keeper 副本对应的 per-host 服务为每个 Keeper 副本生成一个 ZooKeeper 节点。ClickHouse 能感知完整的 Keeper 拓扑故障转移时具备全局视野生产环境推荐使用。源码实现上resolveKeeperByReplicas通过 CHK labeler 的LabelCRName与LabelServiceValueHost标签选择器列出所有 host 服务按名称排序后逐一生成节点见 controller-keeper-resolver.go。service将 CHK CR 级 headless 服务作为一个单一 ZooKeeper 节点条目。配置更简单但 ClickHouse 看不到各个 Keeper 副本拓扑感知能力较弱。源码实现resolveKeeperByService直接通过 CHK 命名器构造 CR 级服务名并查询该 Service 的端口信息见 controller-keeper-resolver.go。与其他 ZooKeeper 设置的组合keeper引用与zookeeper下的其他字段完全正交可以同时使用。解析出的节点会与显式声明的nodes共存最终统一渲染进 ClickHouse 的zookeeper配置zookeeper: keeper: name: my-keeper session_timeout_ms: 30000 operation_timeout_ms: 10000 root: /clickhouse/my-cluster identity: user:password各字段的 ClickHouse 侧语义依据 type_zookeeper.go 的注释session_timeout_msZooKeeper 会话超时毫秒渲染为session_timeout_msoperation_timeout_ms单次 ZooKeeper 操作超时毫秒渲染为operation_timeout_msrootClickHouse 所有 znode 的可选根路径前缀渲染为rootidentityZooKeeper digest 认证凭据格式user:password渲染为identityuse_compressionKeeper 协议客户端-服务端通信压缩开关渲染为use_compression。从合并逻辑看ZookeeperConfig.MergeFromtype_zookeeper.go采用节点去重追加、Keeper 引用仅在接收方为空时采纳、标量字段非零覆盖的策略模板与 CHI 合并时行为可预期。集群级覆盖Cluster-Level Override同一个 CHI 下可以部署多个集群每个集群可以拥有自己的 Keeper 引用从而覆盖顶层配置。覆盖规则很明确只要某个集群带有自己的zookeeper配置无论是自己的keeper引用还是自己的nodes顶层配置对该集群就被整体忽略。spec: configuration: zookeeper: keeper: name: default-keeper clusters: - name: cluster-a # 使用 default-keeper继承自顶层配置 layout: shardsCount: 2 replicasCount: 2 - name: cluster-b # 使用自己专属的 keeper zookeeper: keeper: name: dedicated-keeper namespace: keeper-namespace layout: shardsCount: 1 replicasCount: 3真实的全字段示例docs/chi-examples/99-clickhouseinstallation-max.yaml中同样包含一个集群级覆盖shards-only集群声明了自己的zookeeper.keepercluster-specific-keeper、serviceType: service与顶层配置并存互不干扰。TLS 自动检测Operator 会自动探测 Keeper 是否启用了 TLS探测依据是服务端口定义。相关常量与检测函数位于 pkg/apis/clickhouse.altinity.com/v1/type_host.go端口2181或端口名为zk→ 不安全连接端口2281或端口名为zk-secure→ 安全连接会在 ClickHouse 配置中设置secure1/secure。检测函数ExtractZKPortInfo的优先级是优先返回安全端口若同时暴露了多个端口只要存在zk-secure/2281就以安全模式解析否则回落到非安全端口最后兜底为默认的2181。因此只要 Keeper 暴露了安全端口解析出的 ZooKeeper 节点会自动带上secure: true无需任何手工配置。完整的常量映射为zk/2181Keeper 默认 ZooKeeper 客户端端口不安全zk-secure/2281Keeper 安全TLSZooKeeper 客户端端口raft/9444Keeper 内部 Raft 端口不用于客户端连接Keeper 就绪等待Readiness在解析端点之前Operator 会等待被引用的 CHK 的 Pod 进入Running阶段。这主要处理 CHK 与 CHI同时创建的场景——此时 Keeper Pod 可能尚未启动直接解析会失败。等待超时通过 Operator 配置ClickHouseOperatorConfiguration控制spec: reconcile: coordination: keeper: readyTimeout: 120 # 秒默认120该行为在 pkg/controller/chi/worker-keeper-resolver.go 的waitKeeperReady中实现它读取chop.Config().Reconcile.Coordination.Keeper.ReadyTimeout单位秒轮询 CHK 的所有 Pod任一 Pod 未处于Running阶段就继续等待。如果等待超时CHI 协调将以ErrKeeperNotReady错误失败并在 CHI 资源上发出 Kubernetes Event。该错误哨兵值定义于 controller-keeper-resolver.go同类错误还包括ErrKeeperRefResolve引用解析失败如服务未找到与ErrKeeperRefNoNodes解析成功但得到 0 个节点。CHK 变更自动触发 CHI 协调Auto-ReconcileKeeper 集群扩缩容后ClickHouse 侧需要感知新的节点列表。Operator 提供了可选的 CHK 资源监听机制# ClickHouseOperatorConfiguration spec: reconcile: coordination: keeper: readyTimeout: 120 onKeeperResourceUpdate: reconcile # none默认或 reconcile当onKeeperResourceUpdate: reconcile时Operator 在监听命名空间内 watch 所有 CHK 资源pkg/controller/chi/controller-chk-watcher.go 中的StartCHKWatcher通过动态 informer 实现resync 周期 60 秒仅当 CHK转换到Completed状态时才触发依赖 CHI 的重新协调onCHKUpdate只对从非 Completed 变为 Completed的转换响应InProgress阶段不会触发见 controller-chk-watcher.go触发前会做一次端点差分shouldReconcileOnKeeperUpdate将当前 CHK 状态解析出的节点集合与 CHI 上次完成协调NormalizedCRCompleted消费的节点集合做集合相等比较controller-chk-watcher.go。只有当解析出的 ZooKeeper 端点列表确实发生变化时才入队协调——像磁盘扩容这类不影响端点列表的 CHK 变更会被跳过并发出KeeperUpdateNoEndpointChange事件说明跳过原因。这一差分机制保证了 ClickHouse 能及时跟上 Keeper 拓扑变化如 Keeper 扩缩容同时避免无意义的空转协调。故障排查Troubleshooting查看解析出的端点解析后的 Keeper 节点会出现在 CHI 的归一化状态中kubectl get chi my-chi -o json | jq .status.normalizedCompleted.spec.configuration.zookeeper.nodes查看 Kubernetes EventsKeeper 引用解析失败会发出 Kubernetes Eventskubectl get events --field-selector involvedObject.namemy-chi,reasonReconcileFailed结合前文还可以用reasonKeeperUpdateNoEndpointChange查看CHK 完成但端点未变化、协调被跳过的事件。常见问题速查表症状原因解决方法CHI 卡在 InProgressCHK Pod 未运行检查 CHK 状态kubectl get chkCHI 协调超时失败readyTimeout过短在 Operator 配置中增大readyTimeoutClickHouse 无法连接 Keeperkeeper 引用中的 namespace 错误校验namespace字段或省略以使用同命名空间只解析出 1 个 ZK 节点使用了serviceType: service切换为serviceType: replicas默认Keeper 扩缩后 CHI 未更新Watcher 未启用在 Operator 配置中设置onKeeperResourceUpdate: reconcile另外源码层面还有两个可辅助诊断的错误语义ErrKeeperRefNoNodes提示解析成功但 CHK 当前没有任何可用的 host 服务例如 CHK 尚未生成服务或副本数为 0而replicas模式在副本发现失败时自动回退到 CR 级服务若最终仍失败才会返回ErrKeeperRefResolve。完整配置示例Basic keeper reference最简引用 session_timeout_ms/operation_timeout_ms组合All fields example同时演示顶层keeper引用注释形式与集群级zookeeper.keeper覆盖shards-only集群、以及显式nodes对照写法Operator config with coordination完整ClickHouseOperatorConfiguration其中reconcile.coordination.keeper一节同时给出了readyTimeout: 120与onKeeperResourceUpdate: none默认值的完整上下文可在此基础上按需修改。总结KeeperRef 将ClickHouse ↔ ZooKeeper/Keeper 拓扑的耦合点从手工维护的host:port清单收敛为对 CHK 资源的声明式引用。配合replicas模式的完整拓扑感知、基于服务端口的 TLS 自动检测、CHK 就绪等待与readyTimeout超时保护以及onKeeperResourceUpdate: reconcile下的端点差分触发协调Operator 能够在不改动 CHI 的情况下自动跟随 Keeper 集群的演进这是生产环境搭建复制集群如 docs/chi-examples/04-replication-zookeeper-07-keeper-ref.yaml 演示的 1 分片 2 副本场景时推荐的首选方式。【免费下载链接】clickhouse-operatorAltinity Kubernetes Operator for ClickHouse creates, configures and manages ClickHouse® clusters running on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/cl/clickhouse-operator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考