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

# ClickHouse 연산자 구성 가이드

> 이 가이드에서는 ClickHouse 연산자를 사용해 ClickHouse 및 Keeper 클러스터를 구성하는 방법을 안내합니다.

이 가이드에서는 ClickHouse 연산자를 사용해 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 파드를 생성합니다.

<div id="keeper-integration">
  ### Keeper 통합
</div>

모든 ClickHouse 클러스터는 클러스터 조정을 위해 KeeperCluster를 참조해야 합니다:

```yaml theme={null}
spec:
  keeperClusterRef:
    name: my-keeper
    # namespace: keeper-system  # 선택 사항, 기본값은 ClickHouseCluster 네임스페이스
```

`keeperClusterRef.namespace`가 설정되면 연산자는 두 네임스페이스를 모두 감시해야 합니다. `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">
  ## 파드 구성
</div>

<div id="automatic-topology-spread-and-affinity">
  ### 토폴로지 분산 및 어피니티 자동 설정
</div>

가용 영역에 걸쳐 파드를 분산합니다:

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

<Note>
  분산 제약 조건을 충족할 수 있도록 Kubernetes 클러스터에 서로 다른 zone에 걸쳐 충분한 수의 노드가 있는지 확인하세요.
</Note>

<div id="manual-configuration">
  ### 수동 구성
</div>

사용자 정의 파드 어피니티/안티어피니티 규칙과 토폴로지 분산 제약 조건을 지정할 수 있습니다.

```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">
  ### 지원되는 모든 파드 템플릿 옵션은 [API 참조](/ko/products/kubernetes-operator/reference/api-reference#podtemplatespec)를 참조하십시오.
</div>

<div id="pod-disruption-budgets">
  ## 파드 중단 예산
</div>

연산자는 자발적 중단(노드 드레인, 롤링 업그레이드, 오토스케일러 축출)으로 인해 정족수(quorum)를 잃거나 가용성을 해칠 만큼 많은 파드가 중단되지 않도록 각 클러스터에 대해 [PodDisruptionBudget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/) (PDB)를 생성합니다.

세그먼트가 2개 이상인 ClickHouse 클러스터에서는 **세그먼트마다 PDB가 하나씩 생성**되므로 한 세그먼트에서 발생한 중단이 다른 세그먼트에 영향을 미치지 않습니다.

<div id="pdb-defaults">
  ### 기본값
</div>

