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

ClickHouseCluster 구성

기본 구성

레플리카와 세그먼트

  • 레플리카: 세그먼트당 ClickHouse 인스턴스 수(고가용성을 위해)
  • 세그먼트: 수평 파티션 수(스케일링을 위해)
replicas: 3shards: 2로 구성된 클러스터는 총 6개의 ClickHouse 파드를 생성합니다.

Keeper 통합

모든 ClickHouse 클러스터는 클러스터 조정을 위해 KeeperCluster를 참조해야 합니다:
keeperClusterRef.namespace가 설정되면 연산자는 두 네임스페이스를 모두 감시해야 합니다. WATCH_NAMESPACE가 구성되어 있다면 해당 목록에 ClickHouse와 Keeper 네임스페이스를 모두 포함하십시오.

KeeperCluster 구성

저장소 구성

표준 Kubernetes PersistentVolumeClaimSpecdataVolumeClaimSpec을 사용해 영구 저장소를 구성합니다. 연산자는 이를 데이터 경로 /var/lib/clickhouse에 마운트되는 레플리카별 PersistentVolumeClaim으로 변환합니다:
연산자는 사용 중인 스토리지 클래스가 볼륨 확장을 지원하는 경우에만 기존 PVC를 수정할 수 있습니다.
멀티 디스크(JBOD) 레이아웃에서 추가 디스크를 연결하는 방법, 영구 볼륨 없이 실행하는 방법, 용량 확장, 사용자 지정 저장소 정책, 그리고 생성 후 변경할 수 없는 항목에 대한 규칙은 전용 Storage and volumes guide에서 다룹니다.

클러스터 도메인

spec.clusterDomain은 operator가 ClickHouse 서버 구성에 기록하는 정규화된 파드 호스트 이름을 생성할 때 사용하는 Kubernetes DNS 접미사를 설정합니다. 기본값은 cluster.local이며, ClickHouseClusterKeeperCluster 둘 다에 있습니다.
연산자는 헤드리스 Service를 통해 모든 파드에 <pod>.<headless-service>.<namespace>.svc.<clusterDomain> 형식으로 접근합니다. 이 접미사는 생성된 구성의 두 부분에 반영됩니다:
  • ClickHouseCluster에서는 이 값이 remote_servers의 레플리카 호스트 이름에 사용됩니다 (Distributed 쿼리와 레플리카 간 쿼리용).
  • KeeperCluster에서는 이 값으로 ClickHouse가 조정에 사용하는 Keeper 노드 호스트 이름을 구성합니다.
클러스터의 큐블릿cluster.local이 아닌 --cluster-domain으로 실행되는 경우에만 이 값을 재정의하십시오. 값이 실제 클러스터 도메인과 일치하지 않으면 ClickHouse가 Keeper 및 레플리카 호스트 이름을 해석할 수 없어 조정과 Distributed 쿼리가 DNS 해석 오류로 실패합니다. 참조 대상인 ClickHouseClusterKeeperCluster동일한 값을 설정하십시오.

멀티 디스크(JBOD) 스토리지

additionalVolumeClaimTemplates는 사용에 필요한 프라이머리 dataVolumeClaimSpec에 더해 각 ClickHouse 레플리카에 추가 디스크를 연결합니다. 각 항목은 PVC Template, 즉 metadata.name과 PVC spec으로 이루어집니다. 디스크는 프라이머리 데이터 디스크와 동일한 방식으로 StatefulSet volumeClaimTemplates로 reconcile되므로, StatefulSet 컨트롤러가 레플리카마다 <name>-<statefulset>-0 형식의 이름을 가진 PVC를 하나씩 생성하고 유지합니다.
연산자는 각 추가 볼륨을 /var/lib/clickhouse/disks/<name>에 마운트하고, 생성된 ClickHouse 스토리지 구성에 추가합니다. 이름에 포함된 하이픈은 ClickHouse 디스크 식별자에서 밑줄로 바뀌지만, 마운트 경로에는 원래 이름이 그대로 유지됩니다. 프라이머리 데이터 디스크와 모든 추가 디스크는 default 스토리지 정책의 단일 볼륨에 함께 배치되므로, ClickHouse는 새 데이터 파트를 이들 전체에 라운드 로빈 방식으로 분산합니다. 사용 가능한 용량은 모든 디스크 용량의 합이며, 자체 storage_policy를 설정하지 않은 모든 테이블(system.* 테이블 포함)은 이 통합된 디스크 집합을 사용합니다.
PVC 이름은 ^[a-z]([-a-z0-9]*[a-z0-9])?$ 패턴과 일치해야 하며, 프라이머리 데이터 볼륨 이름과 충돌해서는 안 됩니다. 프라이머리 데이터 디스크와 마찬가지로 추가 디스크 집합도 생성 시점에 고정되며, 생성 후에는 항목의 추가, 제거, 이름 변경이 허용되지 않습니다. 추가 PVC는 프라이머리 데이터 디스크와 마찬가지로 클러스터를 삭제해도 유지됩니다. 기존 항목의 스토리지 크기는 StorageClass가 확장을 지원하는 경우 늘릴 수 있습니다.

