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-ro | replica들 | 읽기 전용 워크로드 분산 |
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만 바라보면 된다.
-rw(또는 -r이 아닌 primary)로 보낸다.접속 자격 증명: basic-auth Secret
Operator는 Cluster마다 최대 두 개의 basic-auth 타입 Secret을 만든다.
| Secret | 내용 |
|---|---|
<cluster>-app | 애플리케이션 계정(기본 데이터베이스 소유자) |
<cluster>-superuser | superuser 계정 — enableSuperuserAccess: true일 때만 |
superuser의 네트워크 접속은 기본적으로 막혀 있으므로, 애플리케이션은 <cluster>-app Secret을 쓴다. 이 Secret 하나에 접속에 필요한 거의 모든 것이 들어 있다.
| 키 | 값 |
|---|---|
username / password | 계정과 비밀번호 |
host / port | rw 서비스 호스트와 포트 |
dbname | 데이터베이스 이름 |
pgpass | .pgpass 파일 형식 |
uri | 표준 PostgreSQL 접속 문자열 |
jdbc-uri | JDBC 형식 |
fqdn-uri / fqdn-jdbc-uri | FQDN 기반 URI |
애플리케이션에서는 대개 이 키들을 환경 변수로 주입해 쓴다.
spec:
containers:
- name: app
image: my-app:latest
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: cluster-example-app
key: uriuri·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>-appbasic-auth Secret에서 읽는다 (uri·jdbc-uri 등 포함) - Secret의 uri는 rw를 가리키므로, ro로 보내려면 host를 따로 구성
- 접속은 DNS 이름 방식을 권장, 같은 namespace면 환경 변수도 가능
다음 절(8.5)에서는 연결 수가 많아질 때 앞단에 두는 PgBouncer 기반 connection pooling을 본다.