infra
Platform

모듈 맵

[Network] Keepalived와 가상 IP(VIP) 기반 고가용성(HA) 구성

0 / 35 완료

펼치기
0 / 35 완료0%

Networking · 28 / 35

[Network] Keepalived와 가상 IP(VIP) 기반 고가용성(HA) 구성

SPOF 제거와 HA 설계 원칙을 이해하고, Keepalived/VRRP 기반 이중화와 AWS ALB/NLB가 이것을 어떻게 대체하는지 배웁니다

🚨INCIDENT ALERT
HIGH

로드밸런서 한 대가 죽자 서비스 전체가 같이 멈췄습니다. 예비 서버는 있었지만 VIP가 넘어가지 않아 사용자는 계속 죽은 IP로 접속했습니다.

고가용성은 서버를 두 대 둔다고 끝나지 않습니다. 장애 순간 누가 IP를 들고 응답할지까지 설계해야 합니다.

고가용성(HA) 네트워크와 이중화 구성

로드밸런서를 한 대 구축했더니 이번엔 로드밸런서 자체가 SPOF(Single Point of Failure)가 되었습니다. 로드밸런서 서버가 다운되면 그 뒤에 있는 모든 서버들이 아무리 멀쩡해도 서비스 전체가 중단됩니다.

이 챕터에서는 KeepalivedVRRP 프로토콜을 사용해 로드밸런서(또는 핵심 서버)를 2대로 이중화하고, 한 대가 장애를 일으키면 자동으로 다른 서버가 역할을 이어받는 Failover 시스템을 구축합니다.


이번 챕터에서 배울 것
  • 1SPOF(단일 장애점) 개념과 고가용성(HA) 설계 목표
  • 2VRRP 프로토콜 원리와 VIP(Virtual IP) — 서버 교체 없이 Failover
  • 3Keepalived — 온프레미스 HA 구현 방식
  • 4AWS ALB/NLB — 클라우드가 HA를 대신 처리하는 방식
실습 환경 준비
Keepalived 설치 (두 서버 모두)
sudo apt-get install -y keepalived # Ubuntu/Debian sudo yum install -y keepalived # CentOS/RHEL
IP 포워딩 및 nonlocal bind 활성화
sudo sysctl -w net.ipv4.ip_forward=1 && sudo sysctl -w net.ipv4.ip_nonlocal_bind=1
네트워크 인터페이스 이름 확인
ip link show
VRRP 멀티캐스트 방화벽 허용

firewalld 환경에서는 sudo firewall-cmd --add-protocol=vrrp --permanent && sudo firewall-cmd --reload 로 VRRP 패킷을 허용해야 합니다

💡개념

SPOF와 고가용성(HA): 왜 이중화가 필요한가

새벽 2시에 로드밸런서 서버 한 대가 죽었습니다. 그 서버가 모든 트래픽을 받고 있었기 때문에 서비스 전체가 멈췄습니다. 서버가 두 대 있었지만 둘 다 똑같이 로드밸런서 역할이 아니었습니다. 고가용성 구성을 안 한 것이 아니라, SPOF가 어디에 있는지 인식하지 못한 게 문제였습니다.

SPOF와 고가용성(HA): 왜 이중화가 필요한가

SPOF(Single Point of Failure): 단일 장애점

SPOF는 시스템에서 그 하나만 고장나도 전체가 멈추는 구성요소를 말합니다.

인터넷
  ↓
[로드밸런서 1대] ← SPOF! 이 서버가 죽으면?
  ↓
[서버A] [서버B]   ← 멀쩡해도 클라이언트 접근 불가

로드밸런서가 SPOF인 아키텍처에서는, 로드밸런서가 5분만 다운돼도 전체 서비스가 중단됩니다.

HA(High Availability): 고가용성

HA는 SPOF를 제거해 서비스의 가용성을 높이는 설계 목표입니다. 일반적으로 99.9% (Three Nines) 이상의 가용성을 목표로 합니다.

가용성연간 다운타임
99%87.6시간
99.9%8.76시간
99.99%52.6분
99.999%5.26분

Active/Standby 이중화 구조

HA의 가장 기본 패턴은 Active/Standby 구성입니다.

인터넷
  ↓
VIP: 192.168.1.100  ← 클라이언트가 항상 바라보는 가상 IP
  ↓
[로드밸런서A - Active]  ← 평상시 VIP 보유, 트래픽 처리
[로드밸런서B - Standby] ← 대기 중, A 장애 시 VIP 인계받음

  ↓ A가 장애나면?

