> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-home-button.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ClickHouse Operator 配置指南

> 本指南介绍如何使用 ClickHouse Operator 配置 ClickHouse 和 Keeper 集群。

本指南介绍如何使用该 Operator 配置 ClickHouse 和 Keeper 集群。

<div id="clickhousecluster-configuration">
  ## ClickHouseCluster 配置
</div>

<div id="basic-configuration">
  ### 基本配置
</div>

```yaml theme={null}
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: my-cluster
spec:
  replicas: 3           # 每个分片的副本数
  shards: 2             # 分片数量
  keeperClusterRef:
    name: my-keeper     # 引用 KeeperCluster
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 10Gi
```

<div id="replicas-and-shards">
  ### 副本和分片
</div>

* **副本**：每个分片中的 ClickHouse 实例数 (用于高可用)
* **分片**：水平分片的数量 (用于扩缩容)

```yaml theme={null}
spec:
  replicas: 3  # 默认值：3
  shards: 2    # 默认值：1
```

一个配置为 `replicas: 3`、`shards: 2` 的集群将总共创建 6 个 ClickHouse pod (容器组) 。

<div id="keeper-integration">
  ### Keeper 集成
</div>

每个 ClickHouse 集群都必须引用一个 KeeperCluster，以进行协调：

```yaml theme={null}
spec:
  keeperClusterRef:
    name: my-keeper
    # namespace: keeper-system  # 可选，默认为 ClickHouseCluster 的命名空间
```

当设置了 `keeperClusterRef.namespace` 时，operator 必须同时监听这两个命名空间。如果配置了 `WATCH_NAMESPACE`，请将 ClickHouse 和 Keeper 所在的命名空间都包含在该列表中。

<div id="keepercluster-configuration">
  ## KeeperCluster 配置
</div>

```yaml theme={null}
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
  name: my-keeper
spec:
  replicas: 3  # 必须为奇数：1、3、5、7、9、11、13 或 15
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 5Gi
```

<div id="storage-configuration">
  ## 存储配置
</div>

配置持久化存储：

```yaml theme={null}
spec:
  dataVolumeClaimSpec:
    storageClassName: fast-ssd  # 可选：根据已安装的 CSI 选择合适的存储类名称
    resources:
      requests:
        storage: 100Gi
```

<Note>
  仅当底层存储类支持卷扩容时，Operator 才能修改现有的 PVC。
</Note>

<div id="pod-configuration">
  ## pod (容器组)  配置
</div>

<div id="automatic-topology-spread-and-affinity">
  ### 自动拓扑分散与亲和性
</div>

将 Pod (容器组) 分散到各可用区：

```yaml theme={null}
spec:
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname
```

<Note>
  确保您的 Kubernetes 集群在不同可用区中具备足够的节点，以满足分布约束要求。
</Note>

<div id="manual-configuration">
  ### 手动配置
</div>

可以指定任意的 pod (容器组) 亲和性/反亲和性规则以及拓扑分布约束条件。

```yaml theme={null}
spec:
  podTemplate:
    affinity:
      <your-affinity-rules-here>
    topologySpreadConstraints:
      <your-topology-spread-constraints-here>
```

<div id="see-api-referenceproductskubernetes-operatorreferenceapi-referencepodtemplatespec-for-all-supported-pod-template-options">
  ### 所有受支持的 pod (容器组)  模板选项，请参见 [API 参考文档](/zh/products/kubernetes-operator/reference/api-reference#podtemplatespec)。
</div>

<div id="pod-disruption-budgets">
  ## pod (容器组) 中断预算
</div>

Operator 会为每个集群创建一个 [PodDisruptionBudget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/) (PDB) ，以确保自愿中断 (如节点排空、滚动升级、自动扩缩容驱逐) 不会导致过多 pod (容器组)  下线，从而失去仲裁或影响可用性。

对于拥有多个分片的 ClickHouse 集群，**每个分片都会创建一个 PDB**，这样一个分片中的中断就不会计入另一个分片。

<div id="pdb-defaults">
  ### 默认值
</div>

operator 会根据集群规模选择安全的默认值，因此即使首次执行 `apply`，也能避免意外丢失仲裁。