클러스터 도메인

spec.clusterDomain은 연산자가 ClickHouse 서버 구성에 기록하는 정규화된 파드 호스트 이름을 생성할 때 사용하는 Kubernetes DNS 접미사를 설정합니다. 기본값은 cluster.local이며, ClickHouseClusterKeeperCluster 둘 다에서 사용할 수 있습니다.
연산자는 헤드리스 Service를 통해 모든 파드에 <pod>.<headless-service>.<namespace>.svc.<clusterDomain> 형식으로 접근합니다. 이 접미사는 생성된 구성의 두 부분에 사용됩니다.
  • ClickHouseCluster에서는 이 값이 remote_servers의 레플리카 호스트 이름에 사용됩니다 (Distributed 쿼리 및 레플리카 간 통신).
  • KeeperCluster에서는 이 값을 바탕으로 ClickHouse가 조정에 사용하는 Keeper 노드 호스트 이름을 구성합니다.
클러스터의 큐블릿cluster.local이 아닌 --cluster-domain으로 실행되는 경우에만 이를 재정의하십시오. 값이 실제 클러스터 도메인과 일치하지 않으면 ClickHouse는 Keeper 및 레플리카 호스트 이름을 확인할 수 없으므로, 조정과 Distributed 쿼리가 DNS 해석 오류로 실패합니다. 참조되는 ClickHouseClusterKeeperCluster동일한 값을 설정하십시오.

파드 구성

토폴로지 분산 및 어피니티 자동 설정

가용 영역에 걸쳐 파드를 분산합니다:
분산 제약 조건을 충족할 수 있도록 Kubernetes 클러스터에 서로 다른 zone에 걸쳐 충분한 수의 노드가 있는지 확인하세요.

수동 구성

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

지원되는 모든 파드 템플릿 옵션은 API 참조를 참조하십시오.

파드 중단 예산

연산자는 자발적 중단(노드 드레인, 롤링 업그레이드, 오토스케일러 축출)으로 인해 정족수(quorum)를 잃거나 가용성을 해칠 만큼 많은 파드가 중단되지 않도록 각 클러스터에 대해 PodDisruptionBudget (PDB)를 생성합니다. 세그먼트가 2개 이상인 ClickHouse 클러스터에서는 세그먼트마다 PDB가 하나씩 생성되므로 한 세그먼트에서 발생한 중단이 다른 세그먼트에 영향을 미치지 않습니다.

기본값

연산자는 클러스터 크기에 따라 안전한 기본값을 선택하므로, 새로 apply해도 우발적인 정족수 손실을 방지할 수 있습니다. replicas: 3인 3개 세그먼트 ClickHouseCluster의 경우, 연산자는 세그먼트마다 하나씩 총 3개의 PDB를 생성하며, 각각 minAvailable: 1로 설정합니다.

기본값 덮어쓰기

minAvailable 또는 maxUnavailable 중 정확히 하나를 재정의하려면 spec.podDisruptionBudget를 사용합니다:
또는 백분율을 지정하는 maxUnavailable 형식:
minAvailablemaxUnavailable를 동시에 설정하면 유효성 검사 웹훅에서 거부됩니다. 둘 다 함께 허용되지 않으므로 하나만 선택하세요.
unhealthyPodEvictionPolicy 필드를 생성된 PDB에 전달할 수도 있습니다. 이는 아직 NotReady 상태인 파드의 축출(eviction)을 허용해야 할 때 유용합니다:

정책

spec.podDisruptionBudget.policy를 사용하면 연산자가 PDB를 어느 정도 적극적으로 관리할지 선택할 수 있습니다. 예시 — 개발 클러스터에서 PDB 관리를 완전히 비활성화합니다:
예시 — 직접 만든 PDB를 클러스터 옆에 두고 연산자가 이를 건드리지 못하게 하십시오:

클러스터 전체 비활성화

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

컨테이너 구성

사용자 지정 이미지

특정 ClickHouse 이미지를 사용하세요:

컨테이너 리소스