VIP: 192.168.1.100  ← 동일한 VIP
  ↓
[로드밸런서B - Active]  ← VIP 인계받아 트래픽 처리 시작

핵심: 클라이언트는 VIP에만 접속합니다. 실제로 어떤 서버가 VIP를 가지고 있는지 알 필요가 없습니다.

Keepalived가 하는 일

Keepalived는 VRRP 프로토콜을 구현한 오픈소스 데몬입니다.

  1. 두 서버가 주기적으로 VRRP 패킷(Heartbeat)을 교환합니다.
  2. priority가 높은 서버가 Master가 되어 VIP를 보유합니다.
  3. Master 서버가 Heartbeat를 보내지 않으면 Backup 서버가 Master로 승격하고 VIP를 가져옵니다.
  4. 원래 Master 서버가 복구되면 다시 VIP를 회수합니다(preempt 기본 동작).

💡개념

VRRP 프로토콜 원리와 VIP 동작 메커니즘

Keepalived를 설정했는데 Master가 죽어도 Backup이 올라오지 않습니다. 로그를 보면 VRRP 광고 패킷이 수신되지 않는다고 나옵니다. VRRP가 어떤 방식으로 상태를 감지하고 IP를 인계하는지 이해하지 못하면, 이 오류 메시지가 무엇을 뜻하는지 알 수 없고 설정 어디를 고쳐야 하는지 찾을 수가 없습니다.

VRRP 프로토콜 원리와 VIP 동작 메커니즘

VRRP(Virtual Router Redundancy Protocol)

VRRP는 RFC 5798에 정의된 네트워크 표준 프로토콜입니다. 원래는 라우터 이중화를 위해 설계되었지만, Keepalived를 통해 일반 Linux 서버에서도 사용합니다.

VRRP 동작 흐름

[서버A - Master]                [서버B - Backup]
priority: 101                   priority: 100
VIP 보유: 192.168.1.100

    → VRRP Advertisement(1초 간격) →
       "나 살아있어요, priority 101"

서버A가 3초간 침묵하면...
                                → 서버B가 Master로 승격
                                → GARP 전송: "192.168.1.100은 이제 내 MAC"
                                → VIP 인계 완료

GARP(Gratuitous ARP): 빠른 VIP 전환의 핵심

Failover 시 새 Master(서버B)는 GARP 패킷을 네트워크에 브로드캐스트합니다.

GARP: "IP 192.168.1.100의 MAC 주소가 변경되었습니다.
       이제 MAC AA:BB:CC:DD:EE:FF입니다."

네트워크의 모든 장비(스위치, 라우터, 클라이언트)가 ARP 캐시를 업데이트합니다. 이 과정이 빠르면 Failover는 수 초 내에 완료됩니다.

VRRP ID(Virtual Router ID)

같은 네트워크에 여러 VRRP 그룹이 있을 수 있습니다. virtual_router_id로 그룹을 구분합니다. 같은 그룹의 서버들은 동일한 virtual_router_id를 사용해야 합니다.

# 잘못된 설정: 두 서버의 virtual_router_id가 다르면 HA 불가
서버A: virtual_router_id 51
서버B: virtual_router_id 52  ← 오타! 서로 다른 그룹으로 인식

VRRP 인증

동일 네트워크에 악의적인 서버가 높은 priority로 Master를 가로채는 것을 방지하기 위해 인증을 설정할 수 있습니다.

authentication {
    auth_type PASS
    auth_pass 비밀번호1234
}

auth_pass는 최대 8자리이며, 같은 VRRP 그룹의 모든 서버에서 동일해야 합니다.


위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# 실습 디렉토리 준비
mkdir -p /tmp/networking/part6/exam_28 && cd /tmp/networking/part6/exam_28

mkdir -p /tmp/networking/part5/keepalived/config
cat > /tmp/networking/part5/keepalived/config/keepalived.conf << 'EOF'
global_defs {
    router_id LVS_MASTER
}

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass secret123
    }

    track_script {
        check_nginx
    }

    virtual_ipaddress {
        192.168.1.100/24
    }
}
EOF
cat > /tmp/networking/part5/keepalived/config/check_nginx.sh << 'EOF'
#!/bin/bash
if systemctl is-active nginx &>/dev/null; then
    exit 0
else
    systemctl start nginx
    sleep 2
    if systemctl is-active nginx &>/dev/null; then
        exit 0
    else
        exit 1
    fi
