> ## 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.

# Guia de configuração do ClickHouse Operator

> Este guia explica como configurar clusters do ClickHouse e do Keeper com o ClickHouse operador.

Este guia explica como configurar clusters do ClickHouse e do Keeper usando o operador.

<div id="clickhousecluster-configuration">
  ## Configuração do ClickHouseCluster
</div>

<div id="basic-configuration">
  ### Configuração básica
</div>

```yaml theme={null}
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: my-cluster
spec:
  replicas: 3           # Número de réplicas por shard
  shards: 2             # Número de shards
  keeperClusterRef:
    name: my-keeper     # Referência ao KeeperCluster
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 10Gi
```

<div id="replicas-and-shards">
  ### Réplicas e shards
</div>

* **Réplicas**: Número de instâncias do ClickHouse em cada shard (para alta disponibilidade)
* **Shards**: Número de partições horizontais (para escalabilidade)

```yaml theme={null}
spec:
  replicas: 3  # Padrão: 3
  shards: 2    # Padrão: 1
```

Um cluster com `replicas: 3` e `shards: 2` criará 6 pods do ClickHouse ao todo.

<div id="keeper-integration">
  ### Integração com o Keeper
</div>

Todo cluster do ClickHouse deve fazer referência a um KeeperCluster para coordenação:

```yaml theme={null}
spec:
  keeperClusterRef:
    name: my-keeper
    # namespace: keeper-system  # Opcional, o padrão é o espaço de nomes do ClickHouseCluster
```

Quando `keeperClusterRef.namespace` estiver definido, o operador deverá monitorar ambos os espaços de nomes. Se `WATCH_NAMESPACE` estiver configurado, inclua os espaços de nomes do ClickHouse e do Keeper nessa lista.

<div id="keepercluster-configuration">
  ## Configuração do KeeperCluster
</div>

```yaml theme={null}
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
  name: my-keeper
spec:
  replicas: 3  # Deve ser ímpar: 1, 3, 5, 7, 9, 11, 13 ou 15
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 5Gi
```

<div id="storage-configuration">
  ## Configuração de armazenamento
</div>

Configure o armazenamento persistente:

```yaml theme={null}
spec:
  dataVolumeClaimSpec:
    storageClassName: fast-ssd  # Opcional: considere sua classe de armazenamento com base no CSI instalado
    resources:
      requests:
        storage: 100Gi
```

<Note>
  O Operator só pode modificar um PVC existente se a classe de armazenamento subjacente oferecer suporte à expansão de volume.
</Note>

<div id="pod-configuration">
  ## Configuração do pod do Kubernetes
</div>

<div id="automatic-topology-spread-and-affinity">
  ### Distribuição automática por topologia e afinidade
</div>

Distribua os pods entre zonas de disponibilidade:

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

<Note>
  Garanta que seu cluster do Kubernetes tenha nós suficientes em zonas diferentes para atender às restrições de distribuição.
</Note>

<div id="manual-configuration">
  ### Configuração manual
</div>

É possível especificar regras arbitrárias de afinidade/anti-afinidade entre pods do Kubernetes e restrições de distribuição de topologia.

```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">
  ### Consulte a [Referência da API](/pt-BR/products/kubernetes-operator/reference/api-reference#podtemplatespec) para ver todas as opções de template de pod do Kubernetes compatíveis.
</div>

<div id="pod-disruption-budgets">
  ## Orçamentos de interrupção de pods
</div>

O operador cria um [PodDisruptionBudget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/) (PDB) para cada cluster, para que interrupções voluntárias — drenagens de nós, atualizações graduais e evicções do autoscaler — não possam derrubar pods suficientes a ponto de causar perda de quórum ou comprometer a disponibilidade.

Para clusters do ClickHouse com mais de um shard, **é criado um PDB por shard** para que uma interrupção em um shard não seja contabilizada contra outro.

<div id="pdb-defaults">
  ### Valores padrão
</div>

O operador escolhe valores padrão seguros com base no tamanho do cluster para que um novo `apply` já proteja contra perda acidental de quórum.

| Recurso             | Topologia                                   | PDB padrão                                                                                                                                         |
| ------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ClickHouseCluster` | `replicas: 1` (shard com uma única réplica) | `maxUnavailable: 1` — a interrupção é permitida em um cluster de nó único para que a drenagem de nós não seja bloqueada                            |
| `ClickHouseCluster` | `replicas: 2+` (shard com várias réplicas)  | `minAvailable: 1` — pelo menos uma réplica por shard deve permanecer disponível                                                                    |
| `KeeperCluster`     | `replicas: 1`                               | `maxUnavailable: 1` — a interrupção é permitida em um cluster de nó único para que a drenagem de nós não seja bloqueada                            |
| `KeeperCluster`     | `replicas: 3+`                              | `maxUnavailable: replicas/2` — preserva o quórum do RAFT para um cluster `2F+1` (3 réplicas toleram 1 fora do ar, 5 réplicas toleram 2 fora do ar) |