ClickHouse 컨테이너의 CPU와 메모리를 설정합니다:

환경 변수

사용자 환경 변수를 추가합니다:

볼륨 마운트

추가 볼륨 마운트를 설정합니다:
동일한 mountPath에 여러 볼륨 마운트를 지정할 수 있습니다. Operator는 지정된 모든 마운트를 포함하는 프로젝티드 볼륨을 생성합니다.

지원되는 모든 컨테이너 템플릿 옵션은 API 참조에서 확인하십시오.

TLS/SSL 구성

보안 endpoint 구성

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

SSL 인증서 시크릿 포맷

시크릿에는 서버 키 쌍이 포함되어 있어야 합니다:
  • tls.crt - PEM으로 인코딩된 서버 인증서
  • tls.key - PEM으로 인코딩된 개인 키
이 포맷은 cert-manager에서 생성한 인증서와 호환됩니다.

TLS를 통한 ClickHouse-Keeper 통신

KeeperCluster에서 TLS가 활성화되어 있으면 ClickHouseCluster는 자동으로 Keeper 노드에 대한 보안 연결(connection)을 사용합니다. ClickHouseCluster는 시스템 신뢰 저장소와 구성한 모든 caBundle을 기준으로 Keeper 노드 인증서를 검증합니다. 비공개 CA(예: 자체 서명 또는 내부 CA)를 신뢰하려면 사용자 지정 CA 번들 참조를 제공하십시오:

외부 시크릿

기본적으로 연산자는 클러스터의 내부 자격 증명(interserver password, management password, Keeper 아이덴티티, cluster secret, named-collections key)이 포함된 시크릿을 생성하고 관리합니다. 이 시크릿은 클러스터 이름으로 생성되며 클러스터의 네임스페이스에 위치합니다. 이러한 자격 증명을 직접 관리하려는 경우(예: HashiCorp Vault, AWS Secrets Manager 또는 External Secrets Operator에서 가져오는 경우) spec.externalSecret을 사용해 기존에 생성된 시크릿을 연산자가 참조하도록 지정하십시오:
참조된 시크릿은 ClickHouseCluster와 같은 네임스페이스에 있어야 합니다. 연산자는 직접 생성하지 않은 시크릿은 절대 삭제하지 않습니다.

필수 키

시크릿에는 다음 키가 포함되어야 합니다: 전체 시크릿은 다음과 같습니다:

정책: Observe와 Manage

spec.externalSecret.policy는 필수 키가 누락되었을 때 연산자가 어떻게 처리할지를 제어합니다.
policy: Manage를 사용하더라도 시크릿은 해당 네임스페이스에 이미 존재해야 합니다. 연산자는 시크릿 자체를 생성하지 않고, 기존 시크릿에 생성된 키만 기록합니다. 참조된 시크릿이 없으면 정책과 관계없이 ExternalSecretNotFound 사유로 리컨실리에이션이 차단됩니다.
외부 시스템(Vault, ESO, sealed-secrets, GitOps)이 신뢰할 수 있는 원본(source of truth)이고, 구성 오류가 있을 때 연산자가 명확하게 실패하도록 하려면 Observe를 선택하십시오. 자체적으로 초기 설정을 진행하면서도 시크릿 객체 자체의 소유권은 유지하려면(예: 백업 목적) Manage를 선택하십시오.

상태 조건과 문제 해결

연산자는 ClickHouseCluster.status.conditionsExternalSecretValid 조건을 표시합니다. 리컨실리에이션이 멈춘 것처럼 보이면 이 조건을 확인하십시오:
가능한 원인: 시크릿이 유효하지 않은 동안 연산자는 리컨실리에이션을 다시 큐에 넣습니다. 따라서 누락된 키를 추가하면 다음 reconcile 시 자동으로 반영되므로 파드를 재시작할 필요가 없습니다.
필요한 키 집합은 실행 중인 ClickHouse 버전에 따라 달라집니다. named-collections-key는 연산자의 version probe가 ClickHouse 25.12 이상을 감지한 경우에만 검증됩니다. 이전 버전에서는 해당 키가 시크릿에 없을 수 있습니다.

추가 포트

