도커(Docker)를 사용할 때 단순히 컨테이너를 띄우는 것을 넘어, 실제 서비스 운영을 위해서는 네트워크(Network)가 어떻게 연결되는지, 그리고 컨테이너 내부의 데이터를 어떻게 관리할 것인지에 대해 이해해야 한다.
Nginx와 Ubuntu 두 개의 컨테이너를 이용해 도커의 네트워크 인터페이스 구조(veth, bridge)를 직접 확인해보자.
1. 컨테이너 포트 포워딩과 네트워크 격리 확인
먼저 Nginx 웹 서버와 우분투 컨테이너를 각각 실행하여 외부에서 접근이 가능한지 확인해 본다.
이때 -p 옵션을 사용하여 호스트의 포트와 컨테이너의 포트를 연결한다.
# Nginx 컨테이너 실행 (호스트 8000 -> 컨테이너 80)
docker run --name myweb -p 8000:80 -d nginx:latest
# Ubuntu 18.04 컨테이너 실행 및 내부 진입 (특정 IP 바인딩 예시)
docker run -it -p 123.345.100.789:7000:80 ubuntu:18.04
내부 설정 및 확인 : 우분투 컨테이너 내부로 들어와서 네트워크 도구를 설치하여 현재 할당받은 IP를 확인한다.
# 컨테이너 내부에서 net-tools 설치 및 Apache2 웹서버 설치
root@765d3f76e061:/# apt update && apt -y install apache2 && service apache2 start
root@765d3f76e061:/# apt -y install net-tools
# 네트워크 인터페이스 확인
root@765d3f76e061:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.7 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:07 ...
도커 네트워크 격리
위 결과를 보면 컨테이너(eth0)는 172.17.0.7이라는 IP를 할당받았다.
이는 도커가 내부적으로 생성한 사설 네트워크 대역이다.
외부에서는 이 172.17.x.x 대역으로 직접 접근할 수 없으며, 반드시 호스트의 IP와 매핑된 포트(위의 경우 8000 또는 7000)를 통해서만 접근이 가능하다.
실제로 브라우저에서 테스트해 보면 다음과 같은 결과가 나온다.
- http://123.456.100.789:8000 (호스트 IP:포트) -> 접속 성공
- https://172.17.0.7/ (컨테이너 내부 IP) -> 접속 실패 (Unable to connect)
2. 도커 브리지(Bridge)와 veth 인터페이스 구조 분석
도커가 생성하는 네트워크의 실체를 파악하기 위해 호스트 머신(Ubuntu)에서 네트워크 인터페이스 목록을 조회해 본다.
ubuntu@master:~$ ip addr
# (중략)
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> ... inet 172.17.0.1/16 ...
5: vethbfe05a3@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> ... master docker0 ...
13: veth8d73f3e@if12: ... master docker0 ...
호스트의 ip addr 결과를 분석하면 도커 네트워크의 핵심인 Bridge Network 구조를 파악할 수 있다.
- docker0 (Bridge): 도커 서비스가 실행되면 호스트에는 docker0라는 가상 브리지 인터페이스가 생성된다. (IP: 172.17.0.1) 이것은 일종의 패킷 전달자 역할을 한다.
- veth (Virtual Ethernet): 컨테이너가 생성될 때마다 veth...로 시작하는 인터페이스가 호스트에 생긴다. 이는 컨테이너 내부의 eth0와 짝(Pair)을 이루는 가상 터널 장치. (하나는 호스트에, 하나는 컨테이너 내부에 위치하여 pair으로 생성됨)
즉, 컨테이너는 docker0 브리지를 통해 서로 통신하며, 외부 통신 시에는 호스트의 물리 NIC를 통해 NAT(Network Address Translation) 방식으로 나간다.

- 외부 사용자: 호스트의 물리 IP(123.456.100.789)와 포트(8000 등)로 접속을 시도한다.
- 물리 NIC & NAT: 호스트가 요청을 받아 docker0 브리지로 트래픽을 넘겨준다. 이 과정에서 포트 포워딩 규칙이 적용된다.
- docker0 Bridge: 172.17.0.1 주소를 가진 가상 스위치로, 연결된 컨테이너들에게 패킷을 분배한다.
- veth Pair: 호스트 쪽에 있는 veth 인터페이스와 컨테이너 내부의 eth0 인터페이스가 짝을 이루어 통신한다.
네트워크 네임스페이스(Network Namespace)
왜 굳이 이런 가상 장치가 필요할까? 그 답은 리눅스의 네트워크 네임스페이스(Network Namespace) 기술에 있다.
- 컨테이너의 실체: 컨테이너는 별도의 서버가 아니라, 리눅스 커널의 기능(Namespace)을 이용해 "네트워크 환경만 격리된 프로세스"다.
- 격리되었기 때문에 호스트의 네트워크 스택과는 완전히 단절되어 있다.
- 이 단절된 공간(컨테이너)과 원래 공간(호스트)을 연결하기 위해 구멍을 뚫어주는 터널이 veth (Virtual Ethernet Pair)이다.
- 그리고 여러 개의 veth 끝단을 하나로 묶어 통신을 중재하는 논리적 장치가 docker0 (Linux Bridge)이다.
'AI Journey > 클라우드' 카테고리의 다른 글
| [Kubernetese] 스프링부트(Spring boot) 서버를 파드(Pod)로 띄우기 (0) | 2026.01.03 |
|---|---|
| [Docker] 바인드 마운트(Bind Mount)를 활용한 데이터 동기화 (0) | 2026.01.01 |
| [Docker] 컨테이너 통신: 링크(--link) 옵션을 활용해서 WordPress와 DB 연동하기 (0) | 2026.01.01 |
| [Kubernetese] Nginx 파드(Pod) 생성하고 포트 포워딩(port forwarding)하기 (0) | 2025.12.31 |
| [Docker] 포트 포워딩(port forwarding) (feat. Nginx) (0) | 2025.12.30 |