Docker와 네트워크 통신 흐름

권경희·2024년 12월 29일

아래 설명은 위 이미지와 같은 NAT 설정이 있고, docker run -d --name webserver 8080:80 nginx 로 실행한 컨테이너가 있을때 통신의 흐름을 정리한 내용입니다.
VirtualBox 위에 Ubuntu VM(docker라는 이름), 그 내부에서 Docker 데몬이 동작하는 상황을 가정하고,

  • 호스트(실제 PC) ↔ VirtualBox VM(NAT) ↔ Docker 컨테이너(bridge)
    구조에서 IP/포트가 어떻게 매핑되고, 실제 데이터가 어떤 경로로 흐르는지 단계별로 풀이한 내용입니다.

전체 시나리오 개요

  1. VirtualBox NAT 네트워크

    • IP 대역: 10.100.0.0/24
    • 예: VM(게스트)에게 10.100.0.105 할당, 게이트웨이(가상 라우터) 10.100.0.1(또는 내부에서 별도 할당)
    • 포트 포워딩 규칙 예시:
      • 호스트 IP: 127.0.0.1
      • 호스트 포트: 105
      • → 게스트(VM) IP: 10.100.0.105
      • 게스트 포트: 22 (SSH)
  2. Ubuntu VM 내부

    • IP: 10.100.0.105 (NAT 네트워크 상에서)
    • 여기에서 Docker 엔진(docker daemon)이 동작 중
    • Docker는 기본적으로 docker0 브리지를 만드는데, 보통 이 브리지의 게이트웨이 IP가 172.17.0.1이 됨.
    • 컨테이너들은 172.17.0.0/16 대역에서 IP를 할당받음. 예: 172.17.0.2, 172.17.0.3
  3. Docker 컨테이너

    • docker run -d --name webserver -p 8080:80 nginx
      • 컨테이너 내부 포트 80을 VM(호스트 OS 입장에서는 “게스트”)의 8080번 포트와 연결(-p 8080:80).
    • 즉, Ubuntu VM 입장에서는 “0.0.0.0:8080 → 컨테이너(172.17.0.x:80)” 형태로 포트 매핑이 이루어짐.
    • 컨테이너 내부의 기본 게이트웨이는 172.17.0.1(docker0 브리지)

1. SSH 예시: 호스트에서 VM(게스트)로 접속할 때의 흐름

아래는 “호스트에서 ssh를 통해 127.0.0.1:105로 접속할 때, 실제로 VM 내부 10.100.0.105:22로 연결되는 경로”를 단계별로 나타낸 것입니다.

┌─────────────────────────────┐
│ ① 호스트 PC                │
│   (예: Windows, IP 다양)   │
│                           │
│  ssh 127.0.0.1 -p 105     │
└──────────────┬──────────────┘
               │
               │  (포트 포워딩 규칙: 127.0.0.1:105 → 10.100.0.105:22)
               ▼
┌─────────────────────────────┐
│ ② VirtualBox NAT 엔진     │
│   - NAT 네트워크: 10.100.0.0/24
│   - 'localhost' 라는 NAT 이름
└──────────────┬──────────────┘
               │
               │  (포트 포워딩 수행)
               ▼
┌─────────────────────────────┐
│ ③ Ubuntu VM (docker)      │
│   - IP: 10.100.0.105      │
│   - SSH 데몬 : 22번 포트    │
│   - 여기서 Docker도 동작 중  │
└──────────────────────────────┘
  1. 호스트 PC에서 ssh 127.0.0.1 -p 105 명령 실행
  2. VirtualBox가 NAT 규칙을 확인해, “호스트의 105번 포트로 들어온 트래픽은 VM의 10.100.0.105:22로 전달”
  3. VM 내부의 SSH 서버(22)에서 연결을 받아 응답
  4. 결과적으로 호스트가 VM에 SSH 접속 성공

2. Docker 컨테이너에서의 포트 매핑: -p 8080:80 예시

2-1. Ubuntu VM 내부(게스트 OS) 관점

  • 우리가 docker run -d --name webserver -p 8080:80 nginx 명령을 VM에서 실행했다고 가정합니다.
  • 이때, VM 입장에서는 “자신의 8080번 포트에 들어온 연결을 컨테이너 내부 80번 포트로 전달”합니다.
  • 즉, VM에서 curl http://localhost:8080 을 하면 Docker가 알아서 컨테이너(172.17.0.x:80)로 패킷을 라우팅해줍니다.
┌───────────────────────┐
│ Ubuntu VM           │
│  - IP: 10.100.0.105 │
│  - Port 8080 ↔      ├──> (docker0 브리지)
│    Container:80     │
└───────────────────────┘

2-2. Docker 네트워크(bridge) 내부 관점

  • 기본적으로 docker0라는 가상 브리지 인터페이스가 생기며, 게이트웨이 IP는 172.17.0.1.
  • 컨테이너는 이 브리지 통해서 IP를 하나씩 할당받습니다. 예) 172.17.0.2
  • 그러면 컨테이너 webserver172.17.0.2:80에서 Nginx가 동작 중이고, Docker가 iptables/NAT 규칙을 이용해 VM의 8080 → 172.17.0.2:80 으로 트래픽을 포워딩합니다.
( VM 내부 )
┌─────────────────────────────────┐
│ docker0 (가상 브리지)          │
│  IP: 172.17.0.1 (게이트웨이)   │
│         │                    │
│         └─────────────────────┬┘
│                              ▼
│  Container IP: 172.17.0.2:80 (Nginx)
│
└─────────────────────────────────┘

