본문으로 건너뛰기
8.4 애플리케이션에서 연결

8.4 애플리케이션에서 연결

애플리케이션이 CloudNativePG 데이터베이스에 붙는 방법은 단순하다. 특정 Pod를 가리키지 않고, Operator가 관리하는 서비스 이름으로 접속하며, 자격 증명은 Operator가 만들어 둔 Secret에서 읽는다. Pod가 죽거나 failover가 일어나도 서비스 이름과 Secret은 그대로이므로, 애플리케이션은 접속 설정을 바꿀 필요가 없다. 이 절에서는 rw/ro/r 세 서비스의 역할, 접속 문자열을 담은 Secret의 구조, 그리고 DNS와 환경 변수 두 가지 연결 방식을 정리한다.

세 개의 서비스: rw / ro / r

Cluster 이름이 cluster-example이라면 세 서비스가 생긴다. 어떤 워크로드냐에 따라 접속할 서비스를 고른다.

서비스대상용도
cluster-example-rw현재 primary쓰기(그리고 최신 읽기)
cluster-example-roreplica들읽기 전용 워크로드 분산
cluster-example-r모든 인스턴스아무 인스턴스나 읽기
    flowchart TD
  APP["애플리케이션"]
  RW["-rw 서비스"]
  RO["-ro 서비스"]
  PRI["primary"]
  R1["replica 1"]
  R2["replica 2"]

  APP -->|쓰기| RW --> PRI
  APP -->|읽기 분산| RO --> R1
  RO --> R2
  PRI -->|streaming| R1
  PRI -->|streaming| R2

  classDef node fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  class APP,RW,RO,PRI,R1,R2 node
  

failover로 primary가 바뀌면 Operator가 -rw의 엔드포인트를 새 primary로 자동 갱신한다. 애플리케이션은 계속 -rw만 바라보면 된다.

읽기·쓰기를 나눠 라우팅하면 primary의 부하를 replica로 덜 수 있다. 다만 async 복제에서는 replica가 약간 뒤처질 수 있으므로, 방금 쓴 데이터를 곧바로 읽어야 하는 경로는 -rw(또는 -r이 아닌 primary)로 보낸다.

접속 자격 증명: basic-auth Secret

Operator는 Cluster마다 최대 두 개의 basic-auth 타입 Secret을 만든다.

Secret내용
<cluster>-app애플리케이션 계정(기본 데이터베이스 소유자)
<cluster>-superusersuperuser 계정 — enableSuperuserAccess: true일 때만

superuser의 네트워크 접속은 기본적으로 막혀 있으므로, 애플리케이션은 <cluster>-app Secret을 쓴다. 이 Secret 하나에 접속에 필요한 거의 모든 것이 들어 있다.

username / password계정과 비밀번호
host / portrw 서비스 호스트와 포트
dbname데이터베이스 이름
pgpass.pgpass 파일 형식
uri표준 PostgreSQL 접속 문자열
jdbc-uriJDBC 형식
fqdn-uri / fqdn-jdbc-uriFQDN 기반 URI

애플리케이션에서는 대개 이 키들을 환경 변수로 주입해 쓴다.

spec:
  containers:
  - name: app
    image: my-app:latest
    env:
    - name: DATABASE_URL
      valueFrom:
        secretKeyRef:
          name: cluster-example-app
          key: uri
Secret의 uri·host는 rw 서비스를 가리킨다. 읽기 전용 워크로드를 ro 서비스로 보내려면 접속 문자열의 host를 <cluster>-ro로 바꿔 별도로 구성한다. Secret 값을 그대로 쓰면 모든 트래픽이 primary로 간다.

두 가지 연결 방식

DNS 이름 (권장)

Kubernetes DNS로 서비스 이름을 해석한다. 같은 namespace면 서비스 이름만, 다른 namespace면 <service>.<namespace> 형태를 쓴다.

# 같은 namespace
host=cluster-example-rw dbname=app user=app

# 다른 namespace
host=cluster-example-rw.pg-namespace dbname=app user=app

환경 변수 (같은 namespace)

애플리케이션을 데이터베이스와 같은 namespace에 배포하면, Kubernetes가 서비스별 접속 정보를 환경 변수로 주입한다. Cluster 이름이 pg-database라면 다음과 같은 변수를 쓸 수 있다.

PG_DATABASE_RW_SERVICE_HOST   # primary(쓰기)
PG_DATABASE_RO_SERVICE_HOST   # replica(읽기)
PG_DATABASE_R_SERVICE_HOST    # 아무 인스턴스(읽기)

정리

  • 애플리케이션은 Pod가 아니라 -rw·-ro·-r 서비스로 접속한다
  • 쓰기·최신 읽기는 -rw, 읽기 분산은 -ro. failover 시 -rw는 자동 갱신
  • 자격 증명은 <cluster>-app basic-auth Secret에서 읽는다 (uri·jdbc-uri 등 포함)
  • Secret의 uri는 rw를 가리키므로, ro로 보내려면 host를 따로 구성
  • 접속은 DNS 이름 방식을 권장, 같은 namespace면 환경 변수도 가능

다음 절(8.5)에서는 연결 수가 많아질 때 앞단에 두는 PgBouncer 기반 connection pooling을 본다.