가상 IP 및 이중화 구성 관리

개요

본 문서는 OpenSQL v3.0의 OpenProxy 모듈에서 제공하는 가상 라우터 다중화 프로토콜(VRRP) 기반의 가상 IP(Virtual IP) 설정 및 관제 기능에 설정과 구성 방법을 다룬다.

가상 IP 관리 기능

  • OpenProxy 에서는 가상라우터 다중화 프로토콜을 사용하여 Virtual IP 관리를 수행한다.

  • OpenProxy 에서는 PostgreSQL 커넥션 Pooling 및 로드밸런싱 기능에 영향을 미치지 않도록 별도의 비동기 런타임을 통하여 가상 라우터 이벤트를 처리한다.

  • 지정한 네트워크 인터페이스의 Multicast 주소로 Advertisement Packet을 보내거나 혹은 다른 Peer 노드 (OpenProxy가 구성된 다른 노드) 들의 IPv4 주소를 설정하여 Unicast 방식으로도 동작할 수 있다.

    • Advertisement Packet의 송/수신은 Linux Raw (L3; IP) 소켓을 열고 네트워크의 Multicast 주소 224.0.0.18 에 바인딩 혹은 자신이 구동중인 노드의 IPv4 주소에 바인딩 (Unicast 옵션을 활성화한 경우) 함으로써 이루어진다.

    • 가상 IP 점유 / 해제는 Linux Netlink 소켓을 열고 커널에 RTM_NEWADDR 혹은 RTM_DELADDR 메세지를 직접 보내는 방식으로 이루어진다.

  • 가상 IP 기능 활성화를 위해서는 OpenProxy 프로세스에 Linux 시스템 권한 cap_net_admincap_net_raw 설정이 필요하다.

Patroni 연동 기능

  • Patroni를 이용해 구성된 PostgreSQL 클러스터에 대해 OpenProxy에서 접속할 PostgreSQL 서버의 Role을 정의할 필요 없이 Patroni의 REST API를 통한 Topology Discovery를 수행하도록 지정할 수 있다.

    • 각 Pool의 Shard 마다 use_patroni (Boolean) 키를 true로 설정해 활성화할 수 있으며 정의되어 있지 않은 경우는 해당 기능이 비활성화된다.

    • Shard 마다 필요한 경우 patroni_port 변수를 추가로 설정해 기본 Port 8008 이 아닌 다른 Port를 리스닝하고 있는 Patroni 서버와도 연동할 수 있다.

    • Patroni 서버와 연동해 클러스터 토폴로지를 가져오는 경우 Shard의 Server 마다 설정한 PostgreSQL에 접속하기 위한 Port 번호와 PostgreSQL 노드 Role (Primary 혹은 Replica) 은 무시된다.

  • Patroni와 연동되도록 설정된 Pool은 설정된 renew_interval(밀리초 단위, 기본값: 5000) 주기마다 Patroni의 REST API 서버에 요청을 보내, PostgreSQL 서버의 접속 정보와 Primary/Replica 역할(Role) 정보를 가져온다.

  • Patroni 서버로 보내는 HTTP 요청은 기본적으로 1초의 타임아웃을 가진다. Shard 내 서버에 요청을 보낸 후, 타임아웃 시간 내에 응답을 받지 못하거나 응답 파싱(Parsing)에 실패할 경우, 다음 서버로 요청을 보내는 방식으로 동작한다.

    • 모든 서버에 질의했음에도 응답을 정상적으로 처리하지 못한 경우, 서버의 역할(Role)을 업데이트하지 않는다. 이로 인해 트랜잭션 풀링 모드에서의 쿼리 파싱(Query Parsing) 및 읽기-쓰기 분리(Read-Write Splitting) 기능이 정상적으로 동작하지 않을 수 있다.


구성

가상 라우터

OpenProxy 설정파일인 openproxy.toml[general.virtual_router] 항목을 설정하여 가상 라우터 기능을 활성화할 수 있다.

[general.virtual_router]
interface = "eno1"
router_id = 50
priority = 150
advert_int = 3
vip_addresses = [ "192.168.0.200/24" ]
pre_promote_script = "/home/opensql/startup.sh"
pre_demote_script = "/home/opensql/cleanup.sh"
unicast_peers = [ "192.168.0.7", "192.168.0.8" ]

