Docker 컨테이너 포트 매핑을 이해하자 feat. IP, Port, Docker

gunny·2026년 7월 30일

[CS] OS, Network

목록 보기
12/12

이번에 GPU 서버에 모델을 올렸다 내렸다 하면서 claude 없었으면 뒤질뻔한 날들의 연속이었던 것. 인프라 쪽은 정말 하면서 부딪히는거라지만 너무 이해가 안가는 것 투성이라서 정리하기

서버 = IP 주소

  • 건물 주소라고 생각하기.
  • IP는 네트워크에서 컴퓨터를 식별하는 주소
  • IP를 알면 어떤 컴퓨터인지 찾을 수 있음
    하지만 컴퓨터 하나가 여러 서비스를 동시에 실행한다.

예를 들어

  • 원격 로그인용인 SSH 데몬
  • nginx
  • llm을 서빙하기 위한 vLLM 컨테이너
  • Triton Inference Server
  • PostgreSQL 등등
    모두 하나의 서버 (IP)에서실행될 수 있다.
    그래서 IP만으로는 부족하다.
    '이 컴퓨터를 찾아왔는데, 어떤 프로그램한테 요청을 전달하지 ?'

-> IP는 컴퓨터를 특정할 뿐이고 컴퓨터 안에서 '어느 서비스한테 이 요청을 넘길지'는 Port 번호로 결정

Port

  • IP가 건물 주소라면 Port는 건물 안의 호실 번호
  • 같은 건물 안에 22호실에는 SSH, 10022호실엔 nginx 등
    Port는 65,535개까지 자유롭게 사용할 수 있는데 가장 유명한 관습이 있음
Port용도
22SSH
80HTTP
443HTTPS
5432PostgreSQL
6379Redis
8000,8080개발용 웹 서버

리스닝 (Listening)

  • 서비스를 실행하면 특정 Port에서 요청을 기다리는 상태(Listening)이 됨
    예를 들어 nginx를 실행하면 port 80에서 대기 중 이라는 의미
    위에서 말한 아파트, 집주소를 비유해보자면 위 컴퓨터 IP(집주소)에서 80호에서 nginx가 기다리는 중
  • 리눅스에서 실제 Listening 중인 Port는
    sudo netstat -tlnp
    또는
    ss -tlnp
    로 확인

Docker 컨테이너와 Port mapping

  • Docker 컨테이너는 자기만의 네트워크 공간을 가짐

  • 즉,

    Host
    IP : 192.168.0.10
    
    Container A
    IP : 172.17.0.2
    
    Container B
    IP : 172.17.0.3

    처럼 컨테니어마다 별도의 IP가 존재함

  • 따라서 Container A 안에서

    nginx
    Port 80 Listening

    이어도 Host에서는

    192.168.0.10:80

    으로 접근되지 않는다.
    Host와 Container는 서로 다른 네트워크이기 때문이다.

그래서 호스트 port <-> 컨테이너 port를 매핑해야 밖에서 접근이 가능함.
예를 들어 내가 작업했던 nginx에서

nginx:
    image nginx
    ports:
        - "10022:80"

이런것 처럼 호스트 10022를 컨테이너 내부 80으로 연결하는 것.

  • curl http://서버IP:10022
    을 Host가 받고 Docker가 10022 -> Container 80으로 전달하면, Container 내부 nginx가 응답하는 식으로 동작함.

컨테이너

  • 컨테이너는 독립된 리눅스 커널을 갖는 것이 아니라, Host의 리눅스 커널을 공유하면서 프로세스와 네트워크를 격리한 실행 환이다.

  • Docker는 컨테이너를 만들 때 Linux의 여러 기능을 활용함

    • Network Namespace
    • PID Namespace
    • Mount Namespace
    • Cgroup
    • Namespace
  • 그래서 컨테이너 안에서는

    127.0.0.1
    eth0
    IP 주소
    Listening Port

    등이 모두 독립적으로 존재하는 것처럼 보인다.

  • 예를 들어

    Container A
    Port 8000
    
    Container B
    Port 8000

    둘 다 동시에 사용할 수 있다.
    왜냐하면 172.17.0.2:8000, 172.17.0.3:8000 처럼 IP가 서로 다르기 때문이다.

Docker compose에서는 왜 서비스 이름으로 통신할까 ?

  • Docker compose를 사용하면 같은 네트워크 안의 컨테이너끼리는 서비스 이름이 DNS 이름처럼 동작한다.
    예를 들어
    SERVICES:
        NGINX:
        VLLM:
    이라면, nginx 컨테이너에서는 http://vllm:8000으로 바로 접근할 수 있다. Docker가 내부적으로 vllm -> 172.18.0.5 처럼 이름을 IP로 변환(DNS)해주기 때문이다.
  • 그래서 컨테이너끼리 통신할 때는 Host Port Mapping이 없어도 된다.
    Port Mapping은 외부(Host)에서 들어오는 요청을 위한 기능이고, 컨테이너끼리의 통신은 Docker 내부 네트워크를 이용한다.

전체 요청 흐름

브라우저 / curl
  │
  ▼
http://203.0.113.10:10022
  │
  ▼
Host(IP)
  │
  ▼
Docker Port Mapping
10022 -> 80
  │
  ▼
Container (nginx)
  │
  ▼
nginx Reverse Proxy
  │
  ▼
http://vllm:8000
  │
  ▼
vLLM Container
  │
  ▼
LLM 추론
  │
  ▼
응답

정리

  • IP는 어떤 컴퓨터인지 찾기 위한 주소이고, Port는 그 컴퓨터 안에서 어떤 서비스가 요청을 처리할 지 구분하는 번호이다.
  • 서비스는 특정 Port에서 Listening 상태로 요청을 기다린다.
  • Docker 컨테이너는 Host와 분리된 네트워크 공간을 가지므로, 외부에서 접근하려면 Host Port <-> Container Port를 매핑해야 한다.
  • Docker Compose에서는 같은 네트워크의 컨테이너끼리 서비스 이름 (vllm, nginx 등)으로 직접 통신할 수 있으며, 이 경우 Port Mapping은 필요하지 않다.
  • 외부 요청은 클라이언트 -> Host IP:Port -> Docker Port Mapping -> 컨테이너 -> 애플리케이션 순서로 전달된다.
profile
꿈꾸는 것도 개발처럼 깊게

0개의 댓글