fi
EOF
chmod +x /tmp/networking/part5/keepalived/config/check_nginx.sh
🔍실행 후 확인할 것
  • 핵심 출력명령 결과에서 성공/실패를 가르는 값을 먼저 확인합니다
  • 대상 식별IP, 포트, 인터페이스, 프로세스명처럼 다음 조치를 결정하는 필드를 봅니다
  • 다음 분기결과가 기대와 다르면 어느 계층을 이어서 점검할지 정합니다

트러블슈팅

가상 IP(VIP) 바인딩 경합 및 상태 동기화 장애 해결

가상 IP(VIP)를 활용해 웹 서버나 프록시 이중화를 기동할 때 발생하는 가장 흔한 장애는 마스터와 백업 서버 모두 VIP를 점유해버리는 split-brain 현상입니다.

  • SRE의 고가용성 네트워크 문제 극복 방법:
    • VRRP 멀티캐스트 포트 방화벽 오픈: Keepalived 데몬 간의 심장박동(Heartbeat) 패킷은 멀티캐스트 IP(224.0.0.18)를 사용합니다. 방화벽에서 이 VRRP 패킷 통신이 막혀있으면 양측 노드가 서로를 죽었다고 판단하여 동시 VIP를 들게 되므로 UFW 정책을 반드시 열어야 합니다.
    • VIP 점유 확인: ip addr show 명령어를 통해 VIP 주소가 올바른 마스터 노드에만 단독 바인딩되어 있는지 점검합니다.

상황

모니터링에서 VIP에 대한 ARP 응답이 두 곳에서 오고 있다는 경보가 발생합니다. 양쪽 서버 모두 ip addr로 확인하면 VIP를 가지고 있습니다.

로컬 터미널
# 서버A에서
ip addr show eth0 | grep 192.168.1.100
# inet 192.168.1.100/24 scope global secondary eth0  ← A가 VIP 보유

# 서버B에서도 동시에
ip addr show eth0 | grep 192.168.1.100
# inet 192.168.1.100/24 scope global secondary eth0  ← B도 VIP 보유!

원인 분석

두 서버 사이의 VRRP 통신이 차단되었습니다.

로컬 터미널
# 서버A에서 서버B의 실제 IP로 ping 시도
ping 192.168.1.11
# Request timeout...  ← 두 서버 간 통신 차단!

VRRP는 멀티캐스트(224.0.0.18) 또는 유니캐스트를 통해 Heartbeat를 교환합니다. 이 통신이 차단되면:

  1. 서버B는 서버A의 Advertisement를 못 받음
  2. "서버A가 죽었나?" 판단하고 Master로 승격
  3. 서버A는 계속 동작 중, 서버B도 Master 선언
  4. 두 서버가 동일 VIP를 사용 → IP 충돌

즉시 해결 방법

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

서버 터미널
# 1. 둘 중 하나를 즉시 Standby로 강제 변경
# priority를 낮춰서 재시작
sudo systemctl stop keepalived

# keepalived.conf의 priority를 낮춤 (서버B의 경우)
sudo sed -i 's/priority 100/priority 50/' /etc/keepalived/keepalived.conf
sudo systemctl start keepalived

근본 원인 제거: 방화벽 규칙 수정

VRRP 멀티캐스트 허용:

위험 명령어

이 명령은 방화벽 정책을 변경해 현재 접속 중인 세션이나 운영 트래픽에 즉시 영향을 줄 수 있습니다. 적용 전 허용 대상 IP·포트와 롤백 명령을 확인하세요.

로컬 터미널
# iptables 기반
sudo iptables -A INPUT -p vrrp -j ACCEPT
sudo iptables -A OUTPUT -p vrrp -j ACCEPT

# firewalld 기반
sudo firewall-cmd --add-protocol=vrrp --permanent
sudo firewall-cmd --reload

또는 유니캐스트 모드로 전환 (멀티캐스트가 막힌 환경에서):

# keepalived.conf에 추가
vrrp_instance VI_1 {
    ...
    unicast_src_ip 192.168.1.10        # 자신의 실제 IP
    unicast_peer {
        192.168.1.11                   # 상대방 실제 IP
    }
    ...
}

재발 방지를 위한 모니터링

로컬 터미널
# VIP를 가진 서버를 주기적으로 점검하는 스크립트
# /usr/local/bin/check-vip.sh
#!/bin/bash
VIP="192.168.1.100"
SERVER_A="192.168.1.10"
SERVER_B="192.168.1.11"

