웹서비스를 운영하면 부하 분산을 위해서 nginx 로 reverse proxy를 사용하거나 HAPROXY 같은 로드밸런서를 널리 사용한다. 물론 이러한 부하 분산은 서비스의 안정적인 운영을 위해서 좋은 방법이다. 그런데, nginx 나 HAPROXY가 설치된 서버가 죽거나 해당 서비스가 다운된다면? 그 뒤에서 웹 서버들은 멀쩡히 돌아가고 있는데, 안정적인 운영을 위해 올려놓은 녀석 하나 때문에 모든 서비스가 불능에 빠져버리는 결과를 초래한다. 로드밸런서 뿐 아니라 라우터와 같이 통신을 위해 꼭 통과해야하는 지점도 불능이 되면, 해당 지점의 전후가 살아 있더라도 전체적인 불능 상태를 초래할 수 있다.
위의 그림과 같이 한 지점이 동작하지 않으면 전체를 불능에 빠트릴 수 있는 요소가 될 수 있는 지점을 spof (single point of failure, 단일장애점) 이라고 한다. 이러한 장애에도 서비스의 지속과 정상 운영을 가능케 하는 행위를 고가용성(High Availability)이라고 한다.
라우터나 로드밸런서의 장애를 극복하고 고가용성을 달성하기 위해서는 라우터와 로드밸런서도 다중화를 시킬 필요성이 있다. 이렇게 네트워크상에 존재하고 있는 라우터 중 어떤 라우터에게 전달 책임을 맡길 것인지 결정하는 프로토콜을 VRRP(Virtual Router Redundancy Protocol)이라고 한다. 비슷한 프로토콜로 HSRP(Hot Standby Router Protocol)이 있는데, 이는 Cisco에 벤더 종속적이며 VRRP는 IETF표준이다. VRRP를 이용해 리눅스에서 HA를 쉽게 해주는 도구로는 대표적으로 keepalived 가 있다. (heartbeat, pacemaker 등 다른 메커니즘을 이용한 도구들도 있지만, 살펴본 결과로는 개인적으로는 keepalived가 가장 간단하다)
VRRP와 keepalived를 소개할 것이며 이번 포스트는 VRRP 에 대해서 살펴보려고 한다.
VRRP는 IETF표준으로 version1(https://tools.ietf.org/html/rfc2338), version2(https://tools.ietf.org/html/rfc3768), version3(https://tools.ietf.org/html/rfc5798)에 그 규격이 지정되어 있으며, RFC에 따르면 다음과 같은 요구조건을 갖춘 프로토콜이다.
1. IP주소 백업 - 여러 라우터에서 마스터 선출, 블랙홀 상태의 최소화, 정상 상태의 대역폭 부하 최소화 및 복잡도 제어, IPvX 트래픽을 지원하는 다중접속LAN 환경에서 폭넓은 동작, 로드밸런싱을 위한 복수의 가상 라우터 지원, 단일 LAN 세그먼트에서 복수의 논리적 IPvX 서브넷 지원
2. 라우터 우선 경로 지정 - 여러 라우터 중 어떤 것이 우선이 될지 직관적인 경로 우선 순위 표현 및 사용 가능한 가장 우수한 라우터로의 수렴 보장
3. 불필요한 서비스 중단 최소화 - 마스터가 정상동작 중인 상황에서 백업이 마스터의 동작을 방해하지 않도록 함
4. 확장된 LAN의 효율적인 작업 - 가상 라우터의 MAC 이 source로 사용되지 않는 경우 learning bridge 를 채택한 LAN 환경에서 station location 학습이 일어나지 않기 때문에 packet 의 범람이 일어나기 때문에 이를 효율화
5. IPv4 및 IPv6의 초단위 이하 작업(ver3 only)- ver3에서 새로 도입된 것인데, ver3 은 ver2 에 비해서 확인 주기를 밀리세컨드 단위로 매우 짧게 가지고 갈 수 있도록 되어 있는데, 이는 보다 빈번한 짧은 주기는 확인 패킷이 밀려서 다운 타임을 감지하는 주기보다 큰 대기가 생길 경우, 마스터의 down으로 오해할 수 있으므로 이를 방지한다.
VRRP 로 맺어진 네트워크에 참여하고 있는 VRRP라우터 중 가장 우선 순위가 높은 VRRP라우터를 MASTER라고하며, 다른 라우터들은 BACKUP이 된다. VRRP는 Health check를 위해 마스터 노드가 IPv4 기준으로 224.0.0.18, IPv6(ver3에서 지원) 기준으로 FF02:0:0:0:0:0:0:12 로 주기적으로 패킷을 송신한다. VRRP 가 사용하는 멀티캐스트 주소는 고정되어 있으므로 네트워크상에 여러 라우터가 존재할 경우 Virtual Rtr ID라는 필드를 통해 패킷을 보내는 라우터를 구분한다.
VRRP 프로토콜이 전송하는 패킷의 필드는 RFC3768(ver2) 기준으로 아래와 같다.
keepalived 를 쓰더라도 아래의 옵션들이 많이 연관되서 사용되니 keepalived 설정 이해에도 도움이 될 듯 하다.
1. IP 필드 지시자
- source address : real interface address 중 Primary IP Address 로 선택된 IP가 source가 된다.
- destination address : 224.0.0.18, TTL(Time To Live)와 관계 없이 이곳으로 패킷을 전송해서는 안 된다.
- TTL : TTL은 255로 고정되어야 한다. 255가 아닌 TTL은 무시한다.
- Protocol : VRRP의 IANA 할당 프로토콜 번호는 112 이다.
2. VRRP 필드 지시자
- version : Version 1 규격은 RFC2338 , Version 2 규격은 RFC3768, Version 3 규격은 RFC5798이다.
- Type : RFC3768 기준으로 Type은 1(ADVERTISEMENT)이다. 이외의 unknown type은 무시된다.
- Virtual Rtr ID(VRID) : 가상 라우터(VRRP라우터가 백업하는 집합)의 식별자이며 1~255 사이의 값이다. 네트워크상에서 여러개의 가상 라우터들이 존재할 때 VRRP는 모든 가상 라우터들이 동일 주소로 멀티캐스팅을 함에도 불구하고 VRID를 통해 가상라우터를 구분할 수 있다. VRID 는 가상 라우터의 MAC 주소에도 쓰인다, 가상 라우터의 MAC 주소는 00-00-5E-00-01-{0xVRID} 이다. 즉, 네트워크상에서 MAC에 매핑되어 제공할 수 있는 VRRP 라우터는 최대 255개까지란 말이다.
- Priority : 가상 라우터에서 VRRP 라우터의 우선순위를 의미하는 부호 없는 8비트 정수 (0~255) 이다. 우선 순위는 숫자가 클수록 높다. 0과 255는 특별한 경우를 위해 예약되어 있으므로, 가상 라우터를 백업하는 VRRP라우터는 1-254 범위의 우선 순위를 가진다.
참고할 사항은 ver2 기준으로는 우선순위가 같더라도 IP 숫자가 크다면 MASTER를 선점할 수 있지만, ver3 기준으로는 우선순위가 큰 것만이 선점이 가능하다.
가상라우터에 할당된 IP를 점유한 VRRP라우터의 우선순위는 255가 되며, 우선순위를 0으로 설정했을 경우 현재의 마스터가 VRRP에 참여하는 것을 포기했다는 것을 의미한다.(예를 들어 Shutdown 하는 경우) 이 때 백업 라우터는 현재의 마스터의 타임아웃을 기다리지 않고 바로 마스터로 전환된다.
- Count IP Addrs : 현재 VRRP advertisement 에 포함된 IP의 숫자이다.
- Authentication Type : ver2 에서는 제거된 기능이다. 즉, VRRP ver2는 별도의 인증 메커니즘을 제공하지 않는다.
RFC2338(ver1)에서는 Authenticaton Type으로 0(No Authentication), 1(Simple Text Password) 2(IP Authentication Header) 를 제공하여 Authentication Data가 일치하지 않는 packet 은 무시하였지만, 보안상 실질적인 이득이 없고, 이에 따른 패킷 교환 실패시에 마스터 분할을 초래하여 ver2 부터는 제거되었다.
단 ver2는 ver1과의 필드 하위호환성을 제공하기 위해 0(No Authentication)을 제외하면 1,2는 Reserved 으로 남아있다. 이는 ver3이 ver2의 필드 하위호환성을 제공하지 않는 것과 대조적이다.
- Advertisement Interval : Advertisement (마스터가 전송하는 헬스체크라고 보면 될 것이다)를 위한 주기를 의미한다, ver2 에서는 second 단위이지만 ver3 에서는 millisecond 단위이다.
- Checksum : 데이터 오류를 검출하기 위한 체크섬이다.
라우터가 가지는 상태값은 다음과 같다.
1. 가상 라우터 파라미터
- VRID : 가상 라우터의 식별자이다. 위에서 VRRP 프로토콜이 전송하는 패킷의 VRID와 같다.
- Priority : 가상라우터 마스터 선출에 참여하는 VRRP라우터의 우선 순위이다. 높을수록 우선 순위가 높다. 역시 위에서 설명한 것과 같다. (0 : 탈퇴, 255 : IP 점유)
- IP_Addresses : 가상 라우터에 연결된 IP이다. 이 IP가 VRRP라우터의 마스터-백업 전환시에 인계된다.
- Advertisement_Interval : Advertisement 주기이다. 역시 위에서 설명한 것과 같다.
- Skew_Time : 백업 라우터들이 동시에 행동하여 중복되는 것을 막기 위한 반응속도 차이이다. ((256 - Priority) / 256)초로 계산되며, Priotity가 높을수록 빠르게 반응한다는 것을 의미한다.
- Master_Down_Interval : 마스터가 다운되었음을 판단하는 주기이다. (3 * Advertisement_Interval) + Skew_time 으로 계산된다.
- Preempt_mode : 우선 순위가 높은 백업 라우터가 우선 순위가 낮은 마스터 라우터를 선점할지 여부를 결정한다. 기본값은 True이다. 값에 따른 차이를 살펴보자면 라우터1의 우선순위가 255 이고 라우터2의 우선순위가 100일 경우, 라우터1이 down 되면 라우터2가 MASTER state로 진입한다. 이 때 이 값이 True이면 라우터1이 살아났을 때 우선순위가 라우터2 보다 높기 때문에 다시 MASTER 상태를 선점하고 라우터2는 BACKUP state로 진입한다. 이 값이 False 일 때는 라우터2가 죽지 않는한 라우터1 이 라우터2 에 앞서 MASTER를 점유하지 않는다. 일반적으로는 우선 순위가 높은 VRRP라우터가 MASTER를 점유하지만, MASTER의 상태가 좋지 못해 재기동을 빈번하게 반복하는 상황이 발생한다면 이 것이 FALSE가 되도록 하는 것도 유효한 방법이다.
- Authentication_Type : 위에서 설명한 것과 같다. ver2 일 경우에는 큰 의미가 없다.
- Authentication_Data : Authentication_Type에 따라 사용하는 데이터이다.
2. 타이머
- Master_Down_Timer : MASTER는 주기적으로 ADVERTISEMENT를 전송한다. BACKUP이 이 값을 Master_Down_Timer 주기가 지나도록 수신하지 못했을 경우, 마스터가 다운된 것으로 판단하고, 백업은 마스터로 전환한다.
- Adver_Timer : MASTER로 행동할 때 Adversement_Interval 주기로 ADVERTISEMENT를 전송하는 타이머이다.
2. 상태전환
MASTER - BACKUP의 상태 전환 과정은 다음과 같다
각 단계는 다음과 같은 상태이다
- Initialize : Startup 이벤트를 대기하는 상태이다. Startup 이벤트가 수신되면 동작한다.
특정 라우터가 startup 되었을 때
- Priority = 255 라면 (가상 라우터에 할당된 IP를 점유한다면 255가 된다)
- ADVERTISEMENT 를 전송한다
- 가상라우터에 할당된 IP주소 및 MAC주소를 담아 GARP 요청을 송신한다. ARP 요청이 IP주소를 송신하여 대상의 MAC주소를 확인하는 과정이라면 GARP 요청 자신의 IP와 MAC을 담아 통지하는 절차이다. 만약 이 때 네트워크상에 해당 IP와 MAC을 사용하는 노드가 있다면 응답이 올 것이며 없다면, L2 스위치에서는 충돌 없이 MAC 주소를 갱신할 수 있다.
- Adver_Timer를 Advertisement_Interval로 설정하고 주기적으로 VRRP 패킷을 전송할 준비를 하고 MASTER 상태로 진입한다.
- Priority = 255가 아니라면
- Master_Down_Timer를 Master_Down_Interval로 설정하고 BACKUP 상태로 진입한다.
- Backup : 마스터 라우터의 가용성 및 상태를 감시 중인 상태이다.
- BACKUP 상태인 동안 VRRP 라우터는
- 가상 라우터와 관련된 IP의 ARP요청을 송신하지 않는다
- 가상 라우터 MAC 주소와 같은 패킷은 무시한다
- 가상 라우터와 관련된 IP주소로 오는 패킷을 수신하지 않는다.
- Shutdown 이벤트가 감지되면
- Master_Down_Timer를 취소하고 Initialize 상태로 진입한다.
- Master_Down_Timer 발동하였다면, MASTER로부터 ADVERTISEMENT를 받지 못해 MASTER에 문제가 생겼다는 말이고, Skew_Time을 감안하였을 때, Timer가 발동된 VRRP라우터가 우선 순위가 가장 높다는 말이다.
- MASTER의 FAIL이 감지된 상태이므로 자신의 ADVERTISEMENT를 송신하고, GARP 요청을 송신한 후
- Adver_Timer를 Advertisement_Interval로 설정하고 주기적으로 VRRP 패킷을 전송할 준비를 하고 MASTER 상태로 진입한다.
- ADVERTISEMENT를 수신하면
- 수신한 ADVERTISEMENT의 Priority가 0이라면, MASTER가 참여를 포기했다는 의미이므로 Master_Down_Timer를 Skew_Time으로 설정하고 즉시 대응할 준비를 한다.
- 수신한 ADVERTISEMENT가 0이 아닐 때, Preempt_Mode가 False 라면 자신의 Priority가 높더라도 선점을 포기한다는 의미이고, 수신한 ADVERTISEMENT가 자신의 Priority보다 높다면 마스터가 살아있거나, 자신보다 높은 Priority의 VRRP라우터가 선점에 나섰다는 의미이므로 BACKUP 상태를 유지하고, Master_Down_Timer를 Master_Down_Interval로 리셋하고 다음 VRRP패킷을 수신할 준비를 한다.
- 다른 경우에는 ADVERTISEMENT를 무시한다. (이 상태에서는 Master_Down_Timer 가 리셋되지 않았음에 유의한다. 자신보다 높은 Priority 의 ADVERTISEMENT 가 오지 않는 상태가 지속되면 Master_Down_Timer가 발동된다)
- Master : 가상 라우터에 연결된 IP주소에 대한 전달 라우터로 동작하는 상태이다.
- MASTER 상태인 동안 VRRP 라우터는
- 가상 라우터에 연결된 IP를 호출하는 ARP 요청에 응답한다.
- 가상 라우터 MAC 주소와 같은 링크 계층 MAC 주소가 있는 패킷을 전달한다.
- IP주소의 오너가 아니라면 가상 라우터에 연결된 IP로 지정된 패킷을 수신하지 않는다
- IP주소의 오너라면 가상 라우터에 연결된 IP로 지정된 패킷에 응답한다.
- Shutdown 이벤트가 감지되면
- Adver_Timer를 취소하고 ADVERTISEMENT를 더 이상 송신하지 않을 준비를 한다
- Priority = 0이 담긴 ADVERTISEMENT를 송신하여 VRRP에서 제외됨을 알린다.
- Initialize 상태로 진입한다.
- Adver_Timer 가 발동하면 ADVERTISEMENT를 송신하고, Adver_Timer를 Advertisement_Interval로 재설정하여 다음 ADVERTISEMENT를 송신할 준비를 한다.
- ADVERTISEMENT를 수신하였다면
- 0이라면 ADVERTISEMENT를 나도 송신하고, Adver_Timer를 리셋한다.
- 0이 아닌데, ADVERTISEMENT의 Priority가 Priority 보다 높거나 Priority는 같지만, IP주소가 크다면 해당 송신자에게 MASTER를 넘겨줄 준비를 해야하므로 Adver_Timer를 취소하고, Master_Down_Timer를 Master_Down_Interval로 설정한 후 BACKUP 상태로 진입한다.
- 이외의 경우는 해당 ADVERTISEMENT를 무시한다.
대략적인 VRRP의 개념은 다음과 같고 keepalived 에 대해서는 끊고 다음 포스팅에서 쓰도록해야겠다.
처음엔 keepalived 예제만 간단히 포스팅할 생각이었다. keepalived를 설치하고 동작을 확인하는 것까지는 그렇게 긴 시간이 소요되지 않았는데, 이것저것 찾아보다보니, 각종 옵션이 왜 그렇게 설정되어야 하는지, 그리고 블로그에 마다 올라온 것들이 약간씩 옵션을 다르게 주거나 시스템 설정을 왜 저렇게 하는지 찾아보다보니, 프로토콜의 기본 이론을 보게 되었고, 이번 포스트는 RFC3768 문서의 2~7절을 거의 통째로 옮긴 거나 다름 없게 되어버렸다.
그러면서 다른 책 보면서 찾은 내용이나 내가 이해한 내용을 약간씩 끼워넣은 정도? 그렇다고 아무리 그래도 데이터센터에서 일하는데, 내가 하는 게 뭔지도 모르고 쓸 수도 없는 노릇이고, keepalived 정도는 실제로 내가 운영을 하면서도 쓸 가능성이 충분히 있는 것이니, 어느 정도 잘 알고 쓰고 싶어서 기초를 다지는 기분으로 공부하고 정리 해 보았다.
그러면서 거의 4년만에 데이터센터 입문 교육 때 썼던 네트워크 교재도 찾아보고... 데이터센터에 근무하지만 개발 직군이라 가장 접할 일이 없는 것이 네트워크쪽이라 약해서 늘 마음에 걸렸는데 (사실 그렇게 따지면 스토리지 같은 건 아예 뭐가 있는지도 잘 모르지만...) 좀 열심히 공부해야겠단 생각이 들었다...
참고자료 :
- 24시간 365일 서버/인프라를 지탱하는 기술 (제이펍)
- 데이터 통신과 네트워크 원론, 실무를 중심으로 (기한재)
https://tools.ietf.org/html/rfc2338
https://tools.ietf.org/html/rfc3768
https://tools.ietf.org/html/rfc5798
https://m.blog.naver.com/PostList.nhn?blogId=goduck2 (오리뎅이의 네트워크 사랑방)
https://ipwithease.com/vrrp-v2-vs-v3/
'dev > Cloud & Infra' 카테고리의 다른 글
Kafka 보안 (1) - JAAS 및 SASL (1) | 2019.08.19 |
---|---|
High Availability 를 위한 VRRP와 keepalived (2) - keepalived (1) | 2019.05.02 |
Apache HTTP 구동시 Cannot load modules/mod_ssl.so into server: libssl.so.1.0.0: cannot open shared object file (0) | 2019.04.26 |
Apache httpd 를 컴파일로 설치하기 (0) | 2019.04.09 |
ElasticSearch Heap 사이즈 설정 (0) | 2019.02.03 |