설치와 기본 설정은 Keepalived 문서에 있다. 여기에는 운영 중 실제로 반복해 묻게 되는 것들을 모았다.
keepalived.conf 예제를 찾아보면 virtual_server 블록이 같이 나오는 경우가 많아 필수라고 오해하기 쉽다. virtual_server 는 LVS(IPVS) 로드밸런서 기능을 켜는 설정이다. VIP 하나를 장애 시 넘기기만 할 목적이라면 vrrp_instance 만 있으면 된다.
global_defs {
router_id node01
}
vrrp_instance VI_1 {
state BACKUP
interface eno1
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass ${VRRP_PASSWORD}
}
virtual_ipaddress {
192.168.105.60/24 dev eno1
}
}
virtual_server 가 필요한 경우는 keepalived 자신이 L4 분산기 역할을 할 때다. 뒤에 HAProxy·nginx·Ingress 가 있다면 그쪽이 분산을 맡으므로 keepalived 는 VIP 만 옮기면 된다.
global_defs 도 필수는 아니다. 다만 router_id 를 노드마다 다르게 적어 두면 로그를 구분하기 쉽다.
없어도 된다. VRRP 는 같은 L2 구간의 노드끼리 주고받는 프로토콜이고, VIP 는 MASTER 노드의 NIC 에 올라간다. 전환 시 gratuitous ARP 를 뿌려 스위치의 MAC 테이블을 갱신한다. 별도 하드웨어 로드밸런서는 필요 없다.
다만 VIP 와 실 IP 가 같은 L2 세그먼트에 있어야 한다. 라우터를 사이에 둔 다른 대역의 주소를 VIP 로 쓰면 ARP 가 닿지 않는다.
모든 노드를 state BACKUP 으로 두고 priority 만 다르게 주는 편이 안전하다. 기동 시 우선순위가 가장 높은 노드가 MASTER 로 승격한다.
state MASTER 를 박아 두면 그 노드가 복구되는 순간 무조건 VIP 를 되가져간다. 데이터베이스 HA 에서는 이 되돌림이 원치 않는 재전환을 만든다. 되돌림을 아예 막으려면 nopreempt 를 준다. nopreempt 는 state BACKUP 인 인스턴스에서만 동작한다.
vrrp_instance VI_1 {
state BACKUP
nopreempt
priority 150
...
}
virtual_router_id 는 같은 L2 안의 모든 참여 노드에서 같아야 하고, 같은 구간에 다른 VRRP 그룹이 있다면 서로 달라야 한다. 값이 겹치면 두 그룹이 서로의 광고를 자기 것으로 받아들여 VIP 가 널뛴다.
VRRP 는 기본적으로 224.0.0.18 멀티캐스트를 쓴다. 클라우드나 일부 가상 스위치, 멀티캐스트를 막은 사내망에서는 통하지 않는다. 이럴 때 유니캐스트로 바꾼다.
vrrp_instance VI_1 {
state BACKUP
interface eno1
virtual_router_id 51
priority 150
advert_int 1
unicast_src_ip 172.18.61.21
unicast_peer {
172.18.61.22
172.18.61.23
}
authentication {
auth_type PASS
auth_pass ${VRRP_PASSWORD}
}
virtual_ipaddress {
192.168.105.60/24 dev eno1
}
}
unicast_src_ip 에는 그 노드 자신의 실 IP 를, unicast_peer 에는 나머지 노드들의 실 IP 를 적는다. 노드가 셋이면 각 노드의 peer 목록에 자기 자신을 빼고 둘씩 들어간다. 자기 IP 를 peer 에 남겨 두면 자기 광고를 받아 상태가 흔들린다.
방화벽을 쓴다면 VRRP(프로토콜 번호 112)를 열어야 한다.
sudo firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
sudo firewall-cmd --reload
정상 동작이다. VIP 는 MASTER 한 노드에만 올라가므로 BACKUP 노드에서 그 주소로 ping 을 쏘면 응답이 없다. 장애로 오해하기 쉬운 지점이다.
# MASTER 에서만 보인다
ip -4 addr show | grep 192.168.105.60
sudo journalctl -u keepalived -f
일부 설정에서 VIP 를 실 NIC 가 아닌 더미 인터페이스에 붙인다.
virtual_ipaddress {
192.168.105.60/32 dev dummy0
}
dummy0 는 NOARP 속성이라 외부에서 그 주소를 ARP 로 찾을 수 없다. 앞단 로드밸런서가 DSR(Direct Server Return) 방식으로 트래픽을 보내 주는 구조에서 쓰는 형태다. 앞단 장비 없이 이대로 두면 VIP 로 접속이 되지 않는다. 일반적인 VIP 페일오버라면 실 NIC 에 대역과 맞는 프리픽스로 올린다.
virtual_ipaddress {
192.168.105.60/24 dev eno1
}
RHEL 9 계열은 NetworkManager 가 기본이다. VIP 를 NetworkManager 프로파일에 절대 넣지 않는다. keepalived 가 런타임으로 올리고 내리는 주소를 NM 이 자기 것으로 관리하려 들면 충돌한다.
nmcli device status
nmcli -f ipv4.addresses connection show eno1
설정 파일 어디에도 없는 주소가 ip addr 에 보인다면 keepalived 나 옛 alias 가 올린 것이다. 이 상태가 통신 장애로 이어지는 사례는 SSH 접속 실패 진단 에 정리했다.
vrrp_instance VI_1 {
...
notify_master "/etc/keepalived/on_master.sh"
notify_backup "/etc/keepalived/on_backup.sh"
notify_fault "/etc/keepalived/on_fault.sh"
}
서비스 상태를 감시해 우선순위를 낮추려면 vrrp_script 를 쓴다.
vrrp_script chk_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight -20
fall 2
rise 2
}
vrrp_instance VI_1 {
...
track_script {
chk_haproxy
}
}