
- Docker의 네트워크 드라이버는 Bridge, Host, None, Overlay, Ipvlan, Macvlan 방식이 있다.
- Docker의 기본 네트워크 드라이버는 bridge이다.
- bridge 방식은 오버헤드가 있을 수 있어, 네트워크 성능이 중요하다면 host나 ipvlan 드라이버를 사용해야 한다.
- Overlay 드라이버를 사용하여 다른 호스트에 있는 컨테이너와도 통신이 가능하다.
- macvlan은 물리적인 네트워크 인터페이스에 직접 연결된 것처럼 동작할 수 있기에 호스트와 같은 네트워크임에도 불구하고 호스트와는 통신이 안 된다.
네트워크의 MAC, IP, DNS, 게이트웨이는 알고 있어야 한다.
WSL의 네트워크 스택과 개념을 알고 있어야 한다. (별도 포스팅 예정)
Docker의 개념을 알고 있어야 한다.
네이버 부스트 캠프에서 만든 최종 프로젝트 🎋Denamu에 각 애플리케이션들(Front, Back, MySQL, Redis, Nginx)을 Docker 엔진 위에 컨테이너로 동작하도록 했다. 하지만, 컨테이너는 각자 격리된 환경이라 IP를 각자 할당받고, 재시작할 때마다 변경되는 문제가 있었다.
Docker Compose에서 네트워크 설정을 해줘야 한다고 생각했다. 이때, Bridge 모드를 사용했었는데, 어떤 방식으로 동작하는지 몰랐었다.
찾아보니 드라이버가 bridge 말고도 host, none, overlay, ipvlan, macvlan 방식이 있음을 확인했고 각 드라이버가 어떻게 동작하는지 궁금했다.
Docker에서 네트워크를 사용하면 컨테이너들이 서로 통신할 수 있도록 연결해준다.
Docker가 호스트 OS 위에 돌아가긴 하지만, 호스트 OS 종류에 상관 없이도 연결할 수 있게 한다.
간단하게 컨테이너 하나를 실행해보자.
$ docker run -p 8080:80 nginx
nginx의 컨테이너를 생성하고 실행하는 명령어다. nginx를 컨테이너 내에서 80번 포트로 열고, HostOS의 포트 8080으로 요청이 오면 컨테이너 내 80번 포트인 nginx로 요청을 전달하게 된다.

여기서 기본 모드는 브릿지 모드이다.
Docker의 네트워크 드라이버는 여러 종류가 존재한다.
여기서는 간단하게 표로 알아보고 이후에 자세하게 알아보도록 하자.
| DRIVER | 설명 |
|---|---|
| bridge(default) | 기본 네트워크 드라이버로 같은 Docker 호스트 내의 컨테이너들만 통신이 가능하다. 각 컨테이너들은 고유한 IP 주솔르 할당받으며, 같은 네트워크에 속한 다른 컨테이너들과 IP를 통해 통신할 수 있다. 호스트 외부 시스템과의 직접적인 연결을 제한한다. 포트포워딩을 하면 가능하다. |
| host | 컨테이너가 호스트 시스템의 네트워크 인터페이스를 공유하게 된다. 즉, 호스트와 동일한 계층에서 네트워크가 존재하게 된다. 그렇기에 포트 맵핑이 필요 없다. |
| none | 네트워크 연결 없이 완전 격리된 상태로 접근이 불가능하다. |
| overlay | 여러 서버를 연결하는 네트워크다. Docker Swarm, k8s(Kubernetes)에서 주로 사용하는 방식이다. 클러스터 내 여러 호스트에 걸쳐서 네트워크를 확장할 수 있도록 하여 하나의 가상 네트워크 상에서 통신할 수 있도록 한다. |
| ipvlan | 컨테이너에 개별 IP를 부여할 수 있다. host 옵션처럼 호스트와 동일 계층에 존재하게 된다. bridge 같은 경우 NAT(네트워크 주소 변환)이 필요하겠지만, ipvlan은 HOST로 직접 IP 연결을 사용하기에 오버헤드가 발생하지 않는다. |
| macvlan | 컨테이너에 MAC 주소를 부여하여 물리 네트워크처럼 사용한다. |
docker 네트워크에서 기본적인 네트워크 모드이다.
docker run -p 8080:80 nginx
대부분 컨테이너를 실행할 때 이렇게 실행할 것이다.
이건 호스트 OS의 8080 포트를 컨테이너 내부 80번 포트와 맵핑하는 것이다.


