본문 바로가기

DevOps/DOIK (Database Operator in Kubernetes)

PostgreSQL Operator for Kubernetes

쿠버네티스 환경에서 PostgreSQL 워크로드를 관리할 수 있는 CloudNativePostgreSQL를 EDG가 개발 후 공개하였다.
(Apache 2.0, Operator Level 5 Auto Pilot)

공식 문서: https://cloudnative-pg.io/documentation/current/

 

CloudNativePG

CloudNativePG CloudNativePG is an open source operator designed to manage PostgreSQL workloads on any supported Kubernetes cluster running in private, public, hybrid, or multi-cloud environments. CloudNativePG adheres to DevOps principles and concepts such

cloudnative-pg.io

CNPG Architecture

CNPG는 Application-level replication에 의존한다. HA와 Scale을 위해 WAL(Write Ahead Lg) shipping을 기반으로 강력하고 신뢰할 수 있는 물리적 복제 기능을 지원한다. CNPG는 이러한 비동기 복제 방식(WAL)과 동기 스트리밍 복제(Quorum-based sync streaming) 구성의 클러스터를 지원한다.

CNPG는 이러한 복제 방식을 바탕으로 multiple hot standby replicas를 관리하기 위해 다음과 같은 특징을 같는다.

  • HA 구성을 위한 하나의 primary와 여러 hot standby replica
  • 서비스:
    - -rw : 클러스터의 primary 연결 (read/write)
    - -ro :  읽기 전용 워크로드를 위한 hot standby 연결
    - -r :    읽기 전용 워크로드를 위한 모든 인스턴스 연결
  • Shard-nothing 아키텍처
    - PG 인스턴스는 각각 서로 다른 worker node에 상주하고 네트워크만 공유해야 한다. (스토리지 공유 X)
    - PG 인스턴스는 동일한 쿠버네티스 클러스터 및 지역 내에서 다른 가용영역에 있어야 한다.

 

 

CPNG - Storage-level Replication을 사용하지 않을까...?

Storage-level Replication의 방법 중 Shared Disk Failover의 경우를 예를 들어보자.

이러한 경우 여러 서버는 단일 디스크 어레이를 사용하게 된다. Primary서버가 장애가 발생하면 Replica 서버는 해당 디스크를 곧바로 마운트하여 해결하여 신속하게 장애 조치가 가능하다.

하지만 이러한 방법에는 큰 제한 사항이 있다. 만약 디스크가 손상되면 Primary, Replica 서버 모두 작동하지 않게 된다. 또한, 일관성을 위해 Primary 서버가 실행 중인 경우 Replica 서버가 해당 디스크에 접근할 수 없다.

 

CNPG - PostgreSQL은 왜 StatefulSet 또는 Deployment를 사용하지 않을까...?

CNPG에서 PostgreSQL 리소스를 직접 개별 파드를 생성해서 관리한다. 왜 그럴까..?

일반적으로 Stateful한 애플리케이션은 StatefulSet controller에 의해 관리된다(동일 사양으로 구축된 파드 세트를 만들고 조정하며, sticky하게 할당된다). CNPG는 StatefulSet Controller에 의존하지 않고 자체 Custom Controller를 통해 PostgreSQL 인스턴스를 관리한다. 그 이유는 무엇일까?

1. PVC Resizing

StatefulSet의 한계점으로 잘 알려진 PVC 크기 한계다.(PVC의 크기 조정을 지원하지 않음) 이러한 점은 데이터베이스를 관리하기 어려운 점으로 지적되며, 그에 따라 CNPG는 스토리지 클래스를 활용하여 PVC크기 조정을 처리한다.(스토리지 클래스가 지원하는 경우)

2. Primary & Replica Instances

StatefuleSet controller는 1개의 template으로 pod set을 구성한다. 반면에 CNPG는 PostgreSQL 인스턴스를 2가지 종류의 Pod종류를 지원한다.

1. Primary Instance (only one)

2. Replicas (multiple, optional)

이 차이는 특정 작업에 대해 실행할 올바를 배포 전략을 결정할 때 관련이 있다.
(Primary 먼저 작업 후 Replica 작업 필요한 경우 또는 Replica 작업 후 Primary 작업이 필요한 경우 StatefulSet은 대응 어려움)

예를 들어, 다음과 같은 경우가 존재한다.

