포스트

Docker 포트 매핑 동작 원리

Docker 포트 매핑 동작 원리

Docker 포트 매핑은 내부적으로 어떻게 동작할까?

기초편에서 -p 8080:8080 옵션으로 포트를 연결했는데, 이게 내부적으로 어떻게 동작하는지 살펴보자.


docker run 실행 순간 (세팅 단계)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[ 개발자 ]
   ↓
docker run -p 8080:1122
   ↓
┌─────────────────────── 호스트 OS ───────────────────────┐
│                                                        │
│  1) 컨테이너 생성                                         │
│     ┌──────── 컨테이너 ────────┐                         │
│     │ IP: 172.17.0.2         │                         │
│     │                        │                         │
│     │   Spring :1122 실행     │                         │
│     └────────────────────────┘                         │
│                                                        │
│  2) docker0 네트워크 연결                                 │
│        (컨테이너를 내부 네트워크에 붙임)                      │
│                                                       │
│  3) iptables 룰 등록                                    │
│     "HOST:8080 → 172.17.0.2:1122"                     │
│                                                       │
└───────────────────────────────────────────────────────┘

여기까지가 “준비 완료 상태”. 아직 요청 없음.

  • docker0: Docker가 만드는 가상 네트워크 브릿지. 컨테이너들은 이 네트워크에 연결되어 호스트와 통신한다.
  • iptables: 리눅스 커널의 네트워크 패킷 제어 도구. Docker는 여기에 포워딩 규칙을 등록한다.

요청 발생부터 응답까지

1. 브라우저가 요청을 보낸다

1
2
3
[ 브라우저 ]
   ↓
http://localhost:8080 요청

2. 호스트 OS 진입

1
2
3
4
5
6
7
┌─────────────────────── 호스트 OS ───────────────────────┐
│                                                       │
│  localhost:8080 요청 도착                               │
│                                                       │
│  "이거 어디로 보내지?"                                     │
│                                                       │
└───────────────────────────────────────────────────────┘

3. iptables 룰 적용

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─────────────────────── 호스트 OS ───────────────────────┐
│                                                       │
│  [ iptables ]                                         │
│                                                       │
│  조건: port == 8080                                    │
│     ↓                                                 │
│  목적지 변경 (DNAT)                                      │
│                                                       │
│  localhost:8080                                       │
│        ↓                                              │
│  172.17.0.2:1122                                      │
│                                                       │
└───────────────────────────────────────────────────────┘

핵심: 여기서 목적지 주소가 바뀐다. (Destination NAT)

4. docker0 네트워크를 통해 컨테이너로 이동

1
2
3
4
5
6
7
8
9
┌─────────────────────── 호스트 OS ───────────────────────┐
│                                                       │
│  172.17.0.2:1122                                      │
│        ↓                                              │
│  [ docker0 브릿지 ]                                     │
│        ↓                                              │
└───────────────┬───────────────────────────────────────┘
                │
                ▼

5. 컨테이너 도착

1
2
3
4
5
6
7
8
9
10
                ▼
      ┌──────── 컨테이너 ─────────┐
      │ IP: 172.17.0.2          │
      │                         │
      │   요청 도착               │
      │        ↓                │
      │   Port 1122             │
      │        ↓                │
      │   [ Spring 서버 ]        │
      └─────────────────────────┘

6. Spring 서버가 응답을 생성한다

1
2
3
4
5
6
7
      ┌──────── 컨테이너 ─────────┐
      │   [ Spring 서버 ]        │
      │        ↓                │
      │   응답 생성               │
      └────────┬────────────────┘
               │
               ▼

7. 응답이 호스트로 복귀

1
2
3
4
5
6
7
8
               ▼
┌─────────────────────── 호스트 OS ───────────────────────┐
│                                                       │
│   [ docker0 ]                                         │
│        ↓                                              │
│   172.17.0.2 응답 도착                                  │
│                                                       │
└───────────────────────────────────────────────────────┘

8. 역 NAT (응답 주소 복원)

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────── 호스트 OS ───────────────────────┐
│                                                       │
│  [ iptables ]                                         │
│                                                       │
│  "이건 원래 8080 요청이었음"                               │
│                                                       │
│  172.17.0.2:1122                                      │
│        ↓                                              │
│  localhost:8080                                       │
│                                                       │
└───────────────────────────────────────────────────────┘

9. 브라우저에 응답 도착

1
2
3
4
5
6
7
8
┌─────────────────────── 호스트 OS ───────────────────────┐
│  localhost:8080                                       │
└───────────────┬───────────────────────────────────────┘
                │
                ▼
           [ 브라우저 ]
                ↓
         응답 렌더링 완료

전체 흐름 한 줄 요약

1
2
컨테이너 생성 → iptables 룰 등록 → 요청 → 주소 변경(DNAT) 
→ docker0 → 컨테이너 → 응답 → 역변환(SNAT) → 브라우저
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.