❗ Docker 컨테이너는 독립적인 환경을 가지기에 컨테이너의 namespace안의 컨테이너는 반드시 1개다. Docker는 컨테이너를 생성할 때 새로운 네트워크 네임스페이스를 매번 할당하기에 독립적인 네트워크 환경을 가진다.
💡 Window 도커 통신 방법
Window 네트워크 인터페이스 -> Window 라우팅 테이블(WSL 찾기) -> WSL 가상 네트워크 인터페이스(vEthernet) -> Window 라우팅 테이블(docker0 찾기) -> docker0 -> Host_veth -> container_veth(container의 eth0)
💡 Mac 도커 통신 방법
Mac 네트워크 인터페이스 -> Mac 라우팅 테이블 -> HyperKit VM 내부 네트워크 인터페이스 (vnic(Virtual Network Interface Card)0, vnic1) -> HyperKit VM 라우팅 테이블 -> docker0 -> Host_veth -> container_veth(container의 eth0)
eth0: 첫 번째 이더넷 네트워크 인터페이스로 호스트 OS에 존재하는 것이다. ex) 랜 카드 or 메인보드 내장 랜 온보드 방식
라우팅 테이블: docker0와 eth0이 연결되기 위한 라우팅 테이블로 NAT(네트워크 주소 변환)을 사용하여 트래픽을 라우팅 한다.
docker0: Docker의 기본 가상 브리지 네트워크이다. 호스트 OS당 1개만 존재한다.
veth: 가상 이더넷이다. 2개가 한 쌍으로 묶여있는 것이다. 한 쪽은 Host 네트워크 네임스페이스가 있고, 한 쪽은 컨테이너 네임스페이스에 위치한다.
호스트 쪽의 veth는 docker0 브리지에 연결된다.
컨테이너쪽의 veth가 컨테이너에서는 eth0로 인식되며 172.17.0.x 같은 IP를 할당 받는다.
❓ docker0가 없이 veth만으로도 연결이 가능한 거 아닌가?
당연히 가능하다. 하지만, Docker 컨테이너 간 통신을 용이하게 하기 위해서 존재하며, 컨테이너들이 같은 네트워크 범위에서 통신할 수 있도록 연결해준다. 또한, IP 주소를 자동으로 할당하는 역할을 한다. 만약 docker0가 없으면 IP 할당 내가 스스로 해야 한다.컨테이너 A에서 컨테이너 B로 요청을 보낸다면 요청은 docker0 네트워크 브리지를 통해 전달하게 되기에 호스트 OS를 거치지 않고 Docker 네트워크에서 처리한다.

위에서는 컨테이너 하나가 본인만의 네트워크 네임스페이스를 가지고 있었다.
하지만, Host모드는 컨테이너가 본인만의 네트워크 네임스페이스를 가지는 것이 아닌 HostOS의 네임 스페이스 안에 들어가게 된다.
이렇게 될 경우 컨테이너의 IP는 호스트 OS의 IP와 동일하게 된다.
또한 컨테이너 내부의 포트가 호스트 OS의 포트와 동일하게 맵핑되기에 별도의 맵핑이 필요없다.
단순 포트만 지정하고 실행하면 호스트 OS에서 하나의 프로세스처럼 접근할 수 있다.
❓ bridge 모드에 컨테이너 1개 달린 거랑, host 모드의 차이는 무엇인가요?
네트워크 성능 차이가 발생한다. bridge 같은 경우 docker0를 거쳐야 한다. 그리고 docker0에서 NAT(Network Address Translation)을 수행해야 하기에 네트워크 성능 오버헤드가 발생한다.
하지만, host 모드는 docker0 같은 것이 없기 때문에 바로 다이렉트로 연결 되어 통신에서의 이점이 있다.
다만, host 모드는 hostOS와 직접 연결되는 것이기에 보안적으로 문제가 생길 수 있다. 외부와의 통신을 원하지 않는 애플리케이션(MySQL, Redis 등...)이 외부적으로 노출될 수 있다.

별도의 네트워크를 생성하지 않는 방식이다.
그 어떤 방식으로도 container에 접근할 수 없다.
그나마 데이터 공유를 한다면 volume으로 공유는 가능하다.
SSH 포트도 없어서 SSH 통신도 안 되고, exec 명령어 수행도 할 수 없다.
솔직히 왜 있는지 이해는 안 된다.
❓ 그럼 none 모드를 사용하지 않고 컨테이너를 실행할 때 bridge 모드에서 HostOS의 포트를 설정 안 하면 되는 거 아닌가요?
이러면 HostOS에서 컨테이너로 접근이 안 되긴 한다. 하지만, 같은 브릿지에 있는 컨테이너끼리는 통신이 된다. 그렇기에 만약 호스트 OS <-> 개방 애플리케이션 <-> bridge 호스트 포트 없는 컨테이너 관계가 된다면, 호스트 OS에서 간접적으로 접근이 가능해진다.

