В этом руководстве пошагово показано, как настроить сквозное шифрование кластера ClickHouse: выпустить сертификат с помощью cert-manager, включить TLS в кластере, подключить клиент через защищённые порты и распространить шифрование на трафик координации Keeper.
Руководство носит практический характер. Подробное справочное описание spec.settings.tls по каждому полю см. в
Configuration → TLS/SSL configuration
и в API Reference.
Предварительные требования
- Работающий кластер ClickHouse под управлением оператора (см. Введение).
- Установленный в кластере cert-manager.
- Доступ к пространству имен кластера через
kubectl.
Оператор не генерирует сертификаты самостоятельно — он использует Kubernetes
Secret, который вы предоставляете. cert-manager — рекомендуемый способ создать и
обновлять этот Secret, но подойдет любой инструмент, который записывает Secret в ожидаемом формате.
В каком виде оператор ожидает сертификаты
TLS включается путём указания spec.settings.tls.serverCertSecret на объект Secret,
который содержит серверную пару ключей:
| Ключ Secret | Содержимое | Обязательно |
|---|---|---|
tls.crt |
PEM-кодированный сертификат сервера | Да |
tls.key |
PEM-кодированный закрытый ключ | Да |
Именно такую структуру cert-manager записывает для ресурса Certificate, поэтому
никакого преобразования не требуется. Оператор монтирует пару ключей в каждый под по пути
/etc/clickhouse-server/tls/ и подключает её к конфигурации openSSL в ClickHouse.
Шаг 1 — Инициализируйте CA с помощью cert-manager
Наиболее воспроизводимый вариант настройки — самоподписанный центр сертификации (CA), который затем подписывает сертификат сервера.
Это даёт вам стабильный ca.crt, которому могут доверять клиенты.
# A self-signed issuer used only to mint the CA certificate
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-bootstrap
namespace: <namespace>
spec:
selfSigned: {}
---
# The CA certificate itself
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: clickhouse-ca
namespace: <namespace>
spec:
isCA: true
commonName: clickhouse-ca
secretName: clickhouse-ca
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-bootstrap
kind: Issuer
---
# A CA issuer that signs leaf certificates from the CA above
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: clickhouse-ca-issuer
namespace: <namespace>
spec:
ca:
secretName: clickhouse-caВ продакшне замените самоподписанный bootstrap на реальный центр сертификации (корпоративный CA, Vault, ACME и т. д.). Меняется только Step 2 — конфигурация кластера остается той же.
Шаг 2 — Выпустите сертификат сервера
Запросите конечный сертификат у CA. Значения dnsNames должны охватывать все способы,
которыми клиенты обращаются к подам. Оператор создает один headless Service с именем
<cluster-name>-clickhouse-headless, и каждый под реплики доступен по адресу
<cluster-name>-clickhouse-<shard>-<index>-0.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local.
Подстановочный знак для домена headless Service покрывает все реплики:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: clickhouse-server
namespace: <namespace>
spec:
secretName: clickhouse-cert # <-- the Secret the operator will read
duration: 8760h # 1 year
renewBefore: 720h # rotate 30 days early
issuerRef:
name: clickhouse-ca-issuer
kind: Issuer
dnsNames:
- "*.<cluster-name>-clickhouse-headless.<namespace>.svc"
- "*.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local"
- "localhost"cert-manager создаёт Secret clickhouse-cert с tls.crt, tls.key и
ca.crt и обновляет его до истечения срока действия. Убедитесь, что он существует:
kubectl -n <namespace> get secret clickhouse-cert -o jsonpath='{.data}' | jq 'keys'
# ["ca.crt","tls.crt","tls.key"]Шаг 3 — Включите TLS в кластере
Укажите Secret для кластера:
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
name: <cluster-name>
namespace: <namespace>
spec:
settings:
tls:
enabled: true
required: true # disable the insecure ports entirely
serverCertSecret:
name: clickhouse-certЧто делает оператор
Когда tls.enabled: true, оператор:
- Открывает защищенные порты на каждом поде и в headless Service:
9440(native TLS) и8443(HTTPS). Они добавляются наряду с уже существующими портами. - Монтирует Secret в
/etc/clickhouse-server/tls/и генерирует блок ClickHouseopenSSLсverificationMode: relaxed,disableProtocols: sslv2,sslv3иpreferServerCiphers: true. Это настройки по умолчанию — чтобы переопределить их, см. Настройка параметров TLS.
Если также задать required: true, оператор дополнительно:
- Удаляет незащищенные порты
9000(native) и8123(HTTP) — остаются только TLS-варианты, поэтому клиенты без TLS больше не смогут подключаться. - Переключает liveness probe пода на защищенный native-порт
9440, чтобы проверка работоспособности продолжала работать без plaintext listener.
Шаг 4 — Подключение по TLS
При required: true клиенты должны использовать защищённые порты и доверять CA. Обращайтесь
к конкретному поду реплики через headless Service (или через собственный Service
типа Кластерный IP, если вы его создали).
Собственный протокол (clickhouse-client, порт 9440):
clickhouse-client --secure \
--host <cluster-name>-clickhouse-0-0-0.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local \
--port 9440 \
--ca-certificate /path/to/ca.crt \
--query "SELECT 1"HTTPS (порт 8443):
curl --cacert /path/to/ca.crt \
"https://<cluster-name>-clickhouse-0-0-0.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local:8443/?query=SELECT%201"Получите ca.crt напрямую из объекта Secret для локального тестирования:
kubectl -n <namespace> get secret clickhouse-cert \
-o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crtШифрование трафика Keeper
Включение TLS в кластере ClickHouse не шифрует соединение с Keeper.
Включите TLS для KeeperCluster отдельно — выпустите сертификат для сервиса Keeper
(шаги 1–2 с dnsNames сервиса Keeper) и укажите его:
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
name: <keeper-name>
namespace: <namespace>
spec:
settings:
tls:
enabled: true
required: true
serverCertSecret:
name: keeper-certKeeper использует защищённый клиентский порт 2281. После включения TLS в Keeper кластер
ClickHouse автоматически подключается к нему по TLS — на стороне
ClickHouseCluster не требуется никаких дополнительных настроек. ClickHouse проверяет сертификат Keeper по системному
хранилищу доверенных сертификатов, а также по указанному вами
caBundle.
Собственный набор сертификатов CA
По умолчанию ClickHouse проверяет узлы, к которым он подключается (другие реплики, Keeper, HTTPS-источники словарей, S3, …), по системному хранилищу доверенных сертификатов. Чтобы дополнительно доверять
приватному CA — самоподписанному или внутреннему CA, корневой сертификат которого отсутствует в системном хранилище, —
укажите caBundle:
spec:
settings:
tls:
enabled: true
serverCertSecret:
name: clickhouse-cert
caBundle:
name: <ca-secret-name>
key: ca.crtОператор монтирует этот набор и добавляет его в хранилище доверенных сертификатов клиента
openSSL (caConfig). Системное хранилище доверенных сертификатов продолжает использоваться — ваш собственный CA считается доверенным в
дополнение к публичным корневым сертификатам, поэтому соединения с публичными конечными точками продолжают работать. Для
самоподписанной конфигурации укажите в caBundle ключ ca.crt того же Secret, в который cert-manager
записал сертификат (как в примере cluster_with_ssl).
Настройка параметров TLS
Блок openSSL, который генерирует оператор, — это конфигурация по умолчанию, а не жёсткое ограничение. Он записывается
в основную конфигурацию сервера; всё, что указано в spec.settings.extraConfig, добавляется в
config.d/99-extra-config.yaml, который ClickHouse обрабатывает в последнюю очередь — поэтому он переопределяет
сгенерированные значения.
Чтобы усилить настройки по умолчанию — например, включить строгую проверку peer и повысить
минимальную версию протокола до TLS 1.2, — задайте ключи openSSL.server, которые хотите изменить:
spec:
settings:
extraConfig:
openSSL:
server:
verificationMode: strict
disableProtocols: "sslv2,sslv3,tlsv1,tlsv1_1"Слияние выполняется по каждому ключу: заменяются только те значения, которые вы задаёте, а сгенерированные ключи, которые вы
не указываете (пути к сертификатам, конфигурация CA), сохраняются. Доступные параметры см. в
настройках сервера openSSL,
а сведения о том, как объединяется extraConfig, — в разделе
Configuration → Встроенная дополнительная конфигурация.
Проверка и устранение неполадок
Убедитесь, что защищённые порты доступны в headless Service:
kubectl -n <namespace> get svc <cluster-name>-clickhouse-headless \
-o jsonpath='{.spec.ports[*].name}'
# expect: ... tcp-secure http-secure (and NO tcp/http when required: true)Убедитесь, что сертификат смонтирован в под:
kubectl -n <namespace> exec <pod> -- ls /etc/clickhouse-server/tls/
# clickhouse-server.crt clickhouse-server.key (plus custom-ca.crt when caBundle is set)| Симптом | Вероятная причина |
|---|---|
| Поды не запускаются / ошибка монтирования тома после включения TLS | Указанный Secret отсутствует или не содержит tls.crt/tls.key (или, если задан caBundle, Secret/ключ, на который он ссылается). Оператор не проверяет содержимое Secret'а — отсутствие ключей проявляется как ошибка монтирования тома в поде, а не как отдельное условие status. Проверьте под командой kubectl describe pod. |
| Вебхук отклоняет кластер | Указано required: true без enabled: true или enabled: true без serverCertSecret. |
У клиента ошибка certificate verify failed |
Клиент не доверяет CA. Передайте ca.crt из Secret или проверьте, что dnsNames в сертификате включают хост, к которому вы подключаетесь. |
| Клиент без шифрования внезапно не может подключиться | required: true отключил порты 9000/8123. Переключите клиент на 9440/8443 или задайте required: false, чтобы небезопасные порты оставались открытыми во время миграции. |
См. также
- Конфигурация → Конфигурация TLS/SSL — справочник полей
- Конфигурация →
additionalPorts— зарезервированные порты - Справочник по API → ClusterTLSSpec
- настройки сервера
openSSL— параметры TLS, которые можно переопределить черезextraConfig