오퍼레이터는 모든 ClickHouse 파드와 해당 헤드리스 Service에 고정된 포트 집합을 노출합니다: 8123 HTTP, 9000 네이티브, 9009 interserver, 9001 management, 9363 Prometheus 메트릭, 그리고 TLS가 활성화된 경우 8443/9440의 TLS 포트도 함께 노출됩니다. ClickHouse가 MySQL, PostgreSQL, gRPC 또는 사용자 지정 포트 같은 추가 프로토콜을 수신하도록 하려면 spec.additionalPorts에 선언하십시오:
연산자는 해당 포트를 파드의 containerPorts와 헤드리스 Service에 추가합니다. 전체 예시는 examples/custom_protocols.yaml에 있습니다.
additionalPorts는 Kubernetes 측에서만 포트를 엽니다. ClickHouse 서버가 해당 포트에서 수신 대기하도록 구성하지는 않습니다. spec.settings.extraConfig.protocols에서 해당 protocol도 활성화해야 합니다. 그렇지 않으면 Service에서는 포트가 열려 있어도 파드 내부에서는 아무것도 응답하지 않습니다.

종단 간 예시: MySQL wire protocol

포트 9004에서 MySQL wire protocol로 ClickHouse를 노출하려면:
적용 후 클러스터 내부에서 확인하십시오:

필드 제약 조건

예약된 포트 및 이름

유효성 검사 웹큅은 연산자가 자체적으로 바인딩하는 포트와 충돌할 수 있는 additionalPorts 항목을 거부합니다. 모든 TLS 관련 포트는 예외 없이 예약되므로, 나중에 spec.settings.tls.enabled를 활성화하더라도 이전에 유효했던 클러스터가 손상되지 않습니다. 다음 이름도 거부됩니다. 이는 연산자의 내부 프로토콜 유형 식별자이며, 사람이 읽기 쉬운 별칭은 아닙니다. 거부된 요청은 다음과 같은 오류를 반환합니다:

버전 프로브 및 업그레이드 채널