| 资源                  | 拓扑                     | 默认 PDB                                                                               |
| ------------------- | ---------------------- | ------------------------------------------------------------------------------------ |
| `ClickHouseCluster` | `replicas: 1` (单副本分片)  | `maxUnavailable: 1` — 对于单节点集群，允许中断，这样不会阻塞节点排空                                        |
| `ClickHouseCluster` | `replicas: 2+` (多副本分片) | `minAvailable: 1` — 每个分片至少必须保持 1 个副本在线                                               |
| `KeeperCluster`     | `replicas: 1`          | `maxUnavailable: 1` — 对于单节点集群，允许中断，这样不会阻塞节点排空                                        |
| `KeeperCluster`     | `replicas: 3+`         | `maxUnavailable: replicas/2` — 为 `2F+1` 集群保留 RAFT 仲裁 (3 个副本可容忍 1 个宕机，5 个副本可容忍 2 个宕机) |

对于一个包含 3 个分片且 `replicas: 3` 的 ClickHouseCluster，operator 会创建 3 个 PDB，每个分片 1 个，且每个都设置为 `minAvailable: 1`。

<div id="pdb-overrides">
  ### 覆盖默认设置
</div>

使用 `spec.podDisruptionBudget` 覆盖 `minAvailable` **或** `maxUnavailable` (两者只能指定一个) ：

```yaml theme={null}
spec:
  replicas: 3
  shards: 2
  podDisruptionBudget:
    minAvailable: 2   # 中断期间，每个分片中至少保持 3 个副本中的 2 个正常运行
```

或者使用按百分比设置的 `maxUnavailable` 形式：

```yaml theme={null}
spec:
  replicas: 5
  podDisruptionBudget:
    maxUnavailable: 40%
```

<Warning>
  同时设置 `minAvailable` 和 `maxUnavailable` 会被验证 webhook 拒绝。请选择其一——Kubernetes 本身也不允许同时设置这两项。
</Warning>

