본문으로 건너뛰기

10.1 모니터링

CloudNativePG는 각 PostgreSQL 인스턴스 안에 metrics exporter를 함께 띄운다. 이 exporter는 인스턴스에 접속해 상태를 SQL로 조회하고, 그 결과를 Prometheus가 이해하는 텍스트 포맷으로 HTTP에 노출한다. 관찰의 큰 그림은 단순하다. 각 Pod가 metrics를 내놓으면 Prometheus가 주기적으로 긁어(scrape) 저장하고, Grafana가 그 저장소를 읽어 대시보드로 그린다.

    flowchart TD
  subgraph POD["PostgreSQL Pod"]
    PG["postgres"]
    EXP["metrics exporter<br/>:9187/metrics"]
    PG -->|SQL 조회| EXP
  end
  PM["PodMonitor"]
  PROM["Prometheus"]
  GRAF["Grafana"]
  PM -->|scrape 대상 등록| PROM
  PROM -->|scrape| EXP
  GRAF -->|query| PROM

  classDef node fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  class PG,EXP,PM,PROM,GRAF node
  

metrics endpoint

인스턴스마다 metrics는 9187 포트/metrics 경로에 노출된다. exporter는 cnpg_metrics_exporter라는 role로 쿼리를 실행하며, 이 role은 pg_monitor 권한을 물려받아 통계 뷰를 읽을 수 있다.

가장 빠르게 눈으로 확인하는 방법은 port-forward다.

kubectl port-forward cluster-example-1 9187:9187
# 다른 터미널에서
curl -s localhost:9187/metrics | head

Pod 안에서 직접 확인하려면 Pod IP로 붙는다.

POD_IP=$(kubectl get pod cluster-example-1 -o jsonpath='{.status.podIP}')
kubectl exec -ti curl -- curl -s ${POD_IP}:9187/metrics
metrics 조회 결과는 기본적으로 30초 동안 캐시된다. 모니터링 쿼리가 매 scrape마다 인스턴스에 부하를 주지 않게 하려는 장치다. 캐시를 끄려면 .spec.monitoring.metricsQueriesTTL을 0으로 둔다. 캐시 효율은 cache_hits·cache_misses metrics로 확인할 수 있다.

PodMonitor로 Prometheus에 연결

Prometheus Operator를 쓴다면, PodMonitor 리소스를 만들어 “이 label을 가진 Pod들의 metrics 포트를 긁어라"라고 선언한다. Prometheus는 이 선언을 읽어 scrape 대상에 자동으로 등록한다.

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: cluster-example
spec:
  selector:
    matchLabels:
      cnpg.io/cluster: cluster-example
  podMetricsEndpoints:
    - port: metrics
예전에는 .spec.monitoring.enablePodMonitor: true로 Operator가 PodMonitor를 대신 만들게 했지만, 이 필드는 deprecated다. 위처럼 PodMonitor를 직접 만드는 방식을 권장한다.

기본 제공 metrics

Operator는 cnpg-default-monitoring이라는 ConfigMap을 설치해 두고, 여기에 담긴 기본 쿼리를 모든 클러스터에 적용한다. 대표적인 것들만 추리면 다음과 같다.

metric의미
cnpg_collector_up인스턴스가 살아 있는지 여부
cnpg_collector_pg_walWAL 파일 개수·크기
cnpg_collector_sync_replicassynchronous replica 현황
cnpg_collector_nodes_used인스턴스가 퍼져 있는 노드 수
cnpg_collector_postgres_versionPostgreSQL 버전 정보

기본 metrics가 불필요하면 클러스터 단위로 .spec.monitoring.disableDefaultQueries: true를 주거나, Operator 설정에서 MONITORING_QUERIES_CONFIGMAP을 빈 문자열로 두어 전역에서 끌 수 있다.

custom query

기본 metrics로 부족하면 직접 쿼리를 정의해 새 metric을 만든다. 쿼리는 ConfigMap이나 Secret에 담고, 클러스터에서 이를 참조한다.

spec:
  monitoring:
    customQueriesConfigMap:
      - name: example-monitoring
        key: custom-queries
참조하는 ConfigMap·Secret은 Cluster와 같은 namespace에 있어야 한다. cnpg.io/reload: "" label을 붙여 두면 내용이 바뀔 때 자동으로 다시 읽힌다.

쿼리 하나의 구조는 아래와 같다. query가 실제 SQL이고, metrics의 각 항목이 결과 컬럼을 어떤 종류의 metric으로 내보낼지 지정한다.

pg_replication:
  query: "SELECT CASE WHEN NOT pg_is_in_recovery() THEN 0 ELSE GREATEST(0, EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))) END AS lag, (NOT pg_is_in_recovery())::int AS in_recovery"
  primary: false          # replica에서도 실행
  target_databases: ["postgres"]
  metrics:
    - lag:
        usage: "GAUGE"
        description: "복제 지연(초)"
    - in_recovery:
        usage: "GAUGE"
        description: "recovery 상태 여부"

usage에는 컬럼의 성격에 맞는 종류를 지정한다.

usage쓰임
LABEL이 컬럼 값을 metric의 label로
GAUGE오르내리는 순간값
COUNTER누적 증가값
HISTOGRAM분포
DURATION소요 시간
DISCARD결과에서 버림

operator metrics

인스턴스뿐 아니라 Operator 자신도 metrics를 노출한다. 이쪽은 8080 포트/metrics이며, 조정 루프 처리량이나 에러 같은 컨트롤러 지표를 담는다. 별도의 PodMonitor로 긁는다.

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: cnpg-controller-manager
  namespace: cnpg-system
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: cloudnative-pg
  podMetricsEndpoints:
    - port: metrics

Grafana 대시보드

CloudNativePG는 곧바로 쓸 수 있는 Grafana 대시보드를 cloudnative-pg/grafana-dashboards 저장소에 공개해 둔다. grafana-dashboard.json을 내려받아 Grafana의 Dashboard > New > Import로 불러오면, 앞서 본 기본 metrics를 기반으로 한 패널이 바로 채워진다.

metrics endpoint를 TLS로 감싸려면 인스턴스는 .spec.monitoring.tls.enabled: true를 주고, Operator metrics는 METRICS_CERT_DIR 환경 변수로 인증서 디렉토리를 지정한다. 사내망이 아니라 노출된 환경이라면 metrics도 접근 통제 대상임을 잊지 않는다.

정리

  • 각 인스턴스는 9187 포트 /metrics에 Prometheus 포맷 metrics를 노출한다
  • PodMonitor로 scrape 대상을 선언하고, Grafana 공식 대시보드를 import해 시작한다
  • 기본 metrics는 cnpg-default-monitoring ConfigMap에서, 부족하면 custom query로 확장한다
  • Operator 자신의 metrics는 8080 포트에서 별도 PodMonitor로 수집한다

다음 절(10.2)에서는 metrics로는 보이지 않는 사건의 흔적, 즉 로그를 다룬다.