연산자는 클러스터 크기에 따라 안전한 기본값을 선택하므로, 새로 `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개 장애를 허용) |

`replicas: 3`인 3개 세그먼트 ClickHouseCluster의 경우, 연산자는 세그먼트마다 하나씩 총 3개의 PDB를 생성하며, 각각 `minAvailable: 1`로 설정합니다.

<div id="pdb-overrides">
  ### 기본값 덮어쓰기
</div>

`minAvailable` **또는** `maxUnavailable` 중 정확히 하나를 재정의하려면 `spec.podDisruptionBudget`를 사용합니다:

```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`를 동시에 설정하면 유효성 검사 웹훅에서 거부됩니다. 둘 다 함께 허용되지 않으므로 하나만 선택하세요.
</Warning>

[`unhealthyPodEvictionPolicy`](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#unhealthy-pod-eviction-policy) 필드를 생성된 PDB에 전달할 수도 있습니다. 이는 아직 `NotReady` 상태인 파드의 축출(eviction)을 허용해야 할 때 유용합니다:

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

<div id="pdb-policies">
  ### 정책
</div>

`spec.podDisruptionBudget.policy`를 사용하면 연산자가 PDB를 **어느 정도 적극적으로** 관리할지 선택할 수 있습니다.

| Policy              | Behavior                                                                                                    |
| ------------------- | ----------------------------------------------------------------------------------------------------------- |
| `Enabled` (default) | 연산자는 reconcile할 때마다 PDB를 생성하고 업데이트합니다. 운영 환경에서 안전한 기본 설정입니다.                                                |
| `Disabled`          | 연산자는 PDB를 생성하지 **않고**, 일치하는 레이블이 있는 기존 PDB를 **삭제합니다**. 모든 자발적 중단을 허용해야 하는 개발 클러스터에서 유용합니다.                  |
| `Ignored`           | 연산자는 PDB를 생성하지도 삭제하지도 않습니다. 기존 PDB는 그대로 유지됩니다. 다른 시스템(예: 정책 admission, GitOps 도구)에서 PDB 관리를 담당하는 경우 사용하십시오. |

예시 — 개발 클러스터에서 PDB 관리를 완전히 비활성화합니다:

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

예시 — 직접 만든 PDB를 클러스터 옆에 두고 연산자가 이를 건드리지 못하게 하십시오:

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

<div id="pdb-cluster-wide-disable">
  ### 클러스터 전체 비활성화
</div>

PDB 관리는 오퍼레이터의 `ENABLE_PDB` 환경 변수를 통해 클러스터 전체에서 비활성화할 수도 있습니다. `ENABLE_PDB=false`로 설정하면 오퍼레이터는 각 ClickHouseCluster 및 KeeperCluster의 `spec.podDisruptionBudget.policy`와 관계없이 **모든** ClickHouseCluster와 KeeperCluster에 대해 PDB reconcile 단계를 건너뛰고, `PodDisruptionBudget` 리소스는 **전혀 감시하지 않습니다**. 따라서 오퍼레이터의 ServiceAccount에는 `poddisruptionbudgets.policy/v1`에 대한 RBAC 권한이 필요하지 않으며, 이는 해당 권한을 의도적으로 제외한 제한된 ServiceAccount로 오퍼레이터를 실행할 때 유용합니다.

```yaml theme={null}
# operator 배포 스펙 내에서
env:
- name: ENABLE_PDB
  value: "false"
```

이는 자체 중단 정책(예: Gatekeeper / Kyverno 사용)을 적용하고 연산자를 이 과정에서 완전히 배제하려는 환경을 위한 것입니다.

<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 참조](/ko/products/kubernetes-operator/reference/api-reference#containertemplatespec)에서 확인하십시오.
</div>

<div id="tls-ssl-configuration">
  ## TLS/SSL 구성
</div>

<div id="configure-secure-endpoints">
  ### 보안 endpoint 구성
</div>

TLS 인증서가 포함된 Kubernetes 시크릿을 참조하도록 설정하여 보안 endpoint를 활성화합니다

```yaml theme={null}
spec:
  settings:
    tls:
      enabled: true
      required: true # 설정 시 비보안 포트가 비활성화됩니다
      serverCertSecret:
        name: <certificate-secret-name>
```

<div id="ssl-certificate-secret-format">
  ### SSL 인증서 시크릿 포맷
</div>

시크릿에는 다음 키가 포함되어 있어야 합니다:

* `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 노드에 대한 보안 연결(connection)을 사용합니다.

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>

시크릿을 생성하세요:

```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과 시크릿을 생성합니다:

```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 구성 예시](/ko/concepts/features/configuration/server-config/configuration-files#example-1)
* [모든 서버 설정](/ko/reference/settings/server-settings/settings)

<div id="embedded-extra-users-configuration">
  ### 내장된 추가 사용자 구성
</div>

`extraUsersConfig`를 사용해 추가 ClickHouse 사용자 구성을 지정할 수도 있습니다. 이는 클러스터 사양에서 사용자, 프로필, 쿼터, 권한 부여를 직접 정의할 때 유용합니다.

```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 객체에 저장됩니다. 여기에 평문 시크릿을 저장하지 마십시오.
</Note>

<div id="see-documentationconceptsfeaturesconfigurationsettingssettings-users-for-all-supported-clickhouse-users-configuration-options">
  #### 지원되는 모든 ClickHouse 사용자 구성 옵션은 [문서](/ko/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 hex 값
---
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
```
