아래 글은 작년에 HA 이중화 테스트를 진행하면서 노션에 정리해둔 내용인데, 블로그에는 따로 작성한 적이 없어서 이번 기회에 정리해 옮겨둔다!
프로젝트에서 서비스 무중단을 요구하는 이슈가 발생했다. 이를 해결하기 위해 Pacemaker + Corosync + DRBD 조합을 사용한 HA(High Availability) 환경을 구성하게 되었다. 이 글은 그 과정을 기록한 기술 블로그 형식의 정리이다.
⚠️ 주의:
본 글에서 소개하는 구성은 테스트 및 개발 환경에 맞춰 작성되었다.
실제 운영 환경에서는 반드시 아래 항목들을 함께 고려해야 한다:STONITH(Fencing): 장애 노드를 강제로 차단하여 Split-Brain을 방지하기 위한 메커니즘. 설정하지 않으면 Failover 동작이 비정상적으로 작동하거나 데이터 손상이 발생할 수 있다.
Quorum(쿼럼): 클러스터 노드들 간의 합의를 통해 운영 가능한 노드 수를 판단하는 기능. 이를 통해 네트워크 분리 시 동시 작동(Split-Brain)을 방지한다.
운영 환경에서는 STONITH와 Quorum을 반드시 활성화하여 데이터 일관성과 시스템 안정성을 확보해야 한다.
📌 왜 Pacemaker + Corosync + DRBD인가?
HA 구성에는 여러 방식이 있다. 대표적으로는 아래와 같은 접근 방식들이 있다:
- 애플리케이션 레벨 로드밸런싱 (ex. nginx, keepalived)
- 컨테이너 기반 오케스트레이션 (ex. Kubernetes)
- 시스템 레벨의 이중화 (Pacemaker, Corosync 등)
내가 선택한 조합은 다음과 같은 이유에서 적합했다:
구성 요소 | 역할 | 선택 이유 |
Pacemaker | 리소스 관리 및 Failover 처리 | 다양한 리소스 유형을 관리할 수 있고 안정적임 |
Corosync | 클러스터 메시징 및 노드 간 통신 | 빠르고 신뢰성 높은 통신 제공 |
DRBD | 블록 디바이스 복제 | 디스크 수준에서 데이터를 실시간 복제 가능 |
결론적으로, 데이터 무결성을 보장하면서 장애 발생 시 자동으로 서비스가 반대 노드에서 실행되는 환경을 만들 수 있었다.
🧭 왜 시스템 레벨의 이중화를 선택했는가?
이 프로젝트에서는 여러 이중화 방식 중 시스템 레벨의 이중화를 선택했다. 이유는 다음과 같다:
- 서비스 무중단 운영 필요
서비스가 중단되면 운영에 큰 영향을 미치는 구조였기 때문에, 장애 발생 시 자동으로 대체 노드에서 서비스를 이어받는 환경이 필요했다. - 단일 인스턴스 중심의 구조
동시에 여러 인스턴스에서 동작할 수 없는 앱들이 많았고, 이 경우에는 Active-Passive 구조가 적합했다. - 컨테이너 기반 오케스트레이션(Kubernetes 등)은 과잉 설계
단순 이중화 목적이라면 K8s는 오히려 복잡성과 유지비용만 증가시킬 수 있었기 때문에, 물리 서버 수준의 이중화가 더 현실적인 선택이었다. - 파일 및 DB의 데이터 일관성 요구
중요한 파일이나 DB 데이터를 다루기 때문에, DRBD로 블록 디바이스 수준에서 실시간 복제가 가능한 구조가 필요했다.
결과적으로, 시스템 수준에서 장애를 감지하고 서비스, 스토리지, IP 자원을 자동 failover 해주는 Pacemaker + Corosync + DRBD 조합이 가장 현실적인 해법이었다.
📁 시스템 구성 개요
- 서버: Master, Slave 각 1대
- 네트워크 카드: 각 서버당 2개 (서비스용 + Heartbeat용)
- IP 구성:
- 서비스 IP: 2개
- Heartbeat 전용 IP: 2개
- VIP(Virtual IP): 1개
- OS: Ubuntu 22.04 LTS
- 주요 패키지:
- Pacemaker 2.1.2
- Corosync 3.1.6
- pcs 0.10.11
- drbd-utils (DRBD 9)
⚙️ 구성 및 설정 과정
1️⃣ 사전 준비
호스트 등록 (/etc/hosts)
10.1.1.11 cluster-node01 # Master 노드의 서비스 IP
10.1.1.12 cluster-node02 # Slave 노드의 서비스 IP
172.1.1.11 cluster-node01-hb # Master 노드의 Heartbeat 전용 IP
172.1.1.12 cluster-node02-hb # Slave 노드의 Heartbeat 전용 IP
Heartbeat 전용 NIC을 사용하는 이유는 네트워크 장애로 인한 split-brain 방지를 위해서다.
LVM 볼륨 생성
vgcreate storage -s 64 /dev/sdb
lvcreate --extents 100%FREE -n data storage
2️⃣ DRBD 설정
DRBD 리소스 파일: /etc/drbd.d/drbd_res01.res
resource "drbd_res01" {
protocol C; # 동기 방식 (쓰기 완료 시 두 노드 모두에 반영되어야 함)
disk { on-io-error detach; } # I/O 오류 발생 시 디스크 분리 (데이터 손상 방지)
syncer {} # 기본 동기화 설정
on cluster-node01 {
device /dev/drbd0; # DRBD 논리 디바이스
disk /dev/sdb; # 실물 디스크 혹은 LVM 볼륨
address 172.1.1.11:7791; # DRBD 통신 포트
meta-disk internal; # DRBD 메타데이터는 동일 디스크 내에 저장
}
on cluster-node02 {
device /dev/drbd0;
disk /dev/sdb;
address 172.1.1.12:7791;
meta-disk internal;
}
}
- protocol C는 완전 동기 복제
- DRBD는 7791 포트 사용
메타데이터 생성 및 시작
drbdadm create-md drbd_res01 # 메타데이터 생성
drbdadm up drbd_res01 # 리소스 활성화
Primary 노드에서 DRBD 활성화
drbdadm -- --overwrite-data-of-peer primary drbd_res01 # 이 노드를 primary로 설정
mkfs.xfs /dev/drbd0 # 파일시스템 생성
mount /dev/drbd0 /mnt/storage # 마운트
Secondary 노드에서는 drbdsetup /dev/drbd0 primary로 승격 후 mount 가능
3️⃣ Pacemaker + Corosync 구성
사용자 패스워드 설정 및 서비스 실행
passwd hacluster # Pacemaker 관리용 계정 패스워드 설정
systemctl enable pcsd && systemctl start pcsd # pcs 데몬 활성화
클러스터 구성
pcs host auth cluster-node01 cluster-node02 # 클러스터 노드 인증
pcs cluster setup file_cluster cluster-node01-hb cluster-node02-hb --force
pcs cluster start --all
기본 클러스터 속성 설정
pcs property set stonith-enabled=false
# STONITH(Fencing) 기능 비활성화. 테스트나 간단한 환경에선 임시로 끌 수 있으나, 운영환경에선 설정 필요.
pcs resource defaults update resource-stickiness=1000
# 클러스터 리소스가 이동되지 않도록 고착성 부여 (failover 후 자동 복귀 방지)
4️⃣ 리소스 등록
pcs cluster cib pcs_conf
Virtual IP 리소스
pcs -f pcs_conf resource create VIP ocf:heartbeat:IPaddr2 \
ip=192.168.0.110 cidr_netmask=32 op monitor interval=5s timeout=10s
# 서비스 접속을 위한 가상 IP. 어떤 노드에서든 VIP가 활성화되면 클라이언트는 항상 이 IP로 접속 가능
DRBD 리소스 (promotable)
pcs -f pcs_conf resource create drbd_res ocf:linbit:drbd \
drbd_resource=drbd_res01 \
op monitor timeout=30s interval=5s role=Master \
op monitor timeout=30s interval=6s role=Slave
pcs -f pcs_conf resource promotable drbd_res \
promoted-max=1 promoted-node-max=1 clone-max=2 clone-node-max=1 notify=true
# DRBD를 Master/Slave로 구성해 failover 시 Promoted 노드를 전환할 수 있도록 설정
Filesystem 리소스
pcs -f pcs_conf resource create Filesystem ocf:heartbeat:Filesystem \
device="/dev/drbd0" directory="/mnt/storage" fstype="xfs" options="noatime"
# DRBD 위에 올리는 파일시스템 마운트
그룹화 및 순서/위치 제약
pcs -f pcs_conf resource group add HA-GROUP VIP Filesystem
pcs -f pcs_conf constraint colocation add HA-GROUP with drbd_res-clone INFINITY with-rsc-role=Promoted
# VIP 및 파일시스템은 반드시 DRBD Master 노드에서 실행되어야 함
pcs -f pcs_conf constraint order promote drbd_res-clone then start Filesystem
# DRBD가 Master로 승격된 후 파일시스템 마운트
리소스 적용
pcs cluster cib-push pcs_conf
🧪 테스트 및 확인
- 장애 발생 시 DRBD와 Filesystem, VIP 리소스가 반대 노드에서 정상적으로 승격되는지 확인
- DRBD 복제 상태 확인: cat /proc/drbd
- 클러스터 상태 확인: pcs status, crm_mon
📌 마무리 및 참고
로그 경로
- /var/log/corosync/corosync.log
- /var/log/pacemaker/pacemaker.log
- /var/log/pcsd/pcsd.log
자주 쓰는 PCS 명령어
pcs cluster start --all # 클러스터 시작
pcs cluster stop --all # 클러스터 중지
pcs cluster destroy --all # 클러스터 완전 삭제
crm_mon # 리소스 상태 실시간 보기
✍️ 마치며
이 구조는 고가용성을 필요로 하는 중소규모 프로젝트에서 비용 부담 없이 이중화를 구현할 수 있는 강력한 방법이다. 단순히 구성을 따라 하는 데서 멈추지 말고, 각 구성 요소의 동작 원리를 잘 이해해야 장애 대응 능력도 향상된다.
다음에는 STONITH(Fencing) 구성이나 DRBD split-brain 방지 전략도 함께 정리해볼 예정이다.
'개발 > DevOps' 카테고리의 다른 글
CI/CD 기본 개념과 Jenkins를 활용한 실습 (0) | 2024.05.20 |
---|---|
RDP(Remote Desktop) SSH 터널 인증방식 도입 (0) | 2024.04.19 |
리눅스 맬웨어 발견과 제거 (2) | 2024.04.19 |