[IT 심층 분석]
Docker 컨테이너 간 Overlay 네트워크의 패킷 드랍 미스터리와 VXLAN MTU 불일치 원인 규명
김민준 · IT 시스템 엔지니어|
쿠버네티스 클러스터 위에서 운영 중인 마이크로서비스들 사이에 간헐적인 요청 실패가 발생해 온콜 엔지니어팀의 슬랙 채널이 시끄러워지기 시작했습니다. 개별 서비스를 단독으로 테스트하면 전혀 문제가 없었으나 서비스 A가 서비스 B를 호출하는 체인 형태의 실제 프로덕션 요청 흐름에서만 특정 확률로 일부 응답이 소실되는 현상이었습니다. 서비스 메시도 아닌데 이런 형태의 간헐적 패킷 드랍은 대개 레이어 2 또는 레이어 3 수준의 네트워크 인프라 문제를 가리키는 신호입니다.
컨테이너 간 통신 경로를 따라 패킷을 추적해 보았습니다. 쿠버네티스의 Pod 간 통신은 VXLAN이라는 기술을 이용해 물리 네트워크 위에 가상 오버레이 터널을 만들어 이루어집니다. 이 VXLAN 터널은 원래 이더넷 프레임에 추가적인 헤더 캡슐화를 씌우게 됩니다. 이 캡슐화로 인해 최종 패킷의 크기는 원본보다 50바이트 가량 더 커집니다. 여기서 충돌이 발생했습니다. 물리 네트워크 스위치의 MTU(Maximum Transmission Unit) 즉 한 번에 전송 가능한 최대 패킷 크기 설정값은 기본값인 1500바이트로 고정되어 있었는데 VXLAN 오버헤드가 더해진 컨테이너 패킷은 이 한도를 초과하게 됩니다. 일부 스위치는 이 초과 크기 패킷을 잘게 쪼개는 PTB(Packet Too Big) 처리를 했지만 일부 경로는 그냥 조용히 버려버리는 블랙홀 라우터처럼 행동하고 있었습니다.
이 MTU 불일치 문제를 해결하는 방법은 두 방향이 있습니다. 하나는 물리 네트워크 스위치 전체의 MTU를 점보 프레임 크기인 9000바이트 이상으로 올리는 것입니다. 이는 인프라 팀의 협조를 받아 스위치 설정을 변경해야 하므로 절차가 복잡합니다. 다른 방법은 쿠버네티스 오버레이 네트워크 설정에서 각 컨테이너 인터페이스(veth)의 MTU를 1450바이트 수준으로 낮추는 것입니다. 이렇게 하면 VXLAN 헤더가 붙어도 최종 패킷이 1500바이트 한도를 초과하지 않게 됩니다. 저희는 후자를 택하여 CNI(Container Network Interface) 플러그인의 설정 파일에서 mtu 값을 조정하고 DaemonSet을 재배포했습니다. 변경 후 패킷 드랍율은 클러스터 모니터링 대시보드에서 완벽하게 0으로 귀환했고 서비스 간 통신 안정성은 완전히 회복되었습니다.