Skip to content

Commit 36c33d1

Browse files
authored
Update users_in_keeper.md
1 parent 1e0906b commit 36c33d1

1 file changed

Lines changed: 50 additions & 11 deletions

File tree

content/en/altinity-kb-setup-and-maintenance/users_in_keeper.md

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ This KB explains how to make SQL RBAC changes (`CREATE USER`, `CREATE ROLE`, `GR
1212

1313
`Keeper` below means either ClickHouse Keeper or ZooKeeper.
1414

15+
TL;DR:
16+
- By default, SQL RBAC changes (`CREATE USER`, `GRANT`, etc.) are local to each server.
17+
- Replicated access storage keeps RBAC entities in ZooKeeper/ClickHouse Keeper so changes automatically appear on all nodes.
18+
- This guide shows how to configure replicated RBAC, validate it, and migrate existing users safely.
19+
1520
Before details, the core concept is:
1621
- ClickHouse stores access entities in access storages configured by `user_directories`.
1722
- By default, following the shared-nothing concept, SQL RBAC objects are local (`local_directory`), so changes done on one node do not automatically appear on another node unless you run `... ON CLUSTER ...`.
1823
- With `user_directories.replicated`, ClickHouse stores the RBAC model in Keeper under a configured path (for example `/clickhouse/access`) and every node watches that path.
19-
- Each node keeps a local in-memory mirror of replicated access entities and updates it from Keeper watch notifications. This is why normal access checks are local-memory fast, while RBAC writes depend on Keeper availability.
20-
21-
Important mental model:
22-
- this feature replicates RBAC state (users, roles, grants, policies, profiles, quotas, masking policies);
23-
- it is not the same mechanism as distributed DDL queue execution used by `ON CLUSTER`.
24+
- Each node keeps a local in-memory mirror of replicated access entities and updates it from Keeper watch callbacks. This is why normal access checks are local-memory fast, while RBAC writes depend on Keeper availability.
2425

2526
Flow of this KB:
2627
1. Why this model helps.
@@ -29,17 +30,19 @@ Flow of this KB:
2930
4. How to migrate existing RBAC safely.
3031
5. Advanced troubleshooting and internals.
3132

32-
## 1. Choose the RBAC replication model (`ON CLUSTER` vs Keeper)
33+
## 1. ON CLUSTER vs Keeper-backed RBAC: when to use which
3334

3435
`ON CLUSTER` executes DDL on hosts that exist at execution time.
35-
In practice, it fans out the query through the distributed DDL queue to currently known cluster nodes.
36+
In practice, it fans out the query through the distributed DDL queue (also Keeper/ZooKeeper-dependent) to currently known cluster nodes.
3637
It does not automatically replay old RBAC DDL for replicas/shards added later.
3738

3839
Keeper-backed RBAC solves that:
3940
- one shared RBAC state for the cluster;
4041
- new servers read the same RBAC state when they join;
4142
- no need to remember `ON CLUSTER` for every RBAC statement.
4243

44+
Mental model: Keeper-backed RBAC replicates access state, while `ON CLUSTER` fans out DDL to currently known nodes.
45+
4346
### 1.1 Pros and Cons
4447

4548
Pros:
@@ -50,12 +53,12 @@ Pros:
5053
- Integrates with access-entity backup/restore.
5154

5255
Cons:
53-
- Writes depend on Keeper availability (reads can continue from local cache, writes fail when Keeper is unavailable).
56+
- Writes depend on Keeper availability. `CREATE/ALTER/DROP USER` and `CREATE/ALTER/DROP ROLE`, plus `GRANT/REVOKE`, fail if Keeper is unavailable, while existing authentication/authorization may continue from already loaded cache until restart.
5457
- Operational complexity increases (Keeper health directly affects RBAC operations).
5558
- Can conflict with `ON CLUSTER` if both mechanisms are used without guard settings.
5659
- Invalid/corrupted payload in Keeper can be skipped or be startup-fatal, depending on `throw_on_invalid_replicated_access_entities`.
5760
- Very large RBAC sets (thousands of users/roles or very complex grants) can increase Keeper/watch pressure.
58-
- If Keeper is unavailable during server startup and replicated RBAC storage is configured, startup can fail, so DBA login is unavailable until startup succeeds.
61+
- If Keeper is unavailable during server startup and replicated RBAC storage is configured, startup can fail, so you may be unable to log in until startup succeeds.
5962

6063
## 2. Configure Keeper-backed RBAC on a new cluster
6164

@@ -85,6 +88,11 @@ Why `replace="replace"` matters:
8588
- defaults include `local_directory`, so SQL RBAC may still be written locally;
8689
- this can cause mixed behavior (some entities in Keeper, some in local files).
8790

91+
Recommended configuration for clusters using replicated RBAC:
92+
- `users_xml`: bootstrap/break-glass admin users and static defaults.
93+
- `replicated`: all SQL RBAC objects (`CREATE USER`, `CREATE ROLE`, `GRANT`, policies, profiles, quotas).
94+
- avoid `local_directory` as an active writable SQL RBAC storage to prevent mixed write behavior.
95+
8896
### 2.1 Understand `user_directories`: defaults, precedence, coexistence
8997

9098
What can be configured in `user_directories`:
@@ -148,6 +156,14 @@ FROM system.user_directories
148156
ORDER BY precedence;
149157
```
150158

159+
Example expected result (values can vary by version/config; precedence values are relative and order matters):
160+
161+
```text
162+
name type precedence
163+
users_xml users_xml 0
164+
replicated replicated 1
165+
```
166+
151167
Check where users are stored:
152168

153169
```sql
@@ -156,11 +172,20 @@ FROM system.users
156172
ORDER BY name;
157173
```
158174

175+
Example expected result for SQL-created user:
176+
177+
```text
178+
name storage
179+
kb_test replicated
180+
```
181+
159182
Smoke test:
160183
1. On node A: `CREATE USER kb_test IDENTIFIED WITH no_password;`
161184
2. On node B: `SHOW CREATE USER kb_test;`
162185
3. On either node: `DROP USER kb_test;`
163186

187+
RBAC changes usually propagate within milliseconds to seconds, depending on Keeper latency and cluster load.
188+
164189
Check Keeper data exists:
165190

166191
```sql
@@ -213,6 +238,8 @@ Also decide your strictness for invalid replicated entities:
213238

214239
Before switching to Keeper-backed RBAC, treat this as a storage migration.
215240

241+
**Important:** replay/restore RBAC on one node only. Objects are written to Keeper and then reflected on all nodes.
242+
216243
Key facts before migration:
217244
- Changing `user_directories` storage or changing `zookeeper_path` does **not** move existing SQL RBAC objects automatically.
218245
- If path changes, old users/roles are not deleted, but become effectively hidden from the new storage path.
@@ -230,6 +257,7 @@ Recommended high-level steps:
230257
This path is useful when:
231258
- RBAC DDL is already versioned in your repo, or
232259
- you want to dump/replay access entities using SQL only.
260+
- Replaying `SHOW ACCESS` output is idempotent only if you handle `IF NOT EXISTS`/cleanup; otherwise prefer restoring into an empty RBAC namespace.
233261

234262
Recommended SQL-only flow:
235263
1. On source, check where entities are stored (local vs replicated):
@@ -271,6 +299,7 @@ clickhouse-backup restore --rbac-only users_bkp_20260304
271299
Important:
272300
- this applies to SQL/RBAC users (created with `CREATE USER ...`, `CREATE ROLE ...`, etc.);
273301
- if your users are in `users.xml`, those are config-based (`--configs`) and this is not an automatic local->replicated RBAC conversion.
302+
- run restore on one node only; entities will be replicated through Keeper.
274303

275304
### 6.3 Migration with embedded SQL `BACKUP/RESTORE`
276305

@@ -311,6 +340,7 @@ About `clickhouse-backup --rbac/--rbac-only`:
311340
- It is an external tool, not ClickHouse embedded backup by itself.
312341
- If `clickhouse-backup` is configured with `use_embedded_backup_restore: true`, it delegates to SQL `BACKUP/RESTORE` and follows embedded rules.
313342
- Otherwise it uses its own workflow; do not assume full equivalence with embedded `allow_backup` semantics.
343+
- run restore on one node only; entities will be replicated through Keeper.
314344

315345
## 7. Troubleshooting: common support issues
316346

@@ -320,6 +350,7 @@ About `clickhouse-backup --rbac/--rbac-only`:
320350
| RBAC objects “disappeared” after config change/restart | `zookeeper_path` or storage source changed | Restore from backup or recreate RBAC in the new storage; keep path stable |
321351
| New replica has no historical users/roles | Team used only `... ON CLUSTER ...` before scaling | Enable Keeper-backed RBAC so new nodes load shared state |
322352
| `CREATE USER ... ON CLUSTER` throws "already exists in replicated" | Query fan-out + replicated storage both applied | Remove `ON CLUSTER` for RBAC or enable `ignore_on_cluster_for_replicated_access_entities_queries` |
353+
| `CREATE USER`/`GRANT` fails with Keeper/ZooKeeper error | Keeper unavailable or connection lost | Check `system.zookeeper_connection`, `system.zookeeper_connection_log`, and server logs |
323354
| RBAC writes still go local though `replicated` exists | `local_directory` remains first writable storage | Use `user_directories replace="replace"` and avoid writable local SQL storage in front of replicated |
324355
| Server does not start when Keeper is down; no one can log in | Replicated access storage needs Keeper during initialization | Restore Keeper first, then restart; if needed use a temporary fallback config and keep a break-glass `users.xml` admin |
325356
| Startup fails (or users are skipped) because of invalid RBAC payload in Keeper | Corrupted/invalid replicated entity and strict validation mode | Use `throw_on_invalid_replicated_access_entities` deliberately: `true` fail-fast, `false` skip+log; fix bad Keeper payload before re-enabling strict mode |
@@ -341,14 +372,14 @@ About `clickhouse-backup --rbac/--rbac-only`:
341372

342373
## 9. Observability and debugging signals
343374

344-
Keeper connectivity:
375+
### 9.1 Check Keeper connectivity
345376

346377
```sql
347378
SELECT * FROM system.zookeeper_connection;
348379
SELECT * FROM system.zookeeper_connection_log ORDER BY event_time DESC LIMIT 100;
349380
```
350381

351-
Keeper operations for RBAC path:
382+
### 9.2 Inspect RBAC activity in Keeper
352383

353384
```sql
354385
SELECT event_time, type, op_num, path, error
@@ -358,6 +389,8 @@ ORDER BY event_time DESC
358389
LIMIT 200;
359390
```
360391

392+
### 9.3 Relevant server log patterns
393+
361394
Note: `system.zookeeper_log` is often disabled in production.
362395
If it is unavailable, use server logs (usually `clickhouse-server.log`) with these patterns:
363396

@@ -370,6 +403,8 @@ Can't have Replicated access without ZooKeeper
370403
ON CLUSTER clause was ignored for query
371404
```
372405

406+
### 9.4 Inspect distributed DDL queue activity (when `ON CLUSTER` is involved)
407+
373408
If troubleshooting mixed usage of distributed DDL:
374409

375410
```sql
@@ -379,6 +414,8 @@ ORDER BY query_create_time DESC
379414
LIMIT 100;
380415
```
381416

417+
### 9.5 Force RBAC reload
418+
382419
Force access reload:
383420

384421
```sql
@@ -387,6 +424,8 @@ SYSTEM RELOAD USERS;
387424

388425
## 10. Keeper path structure and semantics (advanced)
389426

427+
The following details are useful for advanced debugging or when inspecting Keeper paths manually.
428+
390429
If `zookeeper_path=/clickhouse/access`:
391430

392431
```text

0 commit comments

Comments
 (0)