[Case#1 - Replica First]

- PostgreSQL 이미지 버전 업그레이드

- max_connection 늘릴 경우

[Case#2 - Primary First]

- max_connection 줄일 경우

3. PVC 일관성

PostgreSQL 인스턴스는 multiple PVC로 구성될 수 있다. (PGDATA와 WAL 스토리지 분리)

PostgreSQL 관점에서 두 데이터 저장소는 동시에 사용되기 떄문에 일관성이 필요하다. 인스턴스의 WAL저장솔르 삭제하면 PGDATA가 저장된 PVC는 더 이상 사용할 수 없다.

이러한 부분은 StatefulSet Controller을 사용할 경우, 문제가 발생한다. (StatefulSet의 경우 PVC가 drop되면 그냥 재생성해 버리고 이는 PostgreSQL의 Corruption으로 이어진다.)

CNPG는 그에 따라 위와 같은 경우 발생 시 PVC를 사용할 수 없는 것으로 분류하고, 클러스터에 올바르게 합류하기 위해 다른 인스턴스를 위한 PVC 쌍을 만든다.

4. Local & Remote Storage, Database Size

때떄로 업그레이드를 위헤 Kubernetes 노드를 다운해야 하는 경우가 존재한다. 업그레이드 후 업그레이드 전략에 따라 업데이트 된 노드가 올라오거나 새로운 노드로 교체될 수 있다. 사용 불가한 노드에 PostgreSQL가 호스팅된 경우, 다음과 같은 액션 중 하나를 선택할 수 있다.

 

1. Drop된 노드에 있는 PVC를 분리 - 새로운 PVC 생성 후 다른 PVC에 있는 데이터 복제 - 노드에 데이터가 백업될 때까지 대기
 - 데이터베이스 크기가 허용될 떄 실용적이며, 원하는 수의 replica 수를 즉시 가져올 수 있다.

2. 파드를 drop하고 다른 노드에 파드를 스케줄링 - 해당 파드에 PVC 마운트

- 로컬 노드의 스토리지를 사용하지 않는 경우 사용 가능

- 합리적인 시간 내에 다른 호스트에 PVC를 마운트할 수 있음

3. 파드와 PVC를 그대로 두고 백업될 때까지 기다림

- database 사이즈가 크고 최대 성능과 데이터 내구성을 위해 노드 스토리지를 사용할 떄 적합

 

CNPG는 이러한 다양한 옵션을 제공하는 반면, StatefulSet은 이러한 수준의 customizing을 제공하지 않는다.

 

PgBouncer (Connection Pooling)

https://cloudnative-pg.io/documentation/current/connection_pooling/

 

Connection Pooling - CloudNativePG

CloudNativePG provides native support for connection pooling with PgBouncer, one of the most popular open source connection poolers for PostgreSQL, through the Pooler CRD. In a nutshell, a Pooler in CloudNativePG is a deployment of PgBouncer pods that sits

cloudnative-pg.io

다음 아키텍처 구성도를 보면 PgBouncer를 통한 database access layer에 따른 CNPG 구성이 어떻게 바뀌는지 보여준다.

PostgreSQL primary에 직접 연결하는 부분을, PgBouncer를 통해 기존 커넥션을 재활용하여 보다 빠르고 리소스 효율적으로 PostgreSQL을 사용할 수 있게 된다.

 

PgBouncer의 pooler를 통해 얻을 수 있는 이점은 다음과 같다.

  1. 보안 : PgBouncer는 Client side, Server side 모두 TLS 연결을 통한 전송 암호화를 지원
  2. 인증 : PgBouncer 클라이언트는 (only) 비밀번호 기반 인증을 지원
  3. 고가용성 : PgBouncer를 통한 부하 분산 및 connection 재사용을 통한 효율적인 리소스 사용
  4. 모니터링 : Prometheus exporter 포맷으로 모니터링 지표 추출 가능

하지만 단점으로는 단일 CNPG 클러스터만 수용 가능하며 PgBouncer에 대한 구성 설정에 대한 유연성이 부족하다.

 

PgBouncer는 3가지 종류의 pooling mode를 지원한다.

  • Session Pooling (most polite method)
    클라이언트가 PgBouncer에 연결되면, 연결된 전체 기간 동안 서버에 연결이 할당됨. 클라이언트가 연결을 끊으면 서버 연결은 풒로 다시 돌아감. (모든 PG 기능 지원) 
  • Transaction Pooling
    오직 클라이언트가 transaction 중인 경우에만 서버와의 연결을 유지한다. PgBouncer가 transaction이 끝난 것을 알게 되면 서버는 다시 풀로 돌아감. (몇 가지 PG의 세션 기반 기능을 지원하지 않음)
  • Statement Pooling (most aggressive)
    multi statement 트랜잭션을 허용하지 않음. 클라이언트에 auto commit을 시행하기 위해 사용 (주로 PL/Proxy를 대상으로 사용)

PgBouncer의 특징

  • 연결당 2kB 정도의 적은 메모리를 요구
  • 데이터베이스와 다른 호스트에 상주할 수 있음
  • 대부분의 구성 설정에 대한 온라인 재구성 지원
  • 클라이언트 연결을 끊지 않고 재시작 또는 업그레이드 지원

https://www.pgbouncer.org/features.html

 

PgBouncer features

Features Several levels of brutality when rotating connections: Session pooling Most polite method. When a client connects, a server connection will be assigned to it for the whole duration it stays connected. When the client disconnects, the server connec

www.pgbouncer.org

 

'DevOps > DOIK (Database Operator in Kubernetes)' 카테고리의 다른 글

MongoDB Architecture & Replication  (1) 2023.11.12
MySQL Operator for Kubernetes  (0) 2023.10.26
MySQL Architecture & Replication  (0) 2023.10.24
Kubernetes Basic  (0) 2023.10.21