ClickHouse 从单节点切换到分片集群(Sharded Cluster)架构时,用户信息(如 admin
用户)未同步过去
这实际上是 ClickHouse 架构设计中的一个常见问题 —— 用户信息不是通过分片机制自动同步的,因为用户信息并不存储在普通表中,也不属于 replicated
表机制的范围。
🔍 一、为什么用户没有同步?
ClickHouse 的用户信息来源于以下几种方式:
- 本地配置文件(如
/etc/clickhouse-server/users.xml
,users.d/*.xml
); - Kubernetes 下通过 ConfigMap 或 Secret 挂载;
- 外部认证源(如 LDAP、Kerberos);
- 使用 SQL 动态创建(但只影响当前节点,且不会传播);
而 这些用户配置并不会通过复制表、分片机制或 Zookeeper 自动同步。
✅ 二、处理方案(根据部署方式)
✅ A. Kubernetes 部署(推荐方式)
如果你是通过 Kubernetes 部署 ClickHouse(如使用 Altinity Operator、ClickHouse Operator),可以采用以下方法统一管理用户:
方式 1:通过 Operator CRD 配置 users
(推荐)
大部分 Operator 支持在 ClickHouseInstallation
资源中配置用户:
apiVersion: "clickhouse.altinity.com/v1"
kind: "ClickHouseInstallation"
metadata:
name: my-clickhouse
spec:
configuration:
users:
admin:
password: my_secure_password
networks:
ip:
- "::/0"
应用该配置后,所有 Pod 会自动分发该用户。
方式 2:创建统一 ConfigMap,并挂载到所有 Pod
apiVersion: v1
kind: ConfigMap
metadata:
name: ck-user-config
data:
admin.xml: |
<clickhouse>
<users>
<admin>
<password>secure_pass</password>
<networks><ip>::/0</ip></networks>
</admin>
</users>
</clickhouse>
然后在 StatefulSet 中挂载到 /etc/clickhouse-server/users.d/admin.xml
,并重启所有 Pod。
✅ B. 非 K8s 部署(物理机 / 虚拟机 / Docker)
你需要将用户配置 手动同步 到所有分片节点:
-
找出单节点的
users.xml
或users.d/*.xml
中有关admin
的配置; -
将该 XML 文件复制到分片集群所有节点的
/etc/clickhouse-server/users.d/
下; -
重启 ClickHouse 服务:
sudo systemctl restart clickhouse-server
或容器中:
supervisorctl restart clickhouse-server
✅ C. 自动同步脚本(可选)
如果节点多,可以写个简单的同步脚本,使用 scp
或 rsync
批量分发配置文件并重启服务:
for node in node1 node2 node3; do
scp /etc/clickhouse-server/users.d/admin.xml $node:/etc/clickhouse-server/users.d/
ssh $node 'systemctl restart clickhouse-server'
done
🧩 三、补充建议
- ✅ 如果你的 ClickHouse 用户采用 SQL 创建(如
CREATE USER admin IDENTIFIED WITH...
),你需要在所有节点重复执行; - 🚫 这些 SQL 创建不会自动复制,因为用户是本地作用域(不是复制表);
- ✅ 推荐将用户权限/认证集中在配置文件管理,并统一下发。
✅ 四、验证用户是否存在
执行:
SELECT name FROM system.users;
在每个分片上检查 admin
是否存在。
如你使用的是 Operator,我也可以为你生成一份完整的 YAML 配置同步用户。是否使用哪种 Operator(Altinity、Zookeeperless、ClickHouse Keeper)?可以告诉我。
根因定位
从你提供的日志截图来看,ClickHouse Operator 在执行用户同步操作(sync_user
)时权限不足,导致无法成功将用户配置(如 admin
)应用到 Pod 中。
❗关键报错信息分析:
error pods "ck-9260f445-replica0-0-0" is forbidden: User "system:serviceaccount:qfusion:clickhouse-operator" cannot create resource "pods/exec" in API group "" in the namespace "qfusion-admin"
这意味着:
- 当前的 ClickHouse Operator 绑定的 ServiceAccount(
clickhouse-operator
) 没有权限执行pods/exec
操作; - 而用户同步操作依赖
exec
到 Pod 中执行脚本来修改或创建用户; - 最终导致
migrateUsers()
和sync_user
报错失败。
✅ 解决方案:补全 Operator 的权限(RBAC)
你需要为 ClickHouse Operator 的 ClusterRole
添加 pods/exec
权限。
✅ 步骤一:确认 Operator 使用的 ServiceAccount
从报错看是:
ServiceAccount: clickhouse-operator
Namespace: qfusion
✅ 步骤二:扩展 ClusterRole 权限
找到或编辑绑定在 clickhouse-operator
上的 ClusterRole
(通常名为 clickhouse-operator
或类似),增加如下权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: clickhouse-operator
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec"]
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
✅ 如果你已经有
pods
的权限,只需在resources
中添加"pods/exec"
即可。
✅ 步骤三:确认 ClusterRoleBinding 存在
确认这个角色绑定到了 clickhouse-operator
使用的 ServiceAccount:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: clickhouse-operator
subjects:
- kind: ServiceAccount
name: clickhouse-operator
namespace: qfusion
roleRef:
kind: ClusterRole
name: clickhouse-operator
apiGroup: rbac.authorization.k8s.io
✅ 步骤四:应用并重启 Operator(可选)
kubectl apply -f updated-clusterrole.yaml
kubectl apply -f clusterrolebinding.yaml
如果 Operator 是以 Deployment 运行,建议重启它确保权限生效:
kubectl rollout restart deployment -n qfusion clickhouse-operator
✅ 步骤五:再次观察日志
观察 Operator 日志中是否出现如下成功标志:
migrateUsers(): sync_user on host X succeeded
或执行用户查询验证是否生效:
SELECT name FROM system.users;
✅ 附加建议
如果你是用 Altinity Operator 或社区版 Operator,可以提供其 Helm chart 或 manifest 来源,我可以为你补全一份对应的完整 RBAC 权限模板。
是否需要我为你生成一个适配你当前环境的 ClusterRole 文件?只需告诉我使用的 Operator 版本或部署方式(如 Helm chart 名称)。