Para um ClickHouseCluster com 3 shards e `replicas: 3`, o operador cria três PDBs, um por shard, cada um com `minAvailable: 1`.

<div id="pdb-overrides">
  ### Substituindo os padrões
</div>

Use `spec.podDisruptionBudget` para substituir `minAvailable` **ou** `maxUnavailable` (exatamente um):

```yaml theme={null}
spec:
  replicas: 3
  shards: 2
  podDisruptionBudget:
    minAvailable: 2   # mantém pelo menos 2 das 3 réplicas em cada shard ativas durante uma interrupção
```

Ou no formato `maxUnavailable`, com uma porcentagem:

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

<Warning>
  Definir `minAvailable` e `maxUnavailable` ao mesmo tempo é rejeitado pelo webhook de validação. Escolha um deles — o próprio Kubernetes também não permite os dois.
</Warning>

Você também pode passar o campo [`unhealthyPodEvictionPolicy`](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#unhealthy-pod-eviction-policy) para o PDB gerado — útil quando precisar permitir a evicção de pods que ainda estão em `NotReady`:

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

<div id="pdb-policies">
  ### Políticas
</div>

`spec.podDisruptionBudget.policy` permite escolher **com que nível de rigor** o operador gerencia os PDBs:

| Policy              | Behavior                                                                                                                                                                                                       |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Enabled` (default) | O operador cria e atualiza o PDB em toda reconciliação. Esse é o padrão seguro para produção.                                                                                                                  |
| `Disabled`          | O operador **não** cria PDBs e **exclui** quaisquer PDBs existentes com rótulos correspondentes. Útil para clusters de desenvolvimento em que toda interrupção voluntária deve ser permitida.                  |
| `Ignored`           | O operador não cria nem exclui PDBs. Os PDBs existentes são mantidos como estão. Use esta opção quando outro sistema (por exemplo, admissão de políticas ou uma ferramenta GitOps) gerencia os PDBs para você. |

Exemplo — desative completamente o gerenciamento de PDBs em um cluster de desenvolvimento:

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

Exemplo — mantenha seu PDB criado manualmente junto ao cluster e impeça que o operador interfira nele:

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

<div id="pdb-cluster-wide-disable">
  ### Desativação em nível de cluster
</div>

O gerenciamento de PDB também pode ser desativado em nível de cluster por meio da variável de ambiente `ENABLE_PDB` do operator. Com `ENABLE_PDB=false`, o operator ignora a etapa de reconciliação de PDB para **todos os** ClickHouseCluster e KeeperCluster, independentemente de `spec.podDisruptionBudget.policy`, e **não monitora** recursos `PodDisruptionBudget` de forma alguma. Portanto, o ServiceAccount do operator não precisa de permissões de RBAC em `poddisruptionbudgets.policy/v1`, o que é útil ao executar o operator com um ServiceAccount restrito que omite essas permissões intencionalmente.

```yaml theme={null}
# na spec de Implantação do operador
env:
- name: ENABLE_PDB
  value: "false"
```

Isto se destina a ambientes que implementam suas próprias políticas de interrupção (por exemplo, por meio do Gatekeeper / Kyverno) e querem deixar o operator totalmente fora desse processo.

<div id="container-configuration">
  ## Configuração do contêiner
</div>

<div id="custom-image">
  ### Imagem personalizada
</div>

Use uma imagem específica do ClickHouse:

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

<div id="container-resources">
  ### Recursos de contêiner
</div>

Configure CPU e memória para os contêineres do ClickHouse:

```yaml theme={null}
# valores padrão
spec:
  containerTemplate:
    resources:
      requests:
        cpu: "250m"
        memory: "256Mi"
      limits:
        cpu: "1"
        memory: "1Gi"
```

<div id="environment-variables">
  ### Variáveis de ambiente
</div>

Adicione variáveis de ambiente personalizadas:

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

<div id="volume-mounts">
  ### Montagem de volumes
</div>

Adicione montagens adicionais de volumes:

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

<Note>
  É permitido especificar várias montagens de volume no mesmo `mountPath`.
  O Operator criará um volume projetado com todas as montagens especificadas.
</Note>

<div id="see-api-referenceproductskubernetes-operatorreferenceapi-referencecontainertemplatespec-for-all-supported-container-template-options">
  ### Consulte a [Referência da API](/pt-BR/products/kubernetes-operator/reference/api-reference#containertemplatespec) para ver todas as opções de template de contêiner suportadas.
</div>

<div id="tls-ssl-configuration">
  ## Configuração de TLS/SSL
</div>

<div id="configure-secure-endpoints">
  ### Configure endpoints seguros
</div>

Passe uma referência a um Secret do Kubernetes que contenha certificados TLS para ativar endpoints seguros

```yaml theme={null}
spec:
  settings:
    tls:
      enabled: true
      required: true # Portas inseguras são desativadas se definido
      serverCertSecret:
        name: <certificate-secret-name>
```

<div id="ssl-certificate-secret-format">
  ### Formato do Secret de certificado SSL
</div>

Espera-se que o Secret contenha as seguintes chaves:

* `tls.crt` - certificado do servidor codificado em PEM
* `tls.key` - chave privada codificada em PEM
* `ca.crt` - cadeia de certificados da CA codificada em PEM

<Note>
  Esse formato é compatível com certificados gerados pelo cert-manager.
</Note>

<div id="clickhouse-keeper-communication-over-tls">
  ### Comunicação entre ClickHouse e Keeper via TLS
</div>

Se o KeeperCluster tiver TLS habilitado, o ClickHouseCluster usará automaticamente uma conexão segura com os nós do Keeper.

O ClickHouseCluster deve conseguir verificar os certificados dos nós do Keeper.
Se o ClickHouseCluster tiver TLS habilitado, ele usará o bundle `ca.crt` para a verificação. Caso contrário, será usado o bundle de CA padrão.

O usuário pode fornecer uma referência para um bundle de CA personalizado:

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

<div id="clickhouse-settings">
  ## Configurações do ClickHouse
</div>

<div id="default-user-password">
  ### Senha padrão do usuário
</div>

Defina a senha do usuário padrão:

```yaml theme={null}
spec:
  settings:
    defaultUserPassword:
      passwordType: <password-type> # Padrão: password
      <secret|configMap>:
        name: <resource name>
        key: <password>
```

<Note>
  Não é recomendável usar ConfigMap para armazenar senhas em texto simples.
</Note>

Crie o Secret:

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

<div id="using-configmap-for-user-passwords">
  #### Usando ConfigMap para senhas de usuários
</div>

Você também pode usar o ConfigMap para senhas padrão não sensíveis:

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

<div id="custom-users-in-configuration">
  ### Usuários personalizados na configuração
</div>

Configure usuários adicionais em arquivos de configuração.

Crie um ConfigMap e um Secret para o usuário:

```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")

```

Adicione uma configuração personalizada ao 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">
  ### Sincronização do banco de dados
</div>

Ative a sincronização automática do banco de dados para novas réplicas:

```yaml theme={null}
spec:
  settings:
    enableDatabaseSync: true  # Padrão: true
```

Quando ativado, o operator sincroniza as tabelas Replicated e de integração para novas réplicas.

<div id="custom-configuration">
  ## Configuração personalizada
</div>

<div id="embedded-extra-configuration">
  ### Configuração adicional embutida
</div>

Em vez de montar arquivos de configuração personalizados, você pode especificar diretamente opções adicionais de configuração do ClickHouse.

Adicione uma configuração personalizada do ClickHouse usando `extraConfig`:

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

<div id="useful-links">
  #### Links úteis:
</div>

* [Exemplos de configuração em YAML](/pt-BR/concepts/features/configuration/server-config/configuration-files#example-1)
* [Todas as configurações do servidor](/pt-BR/reference/settings/server-settings/settings)

<div id="embedded-extra-users-configuration">
  ### Configuração embutida de usuários adicionais
</div>

Você também pode especificar uma configuração adicional de usuários do ClickHouse usando `extraUsersConfig`. Isso é útil para definir usuários, perfis, quotas e permissões diretamente na especificação do cluster.

```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>
  O `extraUsersConfig` é armazenado em um objeto ConfigMap do k8s. Evite armazenar segredos em texto puro nele.
</Note>

<div id="see-documentationconceptsfeaturesconfigurationsettingssettings-users-for-all-supported-clickhouse-users-configuration-options">
  #### Consulte a [documentação](/pt-BR/concepts/features/configuration/settings/settings-users) para ver todas as opções de configuração de usuários do ClickHouse suportadas.
</div>

<div id="configuration-example">
  ### Exemplo de configuração
</div>

Exemplo completo de configuração:

```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:
  # senha-secreta
  password: "..." # sha256 hex da senha
---
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
```