A_HAS_VIP=$(ssh $SERVER_A "ip addr show | grep $VIP" && echo "yes" || echo "no")
B_HAS_VIP=$(ssh $SERVER_B "ip addr show | grep $VIP" && echo "yes" || echo "no")

if [ "$A_HAS_VIP" = "yes" ] && [ "$B_HAS_VIP" = "yes" ]; then
    echo "CRITICAL: Split-Brain detected! Both servers hold VIP!"
    # 알림 전송 로직
fi

상황

Keepalived를 시작했는데 서버A에 VIP가 생성되지 않습니다. systemctl status keepalived는 active(running)을 보여줍니다.

진단 과정

서버 터미널
# 1. Keepalived 상세 로그 확인
sudo journalctl -u keepalived -n 50

# 예시 오류 메시지:
# VRRP_Instance(VI_1) Cant find interface eth0 for vrrp_instance VI_1 !!!

오류 1: 인터페이스 이름 불일치 — 설정 파일의 interface 값이 실제 NIC 이름과 다릅니다.

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# 실제 인터페이스 이름 확인
ip link show

# eth0이 아닌 ens3, enp0s3 등일 수 있음
# keepalived.conf 수정
sudo sed -i 's/interface eth0/interface ens3/' /etc/keepalived/keepalived.conf
sudo systemctl restart keepalived

오류 2: virtual_router_id 충돌 — 같은 네트워크의 다른 Keepalived 인스턴스와 ID가 겹칩니다.

로컬 터미널
# 같은 네트워크에 다른 VRRP 그룹이 virtual_router_id 51을 이미 사용 중일 수 있음
# tcpdump로 VRRP 패킷 확인
sudo tcpdump -i eth0 -n vrrp

# 사용 중인 router_id 확인 후 다른 값으로 변경

오류 3: auth_pass 불일치

두 서버의 auth_pass가 다르면 VRRP 패킷을 무시하고 둘 다 Master가 됩니다.

로컬 터미널
# 두 서버에서 현재 auth_pass 확인
sudo grep auth_pass /etc/keepalived/keepalived.conf

# 다르면 통일 후 재시작

설정 파일 문법 검증

로컬 터미널
# keepalived 설정 파일 문법 체크
sudo keepalived -t -f /etc/keepalived/keepalived.conf
# Configuration is valid  ← 정상

💡개념

클라우드에서 HA — AWS ALB/NLB가 Keepalived를 대신하는 방식

온프레미스에서 Keepalived로 3~5시간을 써야 구현할 것을, AWS는 체크박스 하나로 제공합니다.

온프레미스 HA 구성:
  서버 2대 + Keepalived 설치 + VRRP 설정 + VIP 할당
  → Failover 시간: ~5~10초
  → Split-Brain 방지 설정 별도 필요

AWS Application Load Balancer (ALB):
  콘솔에서 "Multi-AZ" 체크 → 자동으로 여러 AZ에 분산
  → AZ 장애 시 수 초 내 자동 전환
  → Split-Brain 걱정 없음 (AWS 관리형)
기능온프레미스 (Keepalived)AWS (ALB/NLB)
VIP 이중화VRRP + VIP 수동 설정자동 (Elastic Load Balancer)
Failover510초~수 초 (헬스체크 주기)
헬스체크vrrp_script 직접 작성콘솔에서 경로/임계값 설정
Split-Brain 방지Fencing, 쿼럼 직접 설정AWS 인프라가 처리
유지보수직접 패치, 설정 관리관리형 서비스

언제 Keepalived를 직접 쓰는가:

  • 온프레미스 또는 IDC 환경
  • 클라우드 LB 비용이 부담되는 소규모 환경
  • 특수한 네트워크 요구사항 (Anycast, BGP 연동 등)

개발자 관점에서 중요한 것: 내가 배포하는 서버 앞에 HA가 설정되어 있는지, Failover 시간이 어느 정도인지 파악하는 것입니다.


💼
실무 맥락
현업 패턴

실무 적용 사례

1. HAProxy + Keepalived 조합 (온프레미스 표준 구성) — 온프레미스에서 가장 많이 쓰는 HA 아키텍처입니다.

인터넷
  ↓
VIP (Keepalived 관리)
  ↓
[HAProxy A - Active]  [HAProxy B - Standby]
  ↓
[앱서버 1] [앱서버 2] [앱서버 3]

