Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

ClickHouse 연산자 모니터링

연산자는 Prometheus와 호환되는 메트릭과 Kubernetes 헬스 프로브를 노출하므로, 리컨실리에이션 활동을 관찰하고, 작동이 멈춘 컨트롤러를 감지하고, 장애에 대한 알림을 설정할 수 있습니다.

이 가이드에서는 연산자가 무엇을 노출하는지, 이를 어떻게 스크레이프하는지, 그리고 일상적으로 어떤 쿼리가 유용한지 설명합니다.

엔드포인트

연산자 프로세스는 manager 파드 내에 2개의 HTTP 엔드포인트를 노출합니다.

Endpoint Default port Path Purpose
메트릭 8080 (Helm) / 0 비활성화됨(binary 기본값) /metrics Prometheus 노출 형식
헬스 프로브 8081 /healthz, /readyz Kubernetes 활성 상태 및 준비 상태
메트릭 엔드포인트는 연산자 binary를 직접 실행할 때 기본적으로 비활성화되어 있습니다(--metrics-bind-address=0). Helm 차트에서는 metrics.enable: truemetrics.port: 8080을 사용해 이를 활성화합니다.

헬스 프로브 엔드포인트는 항상 활성화되어 있으며, 배포 템플릿은 /healthz/readyz를 포트 8081의 파드 활성 상태 프로브와 준비 상태 프로브에 연결합니다.

연산자 바이너리 플래그

관련 manager 플래그(cmd/main.go에 정의됨)는 다음과 같습니다.

플래그 기본값 설명
--metrics-bind-address 0 (비활성화) 메트릭 엔드포인트의 바인드 주소입니다. HTTPS에는 :8443, HTTP에는 :8080으로 설정하십시오. 메트릭 서버를 비활성화하려면 0으로 두십시오.
--metrics-secure true 인증 및 권한 부여를 적용한 HTTPS로 메트릭을 제공합니다. 일반 HTTP를 사용하려면 false로 설정하십시오.
--metrics-cert-path 비어 있음 메트릭 서버용 TLS 인증서 파일(tls.crt, tls.key)이 들어 있는 디렉터리입니다.
--metrics-cert-name tls.crt --metrics-cert-path 내 인증서 파일 이름입니다.
--metrics-cert-key tls.key --metrics-cert-path 내 키 파일 이름입니다.
--enable-http2 false 메트릭 및 웹훅 서버에 대해 HTTP/2를 활성화합니다. CVE-2023-44487 / CVE-2023-39325 완화를 위해 기본적으로 비활성화되어 있습니다.
--leader-elect false (바이너리) / true (Helm 차트) 한 번에 하나의 레플리카만 reconcile을 수행하도록 leader election을 활성화합니다. Helm 차트는 기본적으로 manager.args에서 이 플래그를 설정합니다.
--health-probe-bind-address :8081 /healthz/readyz의 바인드 주소입니다.

Helm으로 메트릭 활성화

차트는 이미 메트릭 포트용 Service를 생성하며, 필요에 따라 prometheus-operator용 ServiceMonitor도 생성합니다.

메트릭 엔드포인트 자체는 기본적으로 활성화되어 있습니다(metrics.enable: true, 포트 8080, metrics.secure: true를 통해 HTTPS로 제공). 일반적으로 변경해야 할 설정은 prometheus.enable뿐이며, 이를 설정하면 차트가 ServiceMonitor를 생성합니다:

# values.yaml — minimal override
prometheus:
  enable: true

cert-manager를 사용하지 않는다면 certManager.enable: false도 추가로 설정해야 합니다. 그러면 ServiceMonitor는 insecureSkipVerify: true로 스크레이프하며 bearer-token 인증에만 의존하게 됩니다.

메트릭 관련 전체 기본값은 다음과 같습니다:

metrics:
  enable: true
  port: 8080
  secure: true            # HTTPS with authn/authz enforced on every scrape

certManager:
  enable: true            # Issues the metrics server certificate

prometheus:
  enable: false           # Set to true to render the ServiceMonitor
  scraping_annotations: false   # Alternative: prometheus.io/scrape pod annotations

적용:

helm upgrade --install clickhouse-operator \
  oci://ghcr.io/clickhouse/clickhouse-operator-helm \
  -n clickhouse-operator-system --create-namespace \
  -f values.yaml