해당 항목이 정의되면 OpenProxy 프로세스 시작 시 별도 런타임을 통해 가상 라우터 상태 머신 (State Machine) 이 활성화되어 가상 IP 관련 이벤트를 처리한다.

  • interface 항목은 다른 OpenProxy 노드들과 통신할 이 노드의 네트워크 인터페이스 이름을 지정한다.

  • router_id 항목은 이 네트워크에서 가상 라우터 클러스터를 구분할 식별자로 1 ~ 255 사이의 값을 가진다. 가상 IP MASTER 선출에 참여할 다른 OpenProxy 노드들과 같은 값을 가져야 한다.

  • priority 항목은 MASTER 가상 라우터 선출에 있어 이 노드가 가질 우선순위 값으로 1 ~ 255 사이의 값을 가진다. 우선순위 값이 255 인 노드는 시작과 동시에 BACKUP 상태가 아닌 MASTER 상태로 가상 IP 점유를 시도하게 된다. 이 외에는 Advertisement 패킷을 통해 전달되는 우선순위 값을 인식하여 가장 높은 노드가 MASTER 상태가 된다. 노드마다 다르게 설정하는 것을 권장한다.

  • advert_int 항목은 MASTER 노드가 자신의 상태 및 우선순위 값을 네트워크 내에 전파하는 Advertisement 패킷을 전달할 주기로 단위는 초 (second) 이며 1 ~ 255 사이의 값을 가진다. 클러스터 내의 모든 노드들이 같은 값을 가져야 하며 Advertisement 패킷을 3번 연속으로 수신하지 못하면 다른 BACKUP 노드들이 MASTER 선출을 시작한다.

  • vip_addresses 는 MASTER 노드가 점유할 가상 IP들의 목록으로 쉼표 , 로 구분되는 IPv4 주소 및 네트워크의 비트마스크 길이를 포함한 형태로 주어져야 한다.

  • pre_promote_script (Optional) 은 BACKUP → MASTER 승격이 일어날 경우 이 노드에서 실행할 명령어를 지정하는 항목이다. 특정 클라우드 벤더 환경에서는 노드의 네트워크 인터페이스가 가상화 되어 있어 가상 IP 등록을 위해서는 노드의 Secondary IP 등록 이외에 추가적인 작업이 필요할 수 있다.

  • pre_demote_script (Optional) 은 MASTER → BACKUP 강등이 일어날 경우 이 노드에서 실행할 명령어를 지정하는 항목이다.

  • unicast_peers (Optional) 은 Multicast 방식이 아닌 Unicast 방식으로 다른 OpenProxy 노드에 Advertisement 패킷을 전달하기 위한 옵션이다. 가상 IP MASTER 선출에 참여할 다른 OpenProxy 노드들의 IPv4 주소를 쉼표 , 로 구분되는 배열로 지정한다.

Patroni REST API 연동

OpenProxy 설정파일인 openproxy.toml 에 Patroni REST API와 연동하고자 하는 Pool이 정의된 섹션의 Shard 정의에 use_patroni 키를 설정하여 토폴로지 Discovery 기능을 활성화한다.

  • [general] 섹션의 renew_interval 값을 설정하여 openproxy.toml 파일을 읽어오거나 Patroni 서버에 질의하여 PostgreSQL 서버의 Role을 업데이트 할 주기를 조정할 수 있다.

  • Port 번호와 Role 값은 OpenProxy Connection 생성 시에 실제로 참조되는 값은 아니지만 하위 호환성을 위해 입력되어야 한다.

[general]
renew_interval = 5000  ## openproxy.toml 파일을 읽어 Config을 업데이트하거나 Patroni 서버에 질의하여
                       ## PostgreSQL 서버의 Role을 업데이트 할 주기를 설정할 수 있다.
                       ## 단위는 밀리초 (milliseconds) 이며 기본값은 5000 이다.

[pools.my_pool]

[pools.my_pool.shards.0]
servers = [
  [
    "192.168.0.8",    ## Patroni REST API 서버가 구동중인 호스트들의 IPv4 주소를 입력한다.
    5432,             ## PostgreSQL에 접속하기 위한 Port 번호로 Patroni 연동 시에는 무시된다.
    "Auto",           ## PostgreSQL 인스턴스의 Primary / Replica Role 여부로 Patroni 연동 시에는 무시된다.
  ],
  [
    "192.168.0.9",
    5432,
    "Auto",
  ],
  [
    "192.168.0.10",
    5432,
    "Auto",
  ]
]
database = "postgres"
use_patroni = true
patroni_port = 8765    ## Patroni REST API 서버의 Port 번호를 지정한다. 비어있는 경우 기본값 8008이 사용된다.


실행

가상 라우터 기능을 활성화하기 위해서는 OpenProxy 프로세스를 root 사용자 권한으로 실행하거나 cap_net_raw, cap_net_admin 권한이 부여되어야 한다.

  • cap_net_rawRAW 타입 네트워크 소켓을 열기 위해 필요하다.

  • cap_net_admin 은 네트워크 인터페이스에 Secondary IP 추가 / 삭제를 위해 필요하다.

아래와 같이 Linux setcap 을 이용해 실행 바이너리 openproxy 에 권한을 부여한다.

$ sudo setcap 'cap_net_raw=eip cap_net_admin=eip' openproxy

systemd 서비스로 설정하여 구동하는 경우 아래 옵션을 추가하여 권한을 부여한다.

[Service]
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN

Last updated