물리 서버로 서비스 이관 및 가상환경을 구성하면서 알게된 macvlan....
Docker 기본 네트워크

도커를 설치한 다음 아무런 설정도 하지 않고 컨테이너를 생성하면 위와 같은 구조
컨테이너를 생성하면 컨테이너의 namespace에 가상 인터페이스인 eth0이 생성되고, 호스트에는 veth를 접두어로 갖는 네트워크 인터페이스가 생성되며 이 두 개가 연결된다. 그리고 중요한 점은, 각 veth는 docker0라는 이름의 브릿지에 연결됨으로써 외부와 통신할 수 있다.
즉 브릿지는 각 컨테이너들의 맥 주소와 IP를 내부 테이블에 저장시켜놓음으로써 패킷 프레임이 정상적으로 왔다갔다 주고받고 얼씨구 할 수 있도록 하는, 2계층 디바이스를 연결할 수 있도록 하는 장비(?) 라고 보면 된다. 그렇지만 macvlan은 어찌보면, 브릿지와 완전 상반된다고 볼 수 있는 구조를 가진다.
MacVLan 이란?
macvlan 네트워크는 bridge 네트워크와 overlay 네트워크를 사용할 때 콘테이너와 호스트 사이의 브리지를 제거함으로써 콘테이너 통신을 간단하고 보다 원활하게 만드는 네트워크다.

macvlan은 위에서 말했듯 당연히 브릿지가 없다. 대신 서브 인터페이스(sub-interface) 라는 개념이 새롭게 등장한다.
일단 호스트 머신에 물리 장비 NIC인 eth0은 당연히 존재한다. 그럼 eth0에서 여러 개의 하위 인터페이스를 만듦으로써 동시에 여러 개의 맥 주소를 가질 수 있도록 구축한다. 그리고 나서 그 서브 인터페이스에 여러 개의 컨테이너들이 주렁주렁 달리면서 VLAN을 구성할 수 있게 된다. 즉, macvlan 이라는 이름이 암시하듯이, 하나의 네트워크 인터페이스 카드를 가상화함으로써 여러 개의 맥주소를 양산하는 것이다.
macvlan은 부모 인터페이스(parent)와 서브 인터페이스(slave) 로 나뉜다.
부모 인터페이스는 가상화될 주체, 즉 위 그림에서는 실제 물리 NIC인 eth0가 되겠고, 거기서부터 파생되어 나오는 가상화된 인터페이스를 서브 인터페이스라고 하며 위 그림에서는 mac0, ma1, mac2 가 된다.
그리고 뒤에서 다시 나오겠지만, macvlan으로 생성되는 인터페이스를 지칭할 때는 mac0@eth0 과 같이 표현한다.
mac0이 서브 인터페이스, eth0이 부모 인터페이스 이다.
macvlan에는 총 4가지 방식이 있다. 각각 private, VEPA, Bridge, Passthru 이다. 도커는 Bridge macvlan만을 지원함
Bridge macvlan 이란?

macvlan Bridge 방식을 간단히 설명하면 위와 같다. 요약하자면, "(1) 호스트와는 통신이 안되지만, (2) 다른 서브 인터페이스간 통신은 되는" 방식이다. 원래 (1)은 macvlan에서 안되는거고, (2) 에서 다른 방식들과의 차이를 갖는다고 볼 수 있다. 이 방식은 부모 인터페이스에 간단한 브릿지를 둬서 다른 서브 인터페이스로 향하는 트래픽을 밖으로 내보내지 않고 바로 전달하는 방식이라고 한다. 모든 서브 인터페이스의 맥 주소를 aware 한 상태이기 때문에 브릿지에서의 Mac Learning 작업도 필요 없고, 루핑을 방지하기 위한 STP 알고리즘도 필요가 없다고 한다.
MacVLan의 장/단점?
- 장점
1. 높은 대역폭
2. 낮은 cpu 점유율
- 단점
1. 부모 인터페이스가 죽으면 서브 인터페이스도 같이 사망...
2. 복잡한 네트워크 구성 불가능
3. 호스트와 직접 통신 불가능
적용 방법
1. 우선 연결되어있는 ip 확인
$ ifconfig
2. macvlan 전용 네트워크 생성
$ docker network create -d macvlan --subnet=서브넷마스크/24 --gateway=게이트웨이 -o parent=부모 네트워크 <이름>
3. 생성된 네트워크 확인
$ docker network ls
4. 해당 네트워크 상세하게 확인
$ docker newtork inspect <네트워크이름>
5. 샘플 docker-compose.yml
version: "3"
services:
test-img:
image: test-img:1.0
container_name: test-img
hostname: test-img
networks:
<macvlan 이름>:
ipv4_address: <ip 주소 할당>
restart: always
privileged: true
networks:
<macvlan 이름>:
external: true
해당 컨테이너는 host, bridge 네트워크에 들어가있지 않고, 새로 생성한 macvlan에 들어가있게된다.
=> Host와 연동하지 않고 컨테이너만 쓰려는 입장에서 나쁘지않은 선택지가 될수도...
Refs
- 참조 블로그
'infra > Docker' 카테고리의 다른 글
| docker + jenkins + git (0) | 2024.01.10 |
|---|---|
| IPv6 에러 (docker-compose.yml) (1) | 2024.01.10 |
| Rocky9.1 + tomcat Dockerfile (0) | 2024.01.10 |
| Tomcat 전용 Dockerfile (0) | 2024.01.10 |
| Dockerfile 에서 CMD, ENTRYOINT 차이 (0) | 2024.01.09 |