🚀 요약
SUMMARY
서버를 1대에서 3대로 증설하던 중, 외부에서 VIP 접근은 되는데 내부 서버끼리 VIP로 통신하면 응답 패킷이 유실됐다. 원인은 Hairpinning(NAT Loopback)이었다. L4 담당 업체는 연락이 두절됐고 서비스 오픈은 몇 시간 앞이라, L4 매뉴얼을 뒤져 관련 옵션을 찾은 뒤 이중화된 두 장비 중 Active에만 먼저 적용해 정상화를 확인하고, 그다음 Standby로 확장했다.
⚙️ 환경
- L4 로드밸런서 2대, Active-Standby 이중화 (VIP를 Active가 점유, 장애 시 Standby로 승격)
- 국산 L4 스위치 (벤더·모델명 생략, CLI 설정 방식)
- 서비스 서버 3대, 전부 같은 내부 세그먼트에 위치
- VIP 하나로 서비스·DB 트래픽을 세 서버에 분산
💬 이슈
원래 서버 1대로 돌던 서비스를 후속 사업에서 3대로 스케일아웃(Scale-out)하는 작업이었다. 서버에 솔루션을 올리는 건 끝났고, 남은 건 VIP로 세 대에 트래픽을 분산하는 L4 로드밸런싱 설정이었다. 이건 L4 담당 업체 몫이었는데, 여기서 막혔다.
증상이 묘했다. 외부 네트워크에서 VIP를 호출하면 멀쩡히 응답이 왔다. 그런데 내부 서버끼리 VIP로 통신하면 요청은 서버에 도달하는데 응답 시점에서 패킷이 사라졌다. 서버 A가 VIP를 때리면 그 뒤에 물린 서버 B까지는 잘 가는데, B의 응답이 A로 돌아오지 못했다.
이게 전형적인 Hairpinning(또는 NAT Loopback) 현상이다. 흐름을 따라가 보면 이렇다.
- 서버 A가 VIP로 요청 → L4가 받아서 실서버 B로 DNAT(목적지 주소 변환)
- B는 요청을 처리하고 응답을 보내는데, 응답의 목적지는 A의 실제 IP다
- A와 B는 같은 서브넷이라, B는 L4를 거치지 않고 A에게 직접 응답을 쏜다
- A 입장에선 VIP로 연결을 열었는데 생판 모르는 B의 IP에서 응답이 온다 → 이 패킷은 내가 연 커넥션이 아니니 버린다
머리핀처럼 트래픽이 L4에서 U턴해 같은 대역으로 돌아가는데, 돌아가는 길(리턴 패스)이 비대칭이라 깨지는 것이다. 외부에서 오는 트래픽은 A와 B가 다른 대역이니 응답이 자연히 L4를 거쳐 대칭이 되지만, 내부망 안에서는 지름길이 생겨버린다.
하필 L4 담당 업체가 연락이 안 됐다. 그리고 서비스 오픈은 몇 시간 뒤였다. 남이 관리하는 네트워크 장비를 내가 건드리는 건 부담스러운 일이지만, 손 놓고 있을 수는 없었다.
🧗 해결
1. 매뉴얼에서 옵션 찾기
L4 장비의 온라인 매뉴얼을 확보해 Hairpinning·NAT Loopback 관련 설정을 뒤졌다. 장비마다 부르는 이름이 다른데, 이 장비에선 내부망끼리의 VIP 통신을 처리하는 LAN-to-LAN 계열 옵션이 있었다. 핵심 동작은 Source NAT(출발지 주소 변환)다.
리턴 패스가 비대칭인 게 문제였으니, 해결은 응답을 억지로 L4로 되돌려 보내는 것이다. L4가 실서버로 요청을 넘길 때 출발지 IP를 요청자(A)가 아니라 L4 자신의 IP로 바꿔주면(Full NAT), 실서버 B는 응답을 L4에게 보낸다. L4는 그 응답을 받아 원래 요청자 A에게, 출발지를 VIP로 되돌려 전달한다. 그러면 A가 보기엔 VIP에서 온 정상 응답이 되고 커넥션이 성립한다. 지름길을 막고 왕복 경로를 L4로 강제하는 셈이다.
NOTE
Hairpinning은 L4가 이상한 게 아니라, 로드밸런서 뒤 실서버와 클라이언트가 같은 세그먼트에 있을 때 구조적으로 생기는 문제다. 외부 트래픽만 상정하고 구성하면 내부망 통신을 테스트할 때야 드러난다. 그래서 오픈 직전까지 안 보였던 것이다.
2. Active 먼저, Standby는 나중에
L4는 Active-Standby 이중화였다. 두 장비를 동시에 건드리는 건 최악의 수다. 설정이 잘못되면 Active와 Standby가 같이 망가져 페일오버(Failover)라는 안전장치까지 통째로 날아간다. 남의 장비를, 검증도 안 된 변경을, 이중화 양쪽에 한 번에 넣는 건 리스크를 두 배로 지는 짓이다.
그래서 순서를 이렇게 잡았다.
- Standby는 손대지 않고 그대로 둔다. 이게 롤백 플랜이다. Active를 고치다 장비가 죽어도 VIP가 Standby로 넘어가면 최소한 지금 상태(고장 난 채로)는 유지된다.
- Active 장비 CLI에만 접속해 LAN-to-LAN 옵션을 적용한다.
- 내부 서버에서 VIP 통신이 정상화되는지 확인한다.
- 확인이 끝나야 비로소 Standby에도 같은 설정을 넣는다.
고객사 PM에게 상황과 이 순서를 설명하고, 담당 업체 부재 상황에서 직접 손대겠다고 자청해 승인을 받았다. 다행히 사내에서 UTM 장비 CLI를 만져본 경험이 있어서, 벤더는 달라도 설정 체계가 아주 낯설지는 않았다. Standby는 그대로 둔 채 Active 장비 CLI에만 접속해 LAN-to-LAN 옵션을 적용했다.
✅ 확인
Active에만 넣은 상태에서 내부 서버 간 VIP 통신을 다시 확인했다. 아까 응답이 사라지던 요청이 정상적으로 왕복했다.
Active 쪽에서 내부 VIP 통신이 정상인 걸 확인한 뒤에야 Standby 장비에도 동일 설정을 적용했다. 이렇게 하면 Standby 반영 도중 문제가 생겨도 이미 정상화된 Active가 VIP를 쥐고 있으니 서비스는 계속 뜬다.
변경한 설정 내용은 담당자에게 문서로 공유해, 다음에 같은 증상이 나와도 참고할 수 있게 남겼다. 결과적으로 오픈 몇 시간 전에 터진 장애를 약 한 시간 안에 막았고, 일정대로 서비스를 열었다.
내 담당 범위가 아닌 장비를 건드리는 건 지금 생각해도 부담스러운 선택이었다. 다만 서비스 오픈이 코앞이라 시도하지 않을 수도 없었고, “고치더라도 이중화 안전망은 끝까지 살려둔다”는 순서 하나로 최악은 피할 수 있었다. 어렵게 느껴지던 네트워크 쪽을 직접 파고들어 막아낸 덕에, 고객사와의 신뢰도 한층 쌓였다.