설치 후 chart는 다음 리소스를 생성합니다:

  • Service/<resource-prefix>-metrics-service — 포트 8080을 노출합니다(metrics.secure: true이면 HTTPS).
  • ServiceMonitor/<resource-prefix>-controller-manager-metrics-monitorprometheus.enable: true일 때 생성됩니다.
  • ClusterRole/<resource-prefix>-metrics-reader — 비리소스 URL /metrics``에 대해 get` 권한을 부여합니다.

메트릭 엔드포인트 보안

metrics.secure: true인 경우 메트릭 서버는 모든 스크레이프 요청에 대해 TLS Kubernetes 인증/권한 부여를 적용합니다. 스크레이퍼는 다음 조건을 충족해야 합니다.

  1. 유효한 Kubernetes Bearer token을 제시해야 합니다.
  2. 비리소스 URL /metrics에 대한 get 권한이 부여된 클러스터 역할에 바인딩된 ServiceAccount에 속해야 합니다.

이 차트에는 이러한 클러스터 역할이 포함되어 있습니다.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: clickhouse-operator-metrics-reader
rules:
  - nonResourceURLs:
      - /metrics
    verbs:
      - get

이를 스크레이퍼(일반적으로 Prometheus)에서 사용하는 ServiceAccount에 바인딩하십시오:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-clickhouse-operator-metrics-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: clickhouse-operator-metrics-reader
subjects:
  - kind: ServiceAccount
    name: <prometheus-sa>
    namespace: <prometheus-namespace>

ServiceMonitor 참고

prometheus.enable: true로 설정하면 차트는 다음과 같은 형태의 ServiceMonitor를 렌더링합니다:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: <release>-controller-manager-metrics-monitor
  namespace: <operator-namespace>
  labels:
    control-plane: controller-manager
spec:
  selector:
    matchLabels:
      control-plane: controller-manager
  endpoints:
    - path: /metrics
      port: https           # "http" when metrics.secure: false
      scheme: https
      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
      tlsConfig:
        serverName: <release>-metrics-service.<operator-namespace>.svc
        ca:
          secret:
            name: metrics-server-cert
            key: ca.crt
        cert:
          secret:
            name: metrics-server-cert
            key: tls.crt
        keySecret:
          name: metrics-server-cert
          key: tls.key

Prometheus 인스턴스에서 cert-manager를 실행하지 않는다면 tlsConfig.insecureSkipVerify: true로 설정하고 bearer-token 인증만 사용하십시오 — certManager.enable: false일 때 차트는 이미 이렇게 설정됩니다.

독립형 Prometheus 예시

kube-prometheus-stack를 사용하지 않는다면, 리포지토리에는 examples/prometheus_secure_metrics_scraper.yaml에 포함된 자체 완결형 예시가 제공됩니다. 이 예시는 ServiceAccount, 필요한 RBAC, 그리고 연산자의 ServiceMonitor를 선택하는 Prometheus CR을 생성합니다.

헬스 프로브 엔드포인트

경로 사용 주체 반환값
/healthz Kubernetes liveness probe 프로브 서버가 수신 대기 중인 동안 200 OK를 반환합니다.
/readyz Kubernetes 준비 상태 프로브 프로브 서버가 수신 대기 중인 동안 200 OK를 반환합니다.

두 엔드포인트는 모두 동일한 단순 Ping 검사(sigs.k8s.io/controller-runtimehealthz.Ping)에 등록됩니다. 따라서 프로브 실패는 "manager 프로세스가 :8081에서 HTTP를 제공하지 않는다"는 뜻일 뿐, "컨트롤러가 비정상 상태이다"라는 뜻은 아닙니다. 컨트롤러 수준의 문제를 감지하려면 대신 리컨실리에이션 메트릭을 사용하십시오.

두 엔드포인트는 기본적으로 포트 8081에서 제공됩니다. 배포에는 다음과 같이 연결됩니다:

livenessProbe:
  httpGet:
    path: /healthz
    port: 8081
  initialDelaySeconds: 15
  periodSeconds: 20
readinessProbe:
  httpGet:
    path: /readyz
    port: 8081
  initialDelaySeconds: 5
  periodSeconds: 10

프로브가 반복적으로 실패한다면, 대개 프로브 server 자체가 아예 시작되지 않았다는 뜻입니다. 예를 들어 startup 초기에 manager가 종료되었을 수 있습니다. manager logs에서 unable to start manager, RBAC 실패, 또는 cache did not sync 오류를 확인하십시오.

메트릭 카탈로그

연산자는 사용자 정의 Prometheus collector를 등록하지 않습니다. 아래 항목은 모두 기반이 되는 controller-runtimeclient-go 라이브러리에서 노출하는 것입니다. 가장 유용한 시계열을 용도별로 정리하면 다음과 같습니다:

리컨실리에이션 활동

메트릭 유형 레이블
controller_runtime_reconcile_total counter controller, result (success / error / requeue / requeue_after)
controller_runtime_reconcile_errors_total counter controller
controller_runtime_reconcile_time_seconds_bucket histogram controller
controller_runtime_active_workers gauge controller
controller_runtime_max_concurrent_reconciles gauge controller

controller 레이블은 For(...)에 등록된 리소스 유형을 바탕으로 controller-runtime이 결정합니다. 현재 internal/controller/clickhouseinternal/controller/keeper의 코드에서는 각각 clickhouseclusterkeepercluster로 해석됩니다. 연산자를 사용자 지정한 경우 /metrics를 한 번 스크레이프하여 확인하십시오.

작업 큐

메트릭 유형 레이블
workqueue_depth 게이지 name, controller, priority
workqueue_adds_total 카운터 name, controller
workqueue_retries_total 카운터 name, controller
workqueue_unfinished_work_seconds 게이지 name, controller
workqueue_longest_running_processor_seconds 게이지 name, controller
workqueue_queue_duration_seconds_bucket 히스토그램 name, controller
workqueue_work_duration_seconds_bucket 히스토그램 name, controller

namecontroller 레이블에는 동일한 값(컨트롤러 이름)이 들어갑니다.

API 서버 트래픽

메트릭 유형 레이블
rest_client_requests_total counter code, method, host

리더 선출

메트릭 유형 레이블
leader_election_master_status 게이지 name (= d4ceba06.clickhouse.com)

Helm 차트는 기본적으로 --leader-elect를 활성화하므로, 이 메트릭은 일반적인 Helm 설치에 포함됩니다. 플래그 없이 바이너리를 직접 실행하면 이 메트릭은 표시되지 않습니다.

런타임

표준 Go 프로세스 및 런타임 collector — go_goroutines, go_memstats_*, process_cpu_seconds_total, process_resident_memory_bytes 등입니다.

유용한 PromQL 쿼리

상태 개요

# Reconciliation rate per controller
sum by (controller) (rate(controller_runtime_reconcile_total[5m]))

# Error rate per controller (alert if > 0 sustained)
sum by (controller) (rate(controller_runtime_reconcile_errors_total[5m]))

# p99 reconcile latency
histogram_quantile(
  0.99,
  sum by (le, controller) (rate(controller_runtime_reconcile_time_seconds_bucket[5m]))
)

적체 감지

# Pending items in the work queue — a sustained value > 0 indicates a backlog,
# but short spikes during large reconciles are normal.
avg_over_time(workqueue_depth[10m])

# Reconciles that have been running for a long time
workqueue_longest_running_processor_seconds > 60

스로틀링과 API 부하

# Throttled requests to the API server
sum by (code, host) (rate(rest_client_requests_total{code=~"4..|5.."}[5m]))

리더 상태(HA 배포)

# Should be exactly 1 across the replica set (Helm install enables --leader-elect by default)
sum(leader_election_master_status{name="d4ceba06.clickhouse.com"})

권장 알림

PrometheusRule 작성을 위한 출발점입니다(환경에 맞게 임계값을 조정하십시오):

groups:
  - name: clickhouse-operator
    rules:
      - alert: ClickHouseOperatorReconcileErrors
        # > 0.1 errors/s sustained = > ~6 errors/min, filters transient conflicts.
        expr: sum by (controller) (rate(controller_runtime_reconcile_errors_total[5m])) > 0.1
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: 'ClickHouse operator is failing to reconcile {{ $labels.controller }}'

      - alert: ClickHouseOperatorWorkqueueBacklog
        # avg_over_time avoids alerting on transient bursts during large reconciles.
        expr: avg_over_time(workqueue_depth[10m]) > 5
        for: 30m
        labels:
          severity: warning
        annotations:
          summary: 'Operator work queue backlog sustained for 30m'

      - alert: ClickHouseOperatorReconcileSlow
        expr: |
          histogram_quantile(
            0.99,
            sum by (le, controller) (rate(controller_runtime_reconcile_time_seconds_bucket[10m]))
          ) > 30
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: 'p99 reconcile latency for {{ $labels.controller }} > 30s'

      - alert: ClickHouseOperatorNoLeader
        expr: absent(leader_election_master_status{name="d4ceba06.clickhouse.com"}) == 1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: 'No leader for the ClickHouse operator (HA deployment)'

마지막 규칙은 leader election이 활성화된 경우에만 의미가 있습니다.

설정 확인

차트가 clickhouse-operator-system에 설치되어 있다고 가정하고, 전체 과정을 빠르게 점검합니다:

NS=clickhouse-operator-system

# The metrics Service exists and selects the manager pod
kubectl -n $NS get svc -l control-plane=controller-manager

# The ServiceMonitor exists (only with prometheus.enable=true)
kubectl -n $NS get servicemonitor -l control-plane=controller-manager

# Manager pod is Ready (readiness probe answers)
kubectl -n $NS get pod -l control-plane=controller-manager

# Direct scrape from inside the cluster (with the metrics-reader binding)
kubectl -n $NS run curl-metrics --rm -it --restart=Never \
  --image=curlimages/curl:8.10.1 -- sh -c '
    TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
    curl -sk -H "Authorization: Bearer $TOKEN" \
      https://<release>-metrics-service.'$NS'.svc:8080/metrics \
      | head -20
  '

스크레이프 결과가 Prometheus 노출 형식의 메트릭을 반환하면 엔드포인트와 RBAC가 올바르게 구성된 것입니다.

  • 설치 — 모니터링과 관련된 Helm values입니다.
  • 구성 — 메트릭 서버와 공유하는 TLS 구성입니다.
Navigation