From 790f7c1bb71670467a85b04a6549b31c349220b0 Mon Sep 17 00:00:00 2001 From: Dmitry Dementiev Date: Thu, 13 Aug 2026 10:04:58 +0300 Subject: [PATCH] =?UTF-8?q?feat(clickhouse):=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=80=D0=BE=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=B8=20=D0=BC=D0=B5=D0=B6=D0=BD=D0=BE=D0=B4=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D0=B9=20=D1=81=D0=B5=D0=BA=D1=80=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - менти должен увидеть разделение доступа без состояния в томах. - Что: - пользователи и роли объявлены файлом с паролями из окружения. - межшардовые запросы передают пользователя через общий секрет. - четыре допущения реализации подтверждены в ADR живыми замерами. - Проверка: - make config-test, make smoke, make check-clickhouse, make check-services. --- .env.example | 5 +++ compose.yaml | 6 +++ docs/adr/0007-clickhouse-access.md | 22 ++++++---- infra/clickhouse/config.d/cluster.xml | 6 ++- infra/clickhouse/users.d/access.xml | 63 +++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 infra/clickhouse/users.d/access.xml diff --git a/.env.example b/.env.example index 0cb9c2d..55b193b 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,11 @@ CLICKHOUSE_01_HTTP_PORT=28123 CLICKHOUSE_01_TCP_PORT=29000 CLICKHOUSE_02_HTTP_PORT=28124 CLICKHOUSE_02_TCP_PORT=29001 +CLICKHOUSE_CLUSTER_SECRET=cluster-26-secret +CLICKHOUSE_DEFAULT_PASSWORD=default-26-local +CLICKHOUSE_ETL_PASSWORD=etl-26-writer +CLICKHOUSE_BI_PASSWORD=bi-26-reader +CLICKHOUSE_ANALYST_PASSWORD=analyst-26-reader KAFKA_EXTERNAL_PORT=29092 PROMETHEUS_PORT=29090 GRAFANA_PORT=23000 diff --git a/compose.yaml b/compose.yaml index 663cf94..4b7a748 100644 --- a/compose.yaml +++ b/compose.yaml @@ -11,6 +11,10 @@ x-clickhouse-common: &clickhouse-common environment: # Стенд локальный: нодам нужен общий пользователь без пароля для Distributed. CLICKHOUSE_SKIP_USER_SETUP: "1" + CLICKHOUSE_CLUSTER_SECRET: ${CLICKHOUSE_CLUSTER_SECRET:?Скопируйте .env.example в .env} + CLICKHOUSE_ETL_PASSWORD: ${CLICKHOUSE_ETL_PASSWORD:?Скопируйте .env.example в .env} + CLICKHOUSE_BI_PASSWORD: ${CLICKHOUSE_BI_PASSWORD:?Скопируйте .env.example в .env} + CLICKHOUSE_ANALYST_PASSWORD: ${CLICKHOUSE_ANALYST_PASSWORD:?Скопируйте .env.example в .env} depends_on: clickhouse-keeper: condition: service_healthy @@ -120,6 +124,7 @@ services: - ./infra/clickhouse/config.d/cluster.xml:/etc/clickhouse-server/config.d/cluster.xml:ro - ./infra/clickhouse/config.d/prometheus.xml:/etc/clickhouse-server/config.d/prometheus.xml:ro - ./infra/clickhouse/config.d/macros-01.xml:/etc/clickhouse-server/config.d/macros.xml:ro + - ./infra/clickhouse/users.d/access.xml:/etc/clickhouse-server/users.d/access.xml:ro - clickhouse_01_data:/var/lib/clickhouse # Будущее подключение Superset. @@ -133,6 +138,7 @@ services: - ./infra/clickhouse/config.d/cluster.xml:/etc/clickhouse-server/config.d/cluster.xml:ro - ./infra/clickhouse/config.d/prometheus.xml:/etc/clickhouse-server/config.d/prometheus.xml:ro - ./infra/clickhouse/config.d/macros-02.xml:/etc/clickhouse-server/config.d/macros.xml:ro + - ./infra/clickhouse/users.d/access.xml:/etc/clickhouse-server/users.d/access.xml:ro - clickhouse_02_data:/var/lib/clickhouse kafka: diff --git a/docs/adr/0007-clickhouse-access.md b/docs/adr/0007-clickhouse-access.md index d768b1c..151e116 100644 --- a/docs/adr/0007-clickhouse-access.md +++ b/docs/adr/0007-clickhouse-access.md @@ -132,12 +132,16 @@ Postgres и Grafana. Цена выбора известна: объявленн настройки ClickHouse. - Весь DDL репозитория идёт через `IF NOT EXISTS` (файлы `sql/ddl/`). -Осталось проверить при исполнении, и это работа тикета реализации: точная -форма объявления секрета в описании кластера (готового примера в -документации не нашлось); работает ли подстановка из окружения именно для -пароля пользователя, и если нет — пароли лягут в файл настройки прямым -текстом, а README назовёт это вслух; применяются ли на соседнем шарде права -`bi`, а не общей учётки (вывод из колонки `user`, живьём не измерен — -проверка требует создать пользователя); принимает ли ClickHouse права, -выданные на ещё не созданную базу — на момент решения `dds` и `dm` не -существуют. +Проверено на живом стенде 13 августа 2026 года, ClickHouse 26.3.17.56. + +- Секрет кластера принимается внутри `remote_servers` в виде + ``. Запрос от `etl` через обе + ноды выполнился на каждой под пользователем `etl`. +- `from_env` работает у элемента `password`: `etl`, `bi` и `analyst` вошли с + паролями из окружения и получили свои роли. +- При запросе от `bi` через Distributed на второй ноде `system.query_log` + показал `user = bi` и `initial_user = bi`. Значит, на соседнем шарде + применяются права инициатора, а не общей учётной записи. +- Права на отсутствующие базы `dds` и `dm` приняты. До создания баз они видны + в `SHOW GRANTS FOR etl_writer`; временная таблица в `dm` подтвердила право + `bi` на чтение после появления базы. diff --git a/infra/clickhouse/config.d/cluster.xml b/infra/clickhouse/config.d/cluster.xml index 3c32c5f..eddafeb 100644 --- a/infra/clickhouse/config.d/cluster.xml +++ b/infra/clickhouse/config.d/cluster.xml @@ -5,6 +5,11 @@ --> + + true @@ -33,4 +38,3 @@ /clickhouse/task_queue/ddl - diff --git a/infra/clickhouse/users.d/access.xml b/infra/clickhouse/users.d/access.xml new file mode 100644 index 0000000..b4fc45b --- /dev/null +++ b/infra/clickhouse/users.d/access.xml @@ -0,0 +1,63 @@ + + + + + + GRANT SELECT, INSERT, ALTER, CREATE TABLE, CREATE VIEW, DROP TABLE, DROP VIEW ON default.* + GRANT SELECT, INSERT, ALTER, CREATE TABLE, CREATE VIEW, DROP TABLE, DROP VIEW, CREATE DATABASE ON stg.* + GRANT SELECT, INSERT, ALTER, CREATE TABLE, CREATE VIEW, DROP TABLE, DROP VIEW, CREATE DATABASE ON ods.* + GRANT SELECT, INSERT, ALTER, CREATE TABLE, CREATE VIEW, DROP TABLE, DROP VIEW, CREATE DATABASE ON dds.* + GRANT SELECT, INSERT, ALTER, CREATE TABLE, CREATE VIEW, DROP TABLE, DROP VIEW, CREATE DATABASE ON dm.* + GRANT SELECT ON system.* + GRANT CLUSTER ON *.* + GRANT REMOTE ON *.* + + + + + GRANT SELECT ON dds.* + GRANT SELECT ON dm.* + GRANT SELECT ON system.settings + + + + + GRANT SELECT ON stg.* + GRANT SELECT ON ods.* + GRANT SELECT ON dds.* + GRANT SELECT ON dm.* + GRANT SELECT ON system.settings + + + + + + + + default + default + + GRANT etl_writer + + + + + default + default + + GRANT bi_reader + + + + + default + default + + GRANT analyst_reader + + + +