CS/Linux

[Linux] 네트워크 인터페이스와 Docker 네트워크 트래픽 구조 분석

kyoulho 2025. 7. 30. 19:01

Docker에서 발생하는 트래픽 흐름을 분석하려면 리눅스의 네트워크 인터페이스(NIC) 구조를 먼저 이해해야 합니다. 이 글은 리눅스 NIC 종류 설명, Docker 네트워크 구성, 그리고 컨테이너 간 트래픽 경로 분석까지 모두 담은 실무 중심 가이드입니다.


리눅스 네트워크 인터페이스 종류 정리 (NIC 종류)

인터페이스 설명 활용
ens3, eth0, enp0s3 시스템이 부팅될 때 자동으로 할당되는 물리 네트워크 카드 또는 클라우드 환경의 가상 NIC. ens3처럼 Predictable Naming 방식이 주로 사용됨. 외부 통신의 입구이자 출구. 실제 인터넷, 사내망, VPN 연결. 보안 설정, 방화벽, 라우팅 테이블의 핵심 대상.
lo (Loopback) 자기 자신과 통신하는 전용 가상 인터페이스. 항상 127.0.0.1 (localhost) 주소를 가짐. 커널 수준에서 네트워크 스택을 거치지만 실제 NIC를 타지 않음. 웹서버(nginx), DB(redis, postgres 등) 등 내부 서비스 바인딩 시 사용. 테스트, 모니터링, 시스템 간 RPC 호출 시 자주 활용.
br-xxxxxx, docker0 Docker가 컨테이너 간 통신을 위해 생성하는 가상 브리지. 스위치처럼 작동하여 여러 veth 인터페이스를 같은 네트워크에 묶음. docker0는 기본 브리지 이름이며, 사용자 정의 네트워크는 br-xxxxx 형태. 동일 브리지에 연결된 컨테이너는 서로 직접 통신 가능. Nginx 리버스 프록시, 서비스 메시 구성 시 기본 통로. brctl, ip link로 상태 확인 가능.
vethXXXX Virtual Ethernet Pair. 양 끝단이 연결된 가상 케이블. 하나는 컨테이너의 eth0, 다른 하나는 호스트의 브리지(br-xxxxx)에 연결됨. 네임스페이스 간 통신을 위한 핵심 구조. 컨테이너 ↔ 호스트 간 트래픽 분석 시 사용. tcpdump, iptables, conntrack으로 정밀 디버깅 가능. 서비스 지연이나 연결 실패 시 주요 추적 포인트.

리눅스 네트워크 인터페이스 연결 구조 (NIC 연결 다이어그램)

[컨테이너 eth0]
   ↓
[veth1234]  ←→  [veth5678]
                 ↓
           [br-docker0]
                 ↓
           [ens3 (호스트 NIC)]

이 구조는 Docker가 브리지 네트워크 모드를 사용할 때 기본적으로 생성하는 네트워크 경로입니다.

  • veth pair: 컨테이너와 호스트 간 데이터 전송, 호스트의 veth와 컨테이너 내부에 veth가 한쌍
  • br-xxx: 가상 스위치로 veth들을 연결
  • ens3: 외부와 통신할 수 있는 네트워크 출구
  • lo: 내부 트래픽만 다룸 (NIC 바깥으로 안 나감)

Docker 컨테이너가 호스트 IP로 요청할 때 트래픽 흐름

트래픽 흐름 요약

프론트 컨테이너에서 http://192.168.105.17:8080로 요청이 발생했을 때 다음과 같은 경로를 거칩니다:

[프론트 컨테이너]
   ↓ veth pair (eth0 <-> vethX)
[Docker 브리지 (br-front)]
   ↓
[SNAT: src 172.X → 192.168.105.17]
   ↓
[호스트 커널]
   ↓ 루프백 처리
[DNAT: 192.168.105.17:8080 → 172.Y.0.3:8080]
   ↓
[브리지 (br-back)]
   ↓ veth pair
[백엔드 컨테이너]

단계별 분석: 리눅스와 Docker 네트워크 트래픽 내부 구조

1. 프론트 컨테이너 → 요청 시작

  • 컨테이너 내부 애플리케이션에서 http://192.168.105.17:8080 요청
  • 이는 외부 요청처럼 간주됨

2. veth pair를 통해 호스트로 이동

  • eth0 → vethX 쌍을 따라 리눅스 네임스페이스를 넘나듬

3. Docker 브리지 통과

  • vethX가 연결된 br-front를 거쳐 커널 네트워크 스택으로 이동

4. SNAT 변환 (Source NAT)

  • 출발지 IP가 172.X.X.X → 192.168.105.17로 변경
  • iptables의 MASQUERADE 규칙 적용

5. 커널에서 루프백 경로로 처리

  • 목적지가 자신(192.168.105.17)이므로 외부 NIC를 거치지 않음

6. DNAT 변환 (Destination NAT)

  • iptables에 의해 목적지 IP가 컨테이너 내부 IP로 변경
  • 예: 192.168.105.17:8080 → 172.Y.0.3:8080

7. br-back 브리지를 통해 백엔드 컨테이너로 이동


🧷 반드시 알아야 할 핵심 개념

개념 설명 영향
SNAT 컨테이너 출발지 IP → 호스트 IP 응답이 되돌아오는 경로 확보. 없으면 timeout 발생
DNAT 호스트 목적지 IP → 컨테이너 내부 IP 포트 매핑에 기반한 포워딩. 잘못되면 응답 없음
루프백 처리 호스트 IP로 향한 패킷은 커널 내부 처리 tcpdump -i ens3로는 보이지 않음
conntrack NAT 상태 추적 및 연결 매핑 커널 자원 부족 시 연결 추적 실패
브리지 컨테이너를 L2 수준에서 묶는 스위치 역할 brctl show, ip link 등으로 연결 상태 확인

📎 관련 명령어 실무 예시

  • ip a : 인터페이스 상태 및 IP 확인
  • brctl show : 브리지에 연결된 NIC 목록 확인
  • tcpdump -i any port 8080 : 트래픽 흐름 추적
  • iptables -t nat -L -n -v : NAT 변환 규칙 확인
  • conntrack -L : 연결 추적 상태 보기

🔚 마무리: Docker 네트워크 흐름의 본질은 리눅스 커널이다

Docker의 네트워크는 단순히 "컨테이너끼리 통신한다" 수준이 아닙니다. 실제로는 리눅스 커널 네트워크 네임스페이스, iptables NAT, 브리지, 루프백, veth 등이 유기적으로 작동하여 만들어진 구조입니다.

이해하고 나면 다음과 같은 문제가 쉽게 해결됩니다:

  • “포트는 열려 있는데 접속이 안 돼요”
  • “tcpdump 해도 아무 것도 안 보여요”
  • “컨테이너 응답이 timeout 나요”