HAProxy와 Keepalived를 묶으면 로드밸런서 자체의 HA를 달성할 수 있습니다. vrrp_script로 HAProxy 프로세스 상태를 감시하다가 HAProxy가 죽으면 Keepalived가 자동으로 Failover를 실행합니다.

2. 클라우드에서의 동등한 개념 — 각 클라우드가 Keepalived에 해당하는 기능을 자체 서비스로 제공합니다.

온프레미스AWSGCP
Keepalived + VIPElastic IP + Route 53 상태 체크Cloud DNS + 헬스체크 정책
Active/StandbyMulti-AZ 배포Multi-region 배포
VRRP HeartbeatELB Health CheckLoad Balancer Health Check

클라우드 환경에서는 Keepalived를 직접 쓰는 경우가 줄었지만, 온프레미스 데이터센터, 하이브리드 클라우드, 비용 최적화 환경에서는 여전히 핵심 기술입니다.

운영 시 주의사항

Failover 시간 계산 — advert_int와 preempt_delay 조합으로 전환 속도를 튜닝합니다.

VRRP dead interval = advert_int × 3 = 1초 × 3 = 3초 (기본값)
GARP 전파 시간 = 약 1~2초
HAProxy 재기동 = 약 1초

총 Failover 시간 ≈ 5~10초

이 시간 동안 기존 연결은 끊어집니다. SLA에서 이 시간을 허용하는지 확인해야 합니다.

정기적인 Failover 드릴

실제 장애가 발생했을 때 처음으로 Failover를 테스트하면 안 됩니다. 월 1회 이상 정기적으로 Active 서버를 내리는 드릴을 수행해 Failover 시간과 서비스 영향을 측정합니다.

면접에서 자주 나오는 질문

  • "HA와 DR(Disaster Recovery)의 차이는 무엇인가요?"
    • HA: 같은 데이터센터 내 빠른 장애 복구 (초~분 단위)
    • DR: 데이터센터 전체 재해 시 다른 위치로 복구 (분~시간 단위)
  • "Split-Brain을 어떻게 방지하나요?"
    • Fencing(STONITH): 상대 노드를 강제로 전원 차단
    • 쿼럼(Quorum): 홀수 노드에서 과반수 동의 필요
    • 네트워크 이중화: Heartbeat 경로를 여러 개 구성

정리

개념핵심 요약
SPOF하나의 고장이 전체를 중단시키는 단일 취약점
VRRPActive/Standby 서버 간 VIP를 자동으로 관리하는 프로토콜
VIP클라이언트가 바라보는 가상 IP, Failover 시에도 변하지 않음
priority높은 서버가 Master(Active) 역할
FailoverActive 장애 시 Standby가 VIP 인계, 수 초 내 완료
Split-BrainVRRP 통신 차단 시 두 서버가 동시에 Master 주장

다음 챕터에서는 tcpdump로 패킷을 직접 캡처하고 TCP 3-Way Handshake와 재전송 이슈를 분석합니다.

지식 확인

퀴즈 — 5문제

Q1

서비스 아키텍처를 검토하던 중 아래 구성을 발견했습니다. '로드밸런서 1대 → 웹 서버 3대 → DB 1대'. 장애 발생 시 서비스 전체가 중단될 가능성이 가장 높은 지점은 어디이며, 그 이유는 무엇입니까?

Q2

VRRP에서 VIP(Virtual IP)의 역할은 무엇인가요?

Q3

Keepalived에서 Master(Active) 서버를 결정하는 기준은 무엇인가요?

Q4

Split-Brain 장애란 무엇인가요?

Q5

Active 서버가 복구되었을 때 다시 Master로 돌아오도록 강제하는 Keepalived 설정은 무엇인가요?

0 / 5 답변

🧪 실습으로 확인하기

포트는 열렸다는데 왜 안 되지? — ss/netstat/telnet으로 TCP 진단

초급

"포트 8080 열었는데요?"와 "왜 안 돼요?" 사이의 간극을 메우는 실습. ss로 바인딩 상태를 확인하고, telnet/nc으로 원격 연결을 테스트하고, iptables 방화벽을 진단하고, 바인딩 주소(0.0.0.0 vs 127.0.0.1)까지 수정하는 4단계 TCP 포트 진단 플로우를 완성한다.

35📋 4단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요

networking고급 · 60
[Network] 서비스 안정성을 지키는 메트릭, 로그, 알림 구축 전략
Networking 트랙 계속
docker입문 · 30
[Docker] 백엔드 개발자에게 Docker와 컨테이너 가상화가 필수인 이유
Docker 트랙 시작점