연산자는 클러스터 버전과 관련해 서로 독립적인 두 가지 작업을 수행합니다:
  1. 버전 보고ClickHouseCluster의 경우 Kubernetes Job이 컨테이너 이미지를 한 번 실행해 현재 실행 중인 ClickHouse 버전을 확인하고, KeeperCluster의 경우 연산자가 실행 중인 레플리카에서 서버가 보고한 버전을 읽습니다. 확인된 버전은 .status.version에 기록되며, 다른 리컨실리에이션 단계에서 사용됩니다(예: External Secret named-collections 키는 ClickHouse 25.12부터만 필요합니다).
  2. 업그레이드 채널 — 공개 ClickHouse 릴리스 피드(https://clickhouse.com/data/version_date.tsv)를 주기적으로 확인합니다. 연산자는 VersionUpgraded 상태 조건을 통해 더 최신 버전을 사용할 수 있는지 보고합니다. 연산자가 자체적으로 클러스터를 업그레이드하지는 않으며, image tag는 사용자가 직접 제어합니다.

릴리스 채널 선택

spec.upgradeChannel은 연산자가 비교 대상으로 삼을 업스트림 릴리스 집합을 선택합니다. 동일한 필드는 ClickHouseClusterKeeperCluster 모두에 있습니다.
허용되는 값(CRD가 패턴 ^(lts|stable|\d+\.\d+)?$로 검증함): 프로덕션 환경에서는 채널을 명시적인 <major>.<minor>(예: 25.8)에 고정하는 방식을 일반적으로 권장합니다. 이렇게 하면 클러스터가 의도한 major 릴리스 라인에 고정되며, 어떤 레플리카가 다른 major로 벗어나는 경우 연산자가 WrongReleaseChannel 경고를 표시할 수 있습니다. 이는 특히 image가 사람이 읽기 쉬운 태그가 아니라 다이제스트(@sha256:...)로 참조될 때 중요합니다. 기본 empty 값은 major 버전 점프가 문제가 되지 않는 개발 클러스터에서는 적절합니다.

상태 조건

프로브 및 업그레이드 확인 결과는 다음 두 조건에 반영됩니다: 다음으로 확인할 수 있습니다:

버전 프로브 Job 재정의

이는 ClickHouseCluster에만 적용됩니다. KeeperCluster는 더 이상 version-probe Job을 실행하지 않습니다. 대신 버전은 실행 중인 Keeper 레플리카에서 직접 읽어 오므로 spec.versionProbeTemplate은 더 이상 사용이 권장되지 않으며 여기서는 아무런 효과가 없습니다. 프로브는 일반적인 Kubernetes Job으로 구현됩니다. 클러스터에 특정 Tolerations, 노드 셀렉터, 보안 컨텍스트를 요구하는 admission policy가 있거나 완료된 probe Job이 남아 있는 시간을 제한하려는 경우, spec.versionProbeTemplate을 통해 템플릿을 재정의하십시오:
컨테이너 이름 version-probe는 연산자의 기본값입니다 — containers: 아래의 항목이 이름으로 일치하므로, 연산자는 사용자가 제공한 필드를 기본값 위에 깊게 병합합니다.

Operator 전체 제어

연산자 manager의 두 플래그는 업그레이드 확인 루프를 전역적으로 제어합니다: 에어갭 환경이거나 clickhouse.com으로의 egress가 허용되지 않는 경우 --disable-version-update-checks=true를 설정하십시오.

ClickHouse 설정

기본 default 사용자 비밀번호

spec.settings.defaultUserPassword는 내장된 default 사용자의 비밀번호를 설정합니다. CR에 직접 인라인으로 지정하지 말고, 생성한 시크릿(권장) 또는 ConfigMap의 키에 저장된 값을 사용하십시오:
secret 또는 configMap 중 정확히 하나만 지정하십시오. 선택한 항목에는 name(객체 이름) 및 key(비밀번호가 들어 있는 항목)가 모두 포함되어야 합니다.

비밀번호 유형

passwordType은 값을 어떻게 해석할지 ClickHouse에 지정합니다. 기본값은 password(평문)이며, 대안으로는 password_sha256_hexpassword_double_sha1_hex 같은 해시 형식이 있습니다. 평문이 저장되지 않도록 해시 유형을 사용하는 것이 좋습니다. 전체 목록은 ClickHouse 사용자 설정 을 참조하십시오.

시크릿을 사용하는 전체 예시

시크릿을 생성한 후 해당 키를 참조하세요:
passwordType: password를 사용하면 파드 내 clickhouse-client에 이 비밀번호가 설정되므로 디버깅에 편리합니다.
해시된 비밀번호를 사용하는 경우에는 평문 대신 해시를 저장하십시오:

ConfigMap 사용하기

ConfigMap도 같은 방식으로 작동하지만, 내용은 시크릿처럼 보호되지 않습니다. 민감하지 않거나 이미 해시된 값에만 사용하십시오. 예를 들어 password_sha256_hex 다이제스트가 있습니다:
ConfigMap에 평문 비밀번호를 넣지 마십시오. 평문 (passwordType: password) 값을 사용할 때는 시크릿을 사용하십시오.

구성의 사용자 지정 사용자

설정 파일에서 추가 사용자를 구성합니다. 사용자용 ConfigMap과 시크릿을 생성합니다:
ClickHouseCluster에 사용자 지정 구성을 추가합니다:

데이터베이스 동기화

새 레플리카의 데이터베이스 자동 동기화를 활성화합니다:
활성화하면 operator가 Replicated 및 통합 테이블을 새 레플리카에 동기화합니다.

서버 로깅

spec.settings.logger에서 ClickHouse 서버 로그를 구성합니다. 모든 필드는 안전한 기본값이 적용되는 선택 사항이므로, 별도로 설정하지 않은 클러스터도 기본적으로 컨테이너 콘솔과 디스크의 롤링 파일 모두에 trace 수준으로 로그를 기록합니다.
연산자는 kubectl logs가 작동하도록 항상 콘솔 로깅을 유지하고, logToFiletrue이면 여기에 파일 로깅을 추가합니다. 기본값을 사용하는 cluster는 다음 logger 블록으로 렌더링됩니다:
동일한 spec.settings.logger 블록은 KeeperCluster에도 적용되며, 이 경우 연산자는 파일을 /var/log/clickhouse-keeper/ 아래에 기록합니다.
logToFile과 관계없이 콘솔 로깅은 계속 활성화되므로, 파일 로깅을 비활성화해도 kubectl logs는 계속 작동합니다. JSON을 파싱하는 구조화된 로그 저장소로 로그를 전송하는 경우 jsonLogs: true로 설정하십시오.

사용자 지정 구성

내장 추가 구성

사용자 지정 설정 파일을 마운트하는 대신, ClickHouse의 추가 구성 옵션을 직접 지정할 수 있습니다. extraConfig를 사용하여 사용자 지정 ClickHouse 구성을 추가하십시오:

내장된 추가 사용자 구성

extraUsersConfig를 사용해 추가 ClickHouse 사용자 구성을 지정할 수도 있습니다. 이는 클러스터 사양에서 사용자, 프로필, 쿼터, 권한 부여를 직접 정의할 때 유용합니다.
extraUsersConfig는 k8s ConfigMap 객체에 저장됩니다. 여기에 평문 시크릿을 저장하지 마십시오.

지원되는 모든 ClickHouse 사용자 구성 옵션은 문서를 참조하십시오.

구성 예시

전체 구성 예시는 다음과 같습니다:
마지막 수정일 2026년 7월 3일