在Kubernetes上以Operator方式运行管理ClickHouse集群
clickhouse-operator 有两个同名项目,本文写的是社区使用最广、仍在活跃发版的 Altinity Kubernetes Operator for ClickHouse(CRD 组 clickhouse.altinity.com,集群对象的短名是 chi)。
另一个是 ClickHouse 官方的 ClickHouse/clickhouse-operator:CRD 组为 clickhouse.com(kind ClickHouseCluster / KeeperCluster),2025 年才开始发布、版本号还停在 v0.0.x,依赖 cert-manager 提供 webhook 证书,属于早期阶段。两者的 CRD 名称、字段结构完全不同,查文档时务必先看清是哪一个。
Altinity 这个 Operator 的核心是把「分片(shard)+ 副本(replica)」这套拓扑声明式化:
ClickHouseInstallation 集群本体,短名 chi
ClickHouseInstallationTemplate 可复用的 spec 模板片段
ClickHouseOperatorConfiguration Operator 自身配置
ClickHouseKeeperInstallation ClickHouse Keeper,短名 chk
需要注意:Operator 只负责建 Pod、Service、PVC 和生成 remote_servers / zookeeper 配置,表结构不归它管。Replicated 表、Distributed 表都要你自己在客户端里用 ON CLUSTER 建。
# Helm(推荐)
helm repo add altinity https://helm.altinity.com
helm repo update
helm upgrade --install clickhouse-operator altinity/altinity-clickhouse-operator \
--version 0.27.3 --namespace clickhouse --create-namespace
# 或用安装脚本
curl -s https://raw.githubusercontent.com/Altinity/clickhouse-operator/master/deploy/operator-web-installer/clickhouse-operator-install.sh \
| OPERATOR_NAMESPACE=clickhouse bash
# 或用 bundle 清单
kubectl apply -f https://raw.githubusercontent.com/Altinity/clickhouse-operator/release-0.27.3/deploy/operator/clickhouse-operator-install-bundle.yaml
kubectl get pods -n clickhouse
kubectl get crd | grep altinity
2 分片 × 2 副本 = 4 个 ClickHouse 节点:
apiVersion: clickhouse.altinity.com/v1
kind: ClickHouseInstallation
metadata:
name: cluster01
spec:
templates:
podTemplates:
- name: clickhouse-pod
spec:
containers:
- name: clickhouse
image: altinity/clickhouse-server:25.8.16.10002.altinitystable
volumeClaimTemplates:
- name: data
spec:
storageClassName: fast
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 500Gi
defaults:
templates:
podTemplate: clickhouse-pod
dataVolumeClaimTemplate: data
configuration:
zookeeper:
nodes:
- host: keeper-clickhouse-keeper.clickhouse.svc.cluster.local
port: 2181
clusters:
- name: cluster01
layout:
shardsCount: 2
replicasCount: 2
kubectl apply -f cluster01.yaml -n clickhouse
# 状态:In Progress → Completed
kubectl get chi -n clickhouse -o wide
kubectl get chi cluster01 -n clickhouse -o jsonpath='{.status}'
# Pod 名形如 chi-cluster01-cluster01-0-0-0(shard-replica 编号在名字里)
kubectl get pods -n clickhouse
layout 有两种写法:
# 紧凑写法:所有分片副本数一致
layout:
shardsCount: 3
replicasCount: 2
# 展开写法:逐个分片定义,可以给不同分片配不同的模板与副本数
layout:
shards:
- name: shard-a
replicasCount: 2
- name: shard-b
replicasCount: 1
weight: 2
internalReplication: "true"
shardsCount × replicasCount 等于最终的 host 总数(2×2 就是 4 个 Pod、4 个 Service),不是「2 个分片总共 2 个副本」。
分片数不是越多越好,官方建议数据量不到 5 TB 就不要分片 —— 分片意味着跨节点的分布式查询与数据搬迁,小集群加分片只会让查询更慢。
建表必须在客户端完成:
-- 单机表(每个分片各自一份)
CREATE TABLE analytics.page_views ON CLUSTER cluster01 (...)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/page_views', '{replica}')
ORDER BY ...;
-- 分布式表:统一查询入口
CREATE TABLE analytics.page_views_distributed ON CLUSTER cluster01
AS analytics.page_views
ENGINE = Distributed(cluster01, analytics, page_views, rand());
ClickHouse 的 Replicated 表依赖 Keeper(或 ZooKeeper)做元数据协调,replicasCount > 1 时必须有。Altinity Operator 用独立的 CRD 部署 Keeper,注意它属于另一个 API 组:
apiVersion: clickhouse-keeper.altinity.com/v1
kind: ClickHouseKeeperInstallation
metadata:
name: clickhouse-keeper
spec:
configuration:
clusters:
- name: keeper
layout:
replicasCount: 3
kubectl apply -f keeper.yaml -n clickhouse
# 关键:chi 里 zookeeper.nodes[].host 必须等于这里返回的 endpoint
kubectl get chk clickhouse-keeper -n clickhouse -o jsonpath='{.status.endpoint}'
# 每个 host 一套 PVC
kubectl get pvc -n clickhouse
kubectl get chi -n clickhouse -o jsonpath='{.status.pvc}'
# 临时停掉整个集群但保留数据:StatefulSet 缩到 0,PVC 不删
spec:
stop: true
存储扩容需要 StorageClass 支持 allowVolumeExpansion,改 volumeClaimTemplates 里的 resources.requests.storage 后重新 kubectl apply。
Altinity Operator 没有备份 CRD。不要去找 ClickHouseBackup 这类对象,它只是社区里提过的一个提案,并未实现。可用的两条路:
# 1) 原生 SQL(ClickHouse 22.7+ 内置,配置最简单)
BACKUP TABLE analytics.page_views TO Disk('backups', 'page_views.zip');
RESTORE TABLE analytics.page_views FROM Disk('backups', 'page_views.zip');
# 2) clickhouse-backup 工具(可备份 RBAC/配置,支持增量与对象存储)
clickhouse-backup create
clickhouse-backup upload
clickhouse-backup list
clickhouse-backup restore <backup-name>
原生 BACKUP/RESTORE 支持 Local / S3 / GCS / Azure,但不覆盖 RBAC 与配置文件;需要连用户权限一起备份时用 clickhouse-backup,它支持 Local、S3、GCS、Azure、FTP、SFTP、rsync 等目标。生产环境建议落到对象存储。
两个端口要分清:
8888 ClickHouse 指标(metrics-exporter sidecar 抓 system 表)
9999 Operator 自身指标(端口名 op-metrics)
安装时 Operator 会给 Pod 打上抓取注解:
prometheus.io/scrape: "true"
prometheus.io/port: "8888"
clickhouse-operator-metrics/scrape: "true"
clickhouse-operator-metrics/port: "9999"
用 Prometheus Operator 时,0.27.3 起的 Helm Chart 直接提供了开关:
--set serviceMonitor.enabled=true
--set serviceMonitor.keeperMetrics.enabled=true
集群内还有名为 clickhouse-operator-metrics 的 Service 暴露 8888/TCP。
# Operator
helm repo update altinity
helm upgrade clickhouse-operator altinity/altinity-clickhouse-operator -n clickhouse --version 0.27.3
# CRD 不会被 Helm 升级,需要单独 apply
kubectl apply -f https://raw.githubusercontent.com/Altinity/clickhouse-operator/release-0.27.3/deploy/operator/parts/crd.yaml
# ClickHouse 版本升级:改 podTemplate 里的镜像,apply 后 Operator 滚动重建
kubectl apply -f cluster01.yaml -n clickhouse
kubectl get pods -n clickhouse -w
kubectl delete crd clickhouseinstallations.clickhouse.altinity.com 会导致 Kubernetes 连带删除集群里所有 chi 与 chk 对象,相当于把整个 ClickHouse 集群的定义一次性抹掉。卸载 Operator 时要连带检查 CRD。helm upgrade 不升级 CRD。Chart 里的 CRD 只走 pre-install hook,升级时若含新字段,不手动 kubectl apply 对应版本的 crd.yaml,新字段会被 API Server 静默丢弃,报错信息完全指不到根因。shardsCount: 2 + replicasCount: 2 是 4 个 host(4 份存储、4 个 Pod),不是 2 个。规划容量时按乘积算。replicasCount > 1 没有意义。Replicated 引擎依赖 Keeper 协调,而且 configuration.zookeeper.nodes[].host 必须等于 chk 对象的 status.endpoint,写错的话副本之间无法建立复制,建表会直接报错。clickhouse_operator 的默认密码必须改。Operator 用这个账号做指标采集、schema 维护、清 DNS 缓存,默认值 clickhouse_operator / clickhouse_operator_password 是公开的。volumeClaimTemplates 就会丢数据。默认存储不是持久卷,Pod 重建后数据全没;生产必须显式定义 PVC 模板。remote_servers 里降权、等 in-flight 查询结束」。停留在这些版本时要挑低峰期升级。spec.stop: true 是停集群不是删集群。它把 StatefulSet 副本数缩到 0 但保留 PVC,适用于临时释放算力;恢复时改回 false 即可,数据仍在。kubectl — Kubernetes集群管理工具statefulset — ClickHouse host 的实际载体pvc — 持久卷声明,数据盘storageclass — 存储类,决定 ClickHouse 磁盘性能helm — Kubernetes包管理器prometheus — 抓取 8888 / 9999 指标