你也可以将 [`unhealthyPodEvictionPolicy`](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#unhealthy-pod-eviction-policy) 字段传递到生成的 PDB 中——当你需要允许仍处于 `NotReady` 状态的 pod (容器组) 被驱逐时，这会很有用：

```yaml theme={null}
spec:
  podDisruptionBudget:
    minAvailable: 2
    unhealthyPodEvictionPolicy: AlwaysAllow
```

<div id="pdb-policies">
  ### 策略
</div>

`spec.podDisruptionBudget.policy` 允许你选择 operator 以**多大力度**管理 PDB：

| Policy              | Behavior                                                                        |
| ------------------- | ------------------------------------------------------------------------------- |
| `Enabled` (default) | operator 会在每次 reconcile 时创建并更新 PDB。这是适用于生产环境的安全默认设置。                            |
| `Disabled`          | operator **不会**创建 PDB，并会**删除**所有带有匹配标签的现有 PDB。这适用于开发集群，因为这类集群通常应允许所有自愿中断。       |
| `Ignored`           | operator 既不创建也不删除 PDB。现有 PDB 会保持不变。当 PDB 管理由其他系统 (例如策略准入、GitOps 工具) 接管时，请使用此选项。 |

示例——在开发集群上完全禁用 PDB 管理：

```yaml theme={null}
spec:
  podDisruptionBudget:
    policy: Disabled
```

示例 — 将你手动编写的 PDB 与集群放在一起，并阻止 operator 触碰它：

```yaml theme={null}
spec:
  podDisruptionBudget:
    policy: Ignored
```

<div id="pdb-cluster-wide-disable">
  ### 集群范围内停用
</div>

也可以通过 operator 的 `ENABLE_PDB` 环境变量，在整个集群范围内停用 PDB 管理。设置 `ENABLE_PDB=false` 后，无论 `spec.podDisruptionBudget.policy` 如何，operator 都会跳过 **所有** ClickHouseCluster 和 KeeperCluster 的 PDB reconcile 步骤，并且**完全不监视** `PodDisruptionBudget` 资源。因此，operator 的 ServiceAccount 无需具备 `poddisruptionbudgets.policy/v1` 的 RBAC 权限；当 operator 以受限的 ServiceAccount 运行，且该账户刻意不包含这些权限时，这一点尤其有用。

```yaml theme={null}
# 在 operator 的 Deployment 规格中
env:
- name: ENABLE_PDB
  value: "false"
```

这适用于自行实施中断策略 (例如通过 Gatekeeper / Kyverno) 的环境，并希望将 operator 完全排除在外。

<div id="container-configuration">
  ## 容器配置
</div>

<div id="custom-image">
  ### 自定义镜像
</div>

使用指定的 ClickHouse 镜像：

```yaml theme={null}
spec:
  containerTemplate:
    image:
      repository: clickhouse/clickhouse-server
      tag: "25.12"
    imagePullPolicy: IfNotPresent
```

<div id="container-resources">
  ### 容器资源
</div>

为 ClickHouse 容器配置 CPU 和内存：

```yaml theme={null}
# 默认值
spec:
  containerTemplate:
    resources:
      requests:
        cpu: "250m"
        memory: "256Mi"
      limits:
        cpu: "1"
        memory: "1Gi"
```

<div id="environment-variables">
  ### 环境变量
</div>

添加自定义的环境变量：

```yaml theme={null}
spec:
  containerTemplate:
    env:
    - name: CUSTOM_ENV_VAR
      value: "1"
```

<div id="volume-mounts">
  ### 卷挂载
</div>

添加更多卷挂载：

```yaml theme={null}
spec:
  containerTemplate:
    volumeMounts:
    - name: custom-config
      mountPath: /etc/clickhouse-server/config.d/custom.xml
      subPath: custom.xml
```

<Note>
  可以为同一个 `mountPath` 指定多个卷挂载。
  Operator 会将所有已指定的挂载创建为一个投影卷。
</Note>

<div id="see-api-referenceproductskubernetes-operatorreferenceapi-referencecontainertemplatespec-for-all-supported-container-template-options">
  ### 有关所有受支持的容器模板选项，请参见 [API 参考文档](/zh/products/kubernetes-operator/reference/api-reference#containertemplatespec)。
</div>

<div id="tls-ssl-configuration">
  ## TLS/SSL 配置
</div>

<div id="configure-secure-endpoints">
  ### 配置安全端点
</div>

引用包含 TLS 证书的 Kubernetes Secret，以启用安全端点

```yaml theme={null}
spec:
  settings:
    tls:
      enabled: true
      required: true # 设置此项后，非安全端口将被禁用
      serverCertSecret:
        name: <certificate-secret-name>
```

<div id="ssl-certificate-secret-format">
  ### SSL 证书 Secret 格式
</div>

该 Secret 应包含以下键：

* `tls.crt` - PEM 编码的服务器证书
* `tls.key` - PEM 编码的私钥
* `ca.crt` - PEM 编码的 CA 证书链

<Note>
  此格式兼容由 cert-manager 生成的证书。
</Note>

<div id="clickhouse-keeper-communication-over-tls">
  ### 通过 TLS 进行 ClickHouse-Keeper 通信
</div>

如果 KeeperCluster 启用了 TLS，ClickHouseCluster 会自动使用与 Keeper 节点的安全连接。

ClickHouseCluster 应能够验证 Keeper 节点的证书。
如果 ClickHouseCluster 启用了 TLS，则会使用 `ca.crt` 证书包进行验证；否则，将使用默认的 CA 证书包。

用户可以提供自定义 CA 证书包引用：

```yaml theme={null}
spec:
    settings:
        tls:
          caBundle:
            name: <ca-certificate-secret-name>
            key: <ca-certificate-key>
```

<div id="clickhouse-settings">
  ## ClickHouse 设置
</div>

<div id="default-user-password">
  ### 默认用户密码
</div>

设置默认用户的密码：

```yaml theme={null}
spec:
  settings:
    defaultUserPassword:
      passwordType: <password-type> # 默认值：password
      <secret|configMap>:
        name: <resource name>
        key: <password>
```

<Note>
  不建议使用 ConfigMap 存储明文密码。
</Note>

创建 secret：

```bash theme={null}
kubectl create secret generic clickhouse-password --from-literal=password='your-secure-password'
```

<div id="using-configmap-for-user-passwords">
  #### 使用 ConfigMap 配置用户密码
</div>

您也可以使用 ConfigMap 来设置非敏感的默认密码：

```yaml theme={null}
spec:
  settings:
    defaultUserPassword:
      passwordType: password_sha256_hex
      configMap:
        name: clickhouse-config
        key: default_password
```

<div id="custom-users-in-configuration">
  ### 配置中的自定义用户
</div>

在配置文件中添加其他用户。

为该用户创建 ConfigMap 和 Secret：

```yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: user-config
data:
  reader.yaml: |
    users:
      reader:
        password:
          - '@from_env': READER_PASSWORD
        profile: default
        grants:
          - query: "GRANT SELECT ON *.*"
---
apiVersion: v1
kind: Secret
metadata:
  name: reader-password
data:
  password: "c2VjcmV0LXBhc3N3b3Jk"  # base64("secret-password")

```

向 ClickHouseCluster 添加自定义配置：

```yaml theme={null}
spec:
  podTemplate:
    volumes:
      - name: reader-user
        configMap:
          name: user-config
  containerTemplate:
    env:
      - name: READER_PASSWORD
        valueFrom:
          secretKeyRef:
            name: reader-password
            key: password
    volumeMounts:
      - mountPath: /etc/clickhouse-server/users.d/
        name: reader-user
        readOnly: true
```

<div id="database-sync">
  ### 数据库同步
</div>

为新副本启用数据库自动同步：

```yaml theme={null}
spec:
  settings:
    enableDatabaseSync: true  # 默认值：true
```

启用后，该 Operator 会将 Replicated 表和集成表同步到新副本。

<div id="custom-configuration">
  ## 自定义配置
</div>

<div id="embedded-extra-configuration">
  ### 内嵌额外配置
</div>

无需挂载自定义配置文件，也可以直接指定额外的 ClickHouse 配置选项。

使用 `extraConfig` 添加自定义的 ClickHouse 配置：

```yaml theme={null}
spec:
  settings:
    extraConfig:
      background_pool_size: 20
```

<div id="useful-links">
  #### 有用链接：
</div>

* [YAML 配置示例](/zh/concepts/features/configuration/server-config/configuration-files#example-1)
* [所有服务器设置](/zh/reference/settings/server-settings/settings)

<div id="embedded-extra-users-configuration">
  ### 嵌入式附加用户配置
</div>

你也可以使用 `extraUsersConfig` 指定额外的 ClickHouse 用户配置。这对于直接在集群规范中定义用户、profile、配额和授权非常有用。

```yaml theme={null}
spec:
  settings:
    extraUsersConfig:
      users:
        analyst:
          password:
            - '@from_env': ANALYST_PASSWORD
          profile: "readonly"
          quota: "default"
      profiles:
        readonly:
          readonly: 1
          max_memory_usage: 10000000000
      quotas:
        default:
          interval:
            duration: 3600
            queries: 1000
            errors: 100
```

<Note>
  `extraUsersConfig` 存储在 k8s 的 ConfigMap 对象中。请避免在其中以明文形式存放 secret。
</Note>

<div id="see-documentationconceptsfeaturesconfigurationsettingssettings-users-for-all-supported-clickhouse-users-configuration-options">
  #### 有关所有受支持的 ClickHouse 用户配置选项，请参阅[文档](/zh/concepts/features/configuration/settings/settings-users)。
</div>

<div id="configuration-example">
  ### 配置示例
</div>

完整配置示例：

```yaml theme={null}
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
  name: sample
spec:
  replicas: 3
  dataVolumeClaimSpec:
    storageClassName: <storage-class-name>
    resources:
      requests:
        storage: 10Gi
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname
  containerTemplate:
    resources:
      requests:
        cpu: "2"
        memory: "4Gi"
      limits:
        cpu: "4"
        memory: "8Gi"
  settings:
    tls:
      enabled: true
      required: true
      serverCertSecret:
        name: <keeper-certificate-secret>
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: default-user-password
data:
  # 密钥密码
  password: "..." # 密码的 sha256 十六进制值
---
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: sample
spec:
  replicas: 2
  dataVolumeClaimSpec:
    storageClassName: <storage-class-name>
    resources:
      requests:
        storage: 200Gi
  keeperClusterRef:
    name: sample
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname
  settings:
    tls:
      enabled: true
      required: true
      serverCertSecret:
        name: clickhouse-cert
    defaultUserPassword:
      passwordType: password_sha256_hex
      configMap:
        key: password
        name: default-password
```