2-3. 만약 호스트 PC에서 컨테이너에 접근하려면?

  • 현재까지 설정은 “VM 내부 8080 ↔ 컨테이너 80”만 있지, 호스트 → VM:8080 포트 포워딩은 설정하지 않았다고 가정합니다.
  • 호스트에서 127.0.0.1:8080으로 접근하려면, 추가로 VirtualBox NAT의 포워딩 규칙을 만들어야 합니다. 예:
    • 호스트 IP: 127.0.0.1
    • 호스트 포트: 8080
    • 게스트 IP: 10.100.0.105
    • 게스트 포트: 8080
  • 이렇게 해야 호스트가 http://127.0.0.1:8080으로 접속할 때, VM의 8080에 도달하고, 그 후에 Docker가 컨테이너 80으로 전달해 줄 수 있습니다.

3. 컨테이너에서 외부로 나가는 통신 흐름

컨테이너가 외부 인터넷이나 호스트에 접속할 때는 다음 흐름으로 진행됩니다.

  1. 컨테이너: 예) IP 172.17.0.2 → 게이트웨이 172.17.0.1(docker0)로 패킷 전송
  2. Ubuntu VM 내부 커널: docker0로 들어온 패킷을 VM의 NAT(또는 IP 포워딩/마스커레이드) 규칙에 따라 VM의 IP(10.100.0.105)로 SNAT 변환하여 VirtualBox NAT로 보냄
  3. VirtualBox NAT: VM의 IP(10.100.0.105) → 호스트 또는 외부 인터넷으로 패킷 중계
  4. 호스트(또는 외부망)까지 도달

정리하면, 컨테이너 → (172.17.0.1) → VM(10.100.0.105) → (VirtualBox NAT) → 호스트/외부 순으로 라우팅이 일어납니다.


4. 단계별 IP·포트 흐름 정리 (예시)

시나리오: “호스트 → 웹서버 컨테이너” 접근

  1. 호스트

    • IP/포트: 127.0.0.1:8080 (가정)
    • → VirtualBox NAT 포트포워딩 규칙에서 ‘8080’을 감지, VM으로 전달
  2. VirtualBox NAT

    • “호스트 127.0.0.1:8080 → 게스트 10.100.0.105:8080” 매핑
    • 패킷을 VM의 8080 포트로 전달
  3. Ubuntu VM(docker)

    • 수신: 10.100.0.105:8080
    • Docker 엔진의 iptables 설정에 의해
      • 10.100.0.105:8080172.17.0.2:80 (컨테이너 IP) 로 NAT/포워딩
  4. 컨테이너(webserver)

    • 최종 수신: 172.17.0.2:80
    • Nginx가 요청을 처리하고, 응답은 역순으로 다시 돌아감
┌─────────────┐        ┌─────────────────────────────────┐
│ (1) Host    │       │ (2) VirtualBox NAT           │
│127.0.0.1:8080│      │  10.100.0.0/24 -> VM:8080    │
└────┬────────┘        └──────────────┬──────────────────┘
     │                                 │
     │ (포트포워딩)                     │
     ▼                                 ▼
┌────┴─────────────────────────────────┐
│ (3) Ubuntu VM (10.100.0.105)      │
│   Docker -p 8080:80 ->            │
│   docker0 : 172.17.0.1 (게이트웨이) │
└────┬─────────────────────────────────┘
     │ (iptables / NAT)
     ▼
┌────┴────────────────────────────┐
│ (4) Container (172.17.0.2:80)│
│   webserver(Nginx)           │
└─────────────────────────────────┘

5. 각각의 IP/포트 역할 요약

  1. NAT 네트워크 10.100.0.0/24

    • VirtualBox가 만든 가상 네트워크 대역
    • VM(게스트)에 10.100.0.xxx IP를 할당, 외부(호스트)와 NAT 통해 통신
  2. 호스트 IP/포트 127.0.0.1:105 (또는 8080 등)

    • 실제 PC에서 접근하는 루프백 주소 + 특정 포트
    • VirtualBox NAT 설정에서 이 포트가 게스트 VM으로 포워딩됨
  3. 게스트 IP/포트 10.100.0.105:22

    • VM 내부의 SSH가 22번 포트로 열려 있음
    • 포트포워딩 규칙 덕분에 호스트의 :105 → VM의 :22로 매핑
  4. Docker bridge 게이트웨이 172.17.0.1

    • VM 내부에서 Docker가 만들어낸 가상 브리지(docker0)의 IP
    • 컨테이너들은 172.17.0.0/16 대역의 IP를 할당받고, 게이트웨이로 172.17.0.1을 사용
  5. Container IP 172.17.0.x:80 (예: 172.17.0.2:80)

    • webserver 컨테이너가 실제로 할당받은 IP와 포트(내부 웹 서버)
    • -p 8080:80 옵션으로 VM의 8080과 연결

결론 정리

  • VirtualBox NAT (10.100.0.0/24)와 Docker bridge (172.17.0.0/16)는 서로 다른 계층의 NAT/가상 네트워크입니다.
  • “호스트 → 127.0.0.1:포트” 형태로 접속하면, VirtualBox가 포트 포워딩 규칙에 따라 VM(10.100.0.105)의 특정 포트로 패킷을 전달합니다.
  • VM 내부에선 Docker가 다시 -p 옵션 등으로 “VM의 포트 ↔ 컨테이너 포트”를 연결합니다.
  • 컨테이너가 외부와 통신할 땐 “컨테이너 IP(172.17.0.x) → 브리지 게이트웨이(172.17.0.1) → VM IP(10.100.0.105) → VirtualBox NAT → 호스트/인터넷” 순으로 패킷이 오갑니다.

결국, IP/포트가 여러 겹으로 계층화되어 있지만, 각각의 포트 포워딩(또는 NAT) 규칙에 맞춰 요청이 전달되며, 가상화와 컨테이너 네트워킹이 함께 동작하는 것입니다.

0개의 댓글