티스토리 뷰

도커 네트워크 구조

 

 

- 도커는 컨테이너에 내부 IP를 순차적으로 할당

- 내부 IP는 컨테이너를 재시작할 때마다 변경될 수 있음

- 내부 IP는 도커가 설치된 호스트, 즉 내부망에서만 쓸 수 있는 IP이므로 외부와 연결될 필요가 있음

- 컨테이너를 시작할 때마다 호스트veth(Virtual Ethernet) 라는 네트워크 인터페이스를 생성

- 도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스의 이름은 veth로 시작

- veth 인터페이스는 사용자가 직접 생성할 필요는 없으며 컨테이너가 생성될 때 도커 엔진이 자동으로 생성

- veth 인터페이스는 호스트가 갖고 있는 eth0, eth1 등과 연결되어 있음

- docker0 브리지는 각 veth 인터페이스와 바인딩돼 호스트의 eth0 인터페이스와 이어주는 역할

 

 

 

 

- 컨테이너를 생성하면 기본적으로 docker0 브리지를 통해 외부와 통신할 수 있는 환경을 사용할 수 있지만 사용자의 선택에 따라 여러 네트워크 드라이버를 쓸 수도 있다.

 

* 네트워크 드라이브(Network Drive)

  > 브리지(Bridge), 호스트(Host), 논(none), 컨테이너(container), 오버레이(overlay)

  > 서드파티(Third-party) : weave, flannel, openvswitch

 

 

 

[docker network 확인]

# docker network ls

- docker network ls 명령어로 현재 네트워크 목록을 확인

 

 

 

 

[docker network 상세 정보 확인]

# docker network inspect bridge

- docker network inspect 명령어를 이용하면 네트워크의 자세한 정보를 살펴볼 수 있음

- 서브넷이 172.17.0.0/16으로 설정되어 있어, 컨테이너 생성시 자동으로 해당 대역을 부여

- 네트워크에 대한 아무런 설정없이 컨테이너를 생성하면, docker0를 브리지를 사용

 

 

 

 

 

브리지 네트워크(Bridge Network)

 

- docker0이 아닌 사용자 정의 브리지를 새로 생성해 각 컨테이너에 연결하는 네트워크 구조

- 컨테이너는 연결된 브리지를 통해 외부와 통신

 

 

[bridge 네트워크 생성]

# docker network create --driver bridge mybridge

- 브리지 타입의 mybridge라는 네트워크 생성

 

 

 

[생성한 bridge 네트워크를 사용해 컨테이너 생성]

# docker run -i -t --name mynetwork_container --net mybridge ubuntu:14.04

- 컨테이너 내부에서 ifconfig를 입력하면 새로운 IP 대역이 할당됨

- 브리지 타입의 네트워크를 생성하면 도커는 IP 대역을 차례대로 할당

 

 

 

[컨테이너에 할당된 network 연결 끊기]

# docker network disconnect mybridge mynetwork_container
# docker attach mynetwork_container

- 이렇게 생성된 사용자 정의 네트워크는 docker network  connect, disconnect 를 통해 컨테이너에 유동적으로 붙이고 뗄 수 있음

- 네트워크를 떼어내면 ifconfig 를 통해 확인 할 수 있음

 

 

[컨테이너에 network 할당 하기]

# docker network connect mybridge mynetwork_container
# docker attach mynetwork_container

 

 

 

[Custom Network 생성]

# docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.0.1 \
my_custom_network

- 네트워크의 서브넷, 게이트웨이, IP 할당 범위 등을 임의로 설정하려면 네트워크를 생성할 때 --subnet, --ip-range, 

--gateway 옵션을 추가

- 단 --subnet과 --ip-range는 같은 대역이어야 함

 

 

 

 

 

 

호스트 네트워크 (Host Network)

 

- 네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있음

- 별도로 생성할 필요 없이 기존의 host라는 이름의 네트워크를 사용

 

 

 

[Host 네트워크를 사용하여 컨테이너 생성]

# docker run -i -t --name network_host --net host ubuntu:14.04

- '--net' 옵션으로 호스트를 설정한 컨테이너의 내부에서 네트워크 환경을 확인하면 호스트와 같은 것을 알 수 있음

- 호스트 머신에서 설정한 호스트 이름도 커네티어가 물려받기 때문에 컨테이너의 호스트 이름도 도커 엔진이 설치된 호스트 머신의 호스트 이름으로 설정

