본문으로 건너뛰기

9.4 Service 관리

Pod는 죽고 새로 뜨며 이름과 IP가 바뀌므로, 애플리케이션은 특정 Pod가 아니라 Kubernetes Service를 통해 PostgreSQL에 접속한다(2.1). CloudNativePG는 Cluster마다 세 개의 기본 Service를 자동으로 만들지만, 그중 일부를 끄거나 원하는 형태의 Service를 추가할 수도 있다.

기본 Service 세 가지

Cluster를 만들면 다음 세 Service가 <클러스터이름>-<역할> 형태의 이름으로, 기본 ClusterIP 타입으로 생성된다. Cluster 이름이 pg라면 각각 pg-rw, pg-ro, pg-r가 된다.

Service대상용도
rw현재 primary읽기·쓰기
roreplica들읽기 전용
r아무 인스턴스읽기
    flowchart TD
  APP["애플리케이션"]
  RW["pg-rw"]
  RO["pg-ro"]
  APP -->|쓰기| RW
  APP -->|읽기 분산| RO
  RW --> PRI["primary"]
  RO --> R1["replica 1"]
  RO --> R2["replica 2"]

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

기본 Service 비활성화

ror Service는 필요 없으면 .spec.managed.services.disabledDefaultServices로 끌 수 있다. 다만 rw는 복제 운영에 필수라 끌 수 없다.

spec:
  managed:
    services:
      disabledDefaultServices: ["ro", "r"]
쓰지 않는 Service를 남겨 두면 불필요한 접속 통로가 열려 있는 셈이다. 애플리케이션이 rw로만 접속한다면 ro·r을 끄는 것이 접속 표면을 줄이는 데 도움이 된다.

커스텀 Service 추가

기본 세 개로 부족할 때는 .spec.managed.services.additional에 Service를 추가한다. 예를 들어 클러스터 외부에서 접속해야 해서 LoadBalancer 타입이 필요한 경우다.

spec:
  managed:
    services:
      additional:
        - selectorType: rw
          serviceTemplate:
            metadata:
              name: "pg-lb"
              labels:
                role: external
            spec:
              type: LoadBalancer

각 항목의 필드는 다음과 같다.

  • selectorType — 어느 인스턴스를 대상으로 할지 지정한다(rw, ro, r). 이 값에 따라 Operator가 selector를 채운다.
  • serviceTemplate — 표준 Kubernetes Service의 metadata·spec을 그대로 쓴다. 라벨·어노테이션·타입 등을 자유롭게 지정한다.
  • updateStrategy — 변경을 반영하는 방식으로 patch(기본) 또는 replace를 지정한다.
serviceTemplateselector 필드를 직접 적으면 안 된다. selector는 selectorType을 보고 Operator가 관리한다. 또 Service 이름은 기본 Service가 쓰는 <클러스터이름>-<역할> 패턴과 겹치지 않아야 한다.

updateStrategy: patch와 replace

  • patch(기본) — 기존 Service에 변경을 덧붙인다. 접속 중단이 없다.
  • replace — Service를 지우고 다시 만든다. 재생성 동안 일시적인 접속 중단이 생긴다.

특별한 이유가 없으면 patch를 쓴다. spec.type 변경처럼 patch로 반영되지 않는 항목을 바꿔야 할 때만 replace를 고려한다.

외부 노출 시 주의

외부 접속이 필요한 상황은 임시 테스트, DBaaS 형태의 제공, Kubernetes 밖 레거시 애플리케이션 지원 등이다. 다만 PostgreSQL을 클러스터 외부로 노출하는 것은 접속 표면을 넓히는 일이므로, 노출을 켜기 전에 인증·네트워크 정책 같은 보안 장치를 먼저 갖춰야 한다.

정리

Cluster마다 rw·ro·r 세 Service가 ClusterIP로 자동 생성된다. disabledDefaultServicesro·r은 끌 수 있지만 rw는 복제 운영에 필수라 끄지 못한다.

  • 커스텀 Service는 managed.services.additionalselectorTypeserviceTemplate로 추가한다. selector는 직접 적지 않고 Operator에 맡기며, 이름은 기본 패턴과 겹치지 않게 한다.
  • updateStrategy는 무중단 patch가 기본이고, replace는 재생성이라 일시적인 접속 중단이 생긴다.

외부 노출이 필요할 때는 인증·네트워크 정책 같은 보안 장치를 먼저 갖춘 뒤에 켠다.

이것으로 Part IX를 마친다. PostgreSQL의 설정·role·database·Service를 모두 선언으로 다루면, 클러스터의 상태 전체가 코드로 남아 재현·감사·버전 관리가 가능해진다.