컨테이너를 여러 개 띄워도 기본적으로 서로 통신하지 못한다. Docker Network를 이해하면 컨테이너끼리 이름으로 서로를 찾고, 외부에는 필요한 포트만 열 수 있다. 네트워크 드라이버 선택 하나가 보안과 성능을 모두 결정한다.
Docker는 용도에 따라 네 가지 드라이버를 제공한다.
| 드라이버 | 특징 | 주요 사용 사례 |
|---|---|---|
| bridge | 가상 네트워크 인터페이스 생성, 컨테이너 격리 | 단일 호스트 멀티 컨테이너 |
| host | 호스트 네트워크 스택 직접 사용, 격리 없음 | 최고 성능이 필요한 경우 |
| overlay | 멀티 호스트 간 가상 네트워크 터널 | Docker Swarm, 분산 클러스터 |
| none | 네트워크 인터페이스 없음 | 완전 격리 컨테이너 |
bridge: Docker가 호스트에 docker0라는 가상 브리지 인터페이스를 만들고, 컨테이너마다 veth pair로 연결하는 방식이다.
Docker를 설치하면 bridge라는 기본 네트워크가 생성된다. 그러나 기본 bridge에서는 컨테이너 이름으로 DNS 조회가 불가능하다. 사용자 정의 bridge 네트워크를 만들어야 이름 기반 통신이 된다.
# 사용자 정의 네트워크 생성
docker network create my-network
# 컨테이너를 네트워크에 연결해 실행
docker run -d --name api --network my-network my-api-image
docker run -d --name db --network my-network postgres:16
이제 api 컨테이너 안에서 db라는 호스트명으로 PostgreSQL에 접근할 수 있다.
[Host] | +-- docker0 (bridge) | +-- veth --> [api 컨테이너] :8080 | +-- veth --> [db 컨테이너] :5432
veth pair: 호스트 네임스페이스와 컨테이너 네임스페이스를 연결하는 가상 이더넷 인터페이스 쌍이다. 한쪽에서 전송하면 반대쪽에서 수신한다.
-p 옵션은 호스트 포트를 컨테이너 포트에 매핑해 외부에서 접근할 수 있게 한다. 같은 네트워크 내 컨테이너끼리는 -p 없이도 내부 포트로 직접 통신한다.
# 외부에는 8080만 열고, db는 내부 통신만 허용
docker run -d --name api --network my-network -p 8080:8080 my-api-image
docker run -d --name db --network my-network postgres:16
db는 -p를 쓰지 않았으므로 호스트 밖에서는 5432에 접근할 수 없다. api만 db:5432로 내부 통신한다.
overlay 드라이버는 여러 Docker 호스트에 걸친 컨테이너를 하나의 L2 네트워크처럼 묶는다. Docker Swarm 또는 Kubernetes에서 사용되며, VXLAN 터널로 호스트 간 패킷을 캡슐화한다.
# Swarm 초기화 후 overlay 네트워크 생성
docker swarm init
docker network create --driver overlay my-overlay
[Host A] [Host B]
| |
+-- [컨테이너 A] +-- [컨테이너 B]
| |
+------- VXLAN 터널 --------+
(overlay network)
VXLAN: UDP 기반으로 L2 프레임을 캡슐화해 L3 네트워크를 통해 전달하는 터널링 프로토콜이다.
# 네트워크 목록
docker network ls
# 특정 네트워크에 연결된 컨테이너 확인
docker network inspect my-network
# 실행 중인 컨테이너에 네트워크 추가 연결
docker network connect my-network existing-container
사용자 정의 bridge 네트워크와 -p로 외부 포트를 최소화하는 패턴이 단일 호스트에서 가장 실용적인 출발점이다.