- 컨테이너의 네트워크를 호스트모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트포워딩 없이 바로 서비스

 

 

 

 

 

 

논 네트워크 (None Network)

 

- None, 말 그대로 아무런 네트워크를 쓰지 않는 것을 뜻함

 

 

 

[None 네트워크로 컨테이너 생성]

- '--net' 옵션으로 none을 설정한 컨테이너 내부에서 네트워크 인터페이스를 확인하면 로컬호스트를 나타내는 lo 외에는 존재하지 않음

 

 

 

 

 

컨테이너 네트워크

 

- '--net' 옵션으로 container를 입력하면 다른 컨테이너의 네트워크 네임스페이스 환경을 공유할 수 있음

- 공유되는 속성은 내부 IP, 네트워크 인터페이스의 맥(MAC) 주소등

- ex) --net container:[다른 컨테이너의 ID]

 

 

 

[컨테이너 생성 후, 다른 컨테이너의 네트워크 네임스페이스 환경 공유]

# docker run -i -t -d --name network_container_1 ubuntu:14.04
# docker run -i -t -d --name network_container_2 ubuntu:14.04

- 다른 컨테이너의 네트워크 환경을 공유하면 내부 IP를 새로 할당받지 않으며 호스트에 veth로 시작하는 가상 네트워크 인터페이스도 생성되지 않음

- network_container_2 컨테이너의 네트워크와 관련된 사항은 전부 network_container_1과 같게 설정

 

 

 

[컨테이너2의 네트워크와 관련된 사항은 전부 컨테이너1을 따라감]

# docker exec network_container_1 ifconfig
# docker exec network_contianer_2 ifconfig

 

 

 

- 보통 이런경우는, 하나의 파드안에 여러개의 컨테이너가 있으면 veth을 한개로 사용하는 경우

 

 

 

 

브리지 네트워크와 --net-alias

 

 

- 브리지 타입의 네트워크와 run 명령어의 --net-alias 옵션을 함께 쓰면 특정 호스트 네임으로 여러 컨테이너 접근가능

 

 

[호스트네임을 alicek106 지정하여 3개의 컨테이너 생성]

# docker run -i -t -d --name network_alias_container1 --net mybridge --net-alias alicek106 ubuntu:14.04
# docker run -i -t -d --name network_alias_container2 --net mybridge --net-alias alicek106 ubuntu:14.04
# docker run -i -t -d --name network_alias_container3 --net mybridge --net-alias alicek106 ubuntu:14.04

- 컨테이너 이름 : network_alias_container1~3 

- network type : bridge

- net alias : alicek106

 

- 위 3가지 조건으로 컨테이너 3개 생성

 

 

 

[ping 테스트용 컨테이너 생성 후, 호스트네임으로 ping 테스트]

# docker run -i -t --name network_alias_ping --net mybridge ubuntu:14.04
# ping -c 1 alicek106
# ping -c 1 alicek106
# ping -c 1 alicek106

- ping 테스트용 컨테이너에서 하나의 호스트네임으로 ping 테스트 진행

- 컨테이너 3개의 IP로 각각 ping이 전송된 것을 확인

- 매번 달라지는 IP를 결정하는 것은 Round-Robin 방식

- 도커엔진에 DNS가 내장되어 있어 alicek106이라는 호스트 이름을 --net-alias 옵션으로 alicek106을 설정한 컨테이너로 Resolve 하기 때문

 

 

 

MacVLAN 네트워크

 

- 호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일 제공

- MacVLAN 사용 시, 컨테이너는 물리 네트워크상에서 가상의 맥(MAC) 주소를 가지며 해당 네트워크에 연결된 다른 장치와의 통신이 가능

- MacVLAN에 연결된 컨테이너는 기본적으로 할당되는 IP 대역인 172.17.X.X 대신 네트워크 장비의 IP를 할당받음

- MacVLAN을 사용하는 컨테이너들과 동일한 IP 대역을 사용하는 서버 및 컨테이너들은 서로 통신이 가능

 

- MacVLAN은 보다 더 복잡한 네트워크 개념을 포함하고 있으며, 기억해야될 것은 

  1) Bridge Mode 를 사용

  2) 부모 네트워크 인터페이스 지정 필요

 

# docker network create -d macvlan --subnet=[Host IP 대역] \
--ip-range=[Host IP 대역과 동일한 대역] --gateway=[Gateway IP] \
-o macvlan_mode=bridge -o parent=[Interface Name] my_macvlan