Docker Overlay 모드는 VXLAN(Virtual Extensible Lan)을 사용하여 여러 호스트의 컨테이너들이 동일한 서브넷에서 동작하는 것처럼 보이게 하는 방식이다.
간단하게 말하면, 그냥 여러 컴퓨터에 있는 컨테이너들을 연결하는 방식이라 생각하면 된다.
컨테이너 간 통신은 VXLAN 터널을 이용하여 통신을 한다.
Docker Swarm이나 K8S(Kubernetes)에서 사용할 수 있다.
Overlay 모드는 아예 다른 eth을 만들고, 연결을 수행한다고 생각하면 된다.
나중에 Docker Swarm을 사용하면 docker_gwbridge라는 게 나온다고 한다.
❗ Host모드와 Bridge 모드를 overlay모드와 같이 못 사용하나?
사용할 수 있다. Overlay 모드가 사용하는 eth말고 아예 다른 eth을 구축하면 Host모드나 Bridge 모드를 Overlay 모드와 함께 사용할 수 있다. 물론 Host 모드는 컨테이너 내에 eth가 없어도 된다.
- Bidge 모드 + Overlay 모드
- Host 모드 + Overlay 모드

ipvlan은 Docker 컨테이너에 고유한 IP 주소를 할당할 수 있는 방식이다.
기존에 bridge 모드는 컨테이너에 독립적인 IP를 할당하는 방식이었다. 그리고 docker0를 통해 ip를 발급 받는 방식이었다.
하지만, ipvlan은 호스트의 물리적 인터페이스(ex. eth0)를 직접 사용하며, 컨테이너는 그 네트워크 인터페이스의 일부로 존재하기에 호스트와 컨테이너는 동일한 네트워크 대역에 속하게 된다.
ipvlan은 bridge 네트워크를 사용하지 않기에 컨테이너끼리 연결을 위해서는 네트워크 장비가 라우팅을 처리하게 되며, 모든 컨테이너가 고유의 IP 주소를 가진다.
정리를 해보자.
| 특성 | bridge 모드 | host 모드 | ipvlan 모드 |
|---|---|---|---|
| 컨테이너 IP | docker0를 통한 독립적 IP 할당 | 호스트 OS와 동일한 IP 공유 | 고유한 IP 할당 |
| NAT 사용 여부 | 필요함 | X | X |
| veth | O | X | X |
| 네트워크 네임스페이스 | Docker 네임스페이스 내에서만 유효 | 호스트 네임스페이스 내에서만 유효 | 호스트 네임스페이스와 직접 연결된 네트워크 |
| 라우팅 | 호스트와 별도로 관리 | 라우팅 없이 직접 연결 | 물리적 네트워크를 통해 라우팅 |
그럼 ipvlan은 왜 사용하는 것일까
Bridge 모드나 Overlay와 같은 방식에서의 네트워크 트래픽이 다단계 네트워크 계층을 통과하기 때문에 성능에 부하를 줄 수 있다. Ipvlan은 호스트의 네트워크 인터페이스를 사용하여 컨테이너가 직접적으로 IP를 할당받아 통신하기에 오버헤드가 적고 성능이 향상된다.
그리고 host 모드처럼 컨테이너 내부에서 eth0 인터페이스가 필요 없다.
❓ host 모드 vs ipvlan 모드
host 모드는 호스트 OS의 네트워크 네임스페이스를 컨테이너가 그대로 사용한다.
ipvlan 모드는 호스트 OS의 네트워크 네임스페이스 안에 있긴 하지만, 컨테이너는 고유의 IP를 가진다.

컨테이너에게 물리적인 네트워크 인터페이스에 직접 연결된 것처럼 동작할 수 있다.
별도의 MAC 주소를 컨테이너들에게 할당하여 호스트 네트워크 인터페이스에 가상적으로 연결시켜 주기에 컨테이너는 호스트 OS와 독립된 네트워크 인터페이스를 가진 것처럼 동작할 수 있다.
컨테이너가 호스트 네트워크와 격리된 상태에서 독립적으로 통신을 할 수 있게 된다.
그렇기에, 호스트와 컨테이너가 동일한 네트워크를 사용함에도 불구하고 호스트와 컨테이너 간의 직접적인 통신은 불가능하다.
물리적 네트워크에 컨테이너를 노출해야 할 때 사용한다.
❗ macvlan 방식은 ipvlan 방식과 다르게 컨테이너에서 eth0 인터페이스가 필요하다.
CS에서 네트워크가 가장 어렵다고 생각했는데, Docker는 네트워크는 진짜 넘사인 것 같다. 기초적인 네트워크 이론을 넘어서 상당히 광범위하게 알고 있어야 한다.
Docker 네트워크를 잘 설정한다면, 여러 컴퓨터끼리 컨테이너를 쉽게 관리하고 접근할 수 있게 될 것 같다.
하지만, 네트워크 기초 지식이 부족했던 나에게는 상당히 어려운 주제였다. bridge와 host, none, overlay까지는 이해했으나 ipvlan과 macvlan은 이해를 덜 했다.
특히 macvlan은 왜 필요한지 아직 와닿지는 않는다.
네트워크 공부를 하고 다시 블로그 글을 다듬어야 할듯하다.
그림 그려가면서 학습을 했음에도 불구하고 이해를 못 한 건 처음이다.