계층으로 좁히는 네트워크 디버깅
네트워크 장애를 추측으로 처리하지 않고, L3부터 L7까지 계층별로 좁혀 가는 관점을 다룹니다. 패킷 캡처, 경로 추적, VPC Flow Logs, 컨테이너 디버깅 도구를 어떤 상황에서 선택할지 정리합니다.
Script Companion
오디오와 함께 스크립트 보기
- 01
네트워크 디버깅에서 먼저 잡아야 할 관점은 증상과 원인의 위치가 다를 수 있다는 점입니다. API가 안 된다는 말은 L7에서 보이는 증상이지만, 실제 원인은 DNS 오설정, Security Group 누락, TCP 타임아웃처럼 더 아래 계층에 있을 수 있습니다. 그래서 서버 재시작이나 배포 롤백을 반복하기 전에, 어느 계층에서 끊기는지 먼저 좁혀야 합니다. 추측 디버깅은 MTTR을 늘리고, 계층별 체크리스트는 원인 후보를 빠르게 줄이는 장치가 됩니다.
- 02
기본 흐름은 L3, DNS, L4, L7 순서로 확인하는 것입니다. L3에서는 네트워크 도달성 자체를 보고, DNS에서는 이름이 올바른 주소로 해석되는지 확인합니다. L4에서는 포트와 TCP 연결 가능성을 보고, L7에서는 실제 HTTP 응답과 애플리케이션 동작을 봅니다. 이 순서가 중요한 이유는 위 계층의 실패가 아래 계층의 실패를 감추기 때문입니다. 브라우저 DevTools의 Network 탭에서 익숙하게 보던 요청 실패도, 서버 사이드 도구와 연결하면 더 넓은 풀스택 디버깅으로 이어집니다.
- 03
패킷 캡처 도구를 고를 때는 실행 환경과 분석 깊이를 나눠 봐야 합니다. tcpdump는 CLI 환경에서 SSH로 사용할 수 있고, BPF 커널 필터 덕분에 CPU 부하와 패킷 드롭 위험이 낮아 프로덕션 실시간 캡처에 적합합니다. tshark도 CLI에서 사용할 수 있지만 실시간 디코딩이 들어가면 부하가 더 커지고, BPF를 쓰지 않으면 패킷 드롭 위험이 2~5배 높아질 수 있습니다. Wireshark는 분석 깊이가 가장 좋지만 GUI 렌더링 부담이 있어 개발이나 스테이징 심층 분석에 더 맞습니다.
- 04
권장 흐름은 프로덕션에서 tcpdump로 pcap 파일을 남기고, 그 파일을 로컬로 가져와 Wireshark로 분석하는 방식입니다. tshark는 캡처 파일을 오프라인으로 분석할 때 적합합니다. 여기서 기억할 점은 tcpdump가 애플리케이션 로그보다 낮은 위치에서 사실을 보여준다는 것입니다. 앱 로그에는 요청이 없는데 tcpdump에서 RST가 보인다면, 적어도 패킷 수준에서는 그 종료 신호가 실제로 있었던 것입니다. 반대로 tcpdump에 패킷이 보이는데 앱이 못 받는다면 커널 레벨의 차단도 의심해야 합니다.
- 05
경로 추적 도구는 traceroute와 mtr의 역할이 다릅니다. traceroute는 지금 경로가 어디로 가는지 빠르게 보는 1회 스냅샷에 가깝고, 초기 확인에 적합합니다. mtr은 시간에 따라 수십 번에서 수백 번의 결과를 모아 손실률, 평균 지연, 표준편차 같은 누적 통계를 보여줍니다. 그래서 10분에 한 번씩 패킷이 드롭되는 간헐적 문제는 traceroute보다 mtr이 더 잘 맞습니다. 에스컬레이션할 때도 mtr 리포트는 지속적인 손실과 레이턴시를 설명하는 증거가 됩니다.
- 06
VPC Flow Logs에서 REJECT가 보이는데 Security Group은 열려 있다면 NACL을 봐야 합니다. Security Group은 Stateful이라 응답을 자동으로 허용하지만, NACL은 Stateless라서 인바운드와 아웃바운드를 각각 봅니다. 특히 NACL 아웃바운드 규칙에서 임시 포트, 즉 ephemeral port 1024-65535가 차단되어 있으면 응답 패킷이 돌아가지 못할 수 있습니다. 소스 서브넷의 NACL 아웃바운드 규칙이 제한된 경우도 같은 방향으로 의심합니다. Flow Logs는 이런 방화벽 계층의 차단 여부를 확인하는 핵심 근거가 됩니다.
- 07
쿠버네티스 환경에서는 내부와 외부의 성공 여부를 나눠 봐야 합니다. kubectl exec 내부에서는 접속되는데 클러스터 외부에서는 실패한다면 애플리케이션 자체보다 노출 경로가 문제일 수 있습니다. Ingress가 없거나 Ingress Controller가 실행되지 않는 경우, ALB나 NLB Security Group에서 인바운드 443이 열려 있지 않은 경우, Route 53 레코드가 없거나 잘못된 IP를 가리키는 경우가 후보입니다. 443 포트가 열려 있어도 TLS 인증서 오류 때문에 핸드셰이크가 실패할 수 있으므로, openssl을 통한 인증서 확인도 중요한 점검 축이 됩니다.
- 08
또 다른 패턴은 tcpdump로 패킷은 보이는데 애플리케이션이 요청을 못 받는 경우입니다. 패킷이 NIC 레벨에서는 수신되지만 iptables가 커널 레벨에서 DROP하면 앱까지 올라오지 못합니다. Docker, Kubernetes, 직접 작성한 iptables 규칙이 트래픽을 막을 수 있고, conntrack 테이블이 가득 찬 경우에도 비슷한 증상이 나타날 수 있습니다. 컨테이너에 필요한 도구가 없을 때는 프로덕션 이미지를 바꾸는 대신 nsenter 또는 kubectl debug로 디버깅 경로를 열 수 있습니다. 네트워크 성능 자체가 의심될 때는 iperf3로 대역폭을 측정합니다.
- 09
정리하면 네트워크 디버깅은 한 번에 정답을 찍는 일이 아니라, 계층별로 관측 지점을 옮기며 후보를 줄이는 일입니다. L3에서 도달성을 보고, DNS에서 이름 해석을 보고, L4에서 연결을 보고, L7에서 실제 요청을 봅니다. 브라우저 DevTools의 TTFB는 ALB 로그의 target_processing_time과 연결해 서버 처리 시간을 볼 수 있고, TIME_WAIT는 정상 종료 후 대기인 반면 CLOSE_WAIT는 서버가 연결을 닫지 않는 코드 버그로 구분합니다. 이 구분들이 쌓이면 증상은 위에 있어도 원인은 아래에서 찾을 수 있습니다.
같은 레이어