Notice
Recent Posts
Recent Comments
Today
Total
04-29 20:19
Archives
관리 메뉴

Jeongchul Kim

Docker network 네트워크 본문

Docker

Docker network 네트워크

김 정출 2019. 7. 26. 19:48


Docker network 네트워크




네트워크 드라이버

Docker의 네트워킹 서브 시스템은 여러 개의 드라이버를 사용해 네트워킹을 가능하게 합니다.


$ ifconfig


$ docker network ls


bridge

default 네트워크 드라이버. 드라이버를 지정하지 않으면 자동 지정되는 네트워크입니다. bridge 네트워크는 일반적으로 container의 application이 통신이 필요할 때 사용됩니다.


host

container와 Docker host 간에 네트워크 격리(isolation)를 제거하고 직접 호스트의 네트워킹을 사용합니다. Docker 17.06 이상의 swarm 서비스에서 사용 가능합니다.

$ docker --version


overlay

overlay 네트워크는 여러 Docker demons을 서로 연결하여 swarm 서비스가 서로 통신할 수 있도록 합니다. 즉 여러 대의 서버( 물리적으로 네트워크 분리되어 ip가 다른)에서 실행된 container 들 간에 통신이 가능하도록 해줍니다. 


$ ifconfig


macvlan 

macvlan 네트워크를 사용하면 MAC 주소를 container에 할당하여 네트워크의 물리적 장치로 표시할 수 있습니다. Docker daemon은 트래픽을 container의 MAC 주소로 라우팅합니다. Docker 호스트의 네트워크 스택을 통해 라우팅하는 것이 아니라 실제 네트워크에 직접 연결이 필요할 경우 사용됩니다. 


none

container에 모든 네트워킹 사용을 불가합니다. 일반적으로 사용자 정의 네트워크 드라이버와 함께 사용됩니다. none인 경우 swarm 서비스가 불가합니다.


summary

  • 동일한 Docker 호스트에서 여러 개의 container 간의 통신이 필요하다면 사용자 정의 bridge network를 사용하는 것이 좋습니다.

  • Host 네트워크는 Docker 호스트에서 네트워크 스택을 격리하면 안될 경우에 사용됩니다.

  • Overlay 네트워크는 서로 다른 Docker host에서 실행되는 container가 서로 통신할 필요가 있을 경우(ex: hadoop, spark, distributed tensorflow) swarm 서비스를 사용하면 좋습니다.

  • Macvlan 네트워크는 VM 설정으로부터 마이그레이션 하거나 container가 고유한 MAC 주소를 가진 네트워크를  물리적 호스트처럼 보일 때 좋습니다.


bridge network

네트워킹 측면에서 bridge network는 network segments 끼리 트래픽을 전달하는 링크 계층(link layer) 장치입니다.

[*] link layer : 인터넷의 네트워킹 아키텍처에서 가장 낮은 계층으로 호스트가 물리적으로 연결되는 링크 상에서만 운용되는 method와 통신 프로토콜이 모여 있습니다.



Docker에서의 bridge 네트워크를 이용하면 해당 bridge 네트워크에 연결되지 않은 container로부터 격리를 할 수 있습니다. Docker bridge driver는 서로 다른 bridge network에 연결된 container간에 통신하지 않도록 규칙을 설정합니다.


Docker를 시작하면 자동적으로 bridge라고 불리는 default bridge 네트워크가 생성됩니다. 사용자가 생성하는 bridge network는 이 bridge를 상속 받습니다.

$ docker network ls


$ docker network inspect bridge


container를 network 옵션없이 시작해봅시다. default로 bridge 네트워크에 물려 ip를 할당 받습니다.

$ docker urn -d --name server -p 8080:8080 kimjeongchul/node-app-server

$ curl localhost:8080


$ docker run -dit --name client kimjeongchul/ubuntu /bin/bash


같은 bridge 네트워크에 container를 생성하면 통신이 가능합니다.

$ docker exec -it client bash

# curl 172.18.0.2:8080


bridge를 하나 생성해봅시다.

$ docker network create my-bridge

$ docker network ls


네트워크 상세 정보를 살펴봅시다.

서브넷이 172.20.0.0/16 입니다.

$ docker network inspect my-bridge


container를 my-bridge에 물리고 시작하면 eth0 ip가 172.20.0.2로 받습니다.

$ docker run -d --name server --network my-bridge -p 8080:8080 kimjeongchul/node-app-server

$ curl localhost:8080


host 기기에서 ifconfig 를 해봅시다. 새로운 br-[my-bridge-NETWORK-ID] 네트워크 장치가 생긴 것이 확인됩니다.

$ ifconfig


$ docker network inspect my-bridge


$ docker exec -it client bash

$ curl 172.20.0.2:8080

응답하지 않습니다.


network 연결을 해제할 수 있습니다.

$ docker network disconnect my-bridge server


네트워크 재 연결은 connect를 사용합니다.

$ docker network connect my-bridge server


bridge 네트워크에서는 각기 container의 이름으로도 통신이 가능합니다.

$ curl server:8080


네트워크 삭제는 network rm을 사용합니다. 그 전에 물려있는 bridge 컨테이너를 종료해야 합니다.

$ docker stop server && docker rm server

$ docker network rm my-bridge

$ docker network ls

 


host 네트워크 

container에 대해 host 네트워크 모드를 사용하는 경우 해당 container의 네트워크 스택은 Docker host와 분리되지 않으며, container는 host의 namespace를 공유합니다. 이에 따라 자체 IP 주소를 할당받지 않습니다. port 80을 바인딩하는 container는 호스트 IP 주소에 있는 port 80을 사용할 수 있습니다.



호스트 모드 네트워킹은 성능을 최적화하는데 유용하며 container가 NAT(Network Address Translation)을 피룡로 하지 않고, 광범위한 포트를 사용할 경우 유용합니다. Host 네트워킹 드라이버는 Linux 호스트에서만 지원합니다.


-p 옵션으로 8080 포트를 맵핑하지 않고도 포트가 열리게 됩니다. IP 주소를 보면 docker 0, docker_gwbridge, eth0 장치를 통해 host의 네트워크 네임스페이스를 공유하는 것을 확인할 수 있습니다.

$ docker run -d --name server --network host kimjeongchul/node-app-server


직접들어가서 확인하면 기존의 hostname이 container가 아니라 host 머신의 hostname으로 설정됩니다.

$ hostname

$ docker exec -it server bash

# hostname

# ifconfig


Overlay 네트워크

overlay 네트워크는 여러 Docker daemon 호스트 사이에 분산 네트워크를 생성합니다.  Overlay 네트워크에 연결된 컨테이너들은 같은 subnet에 묶여 서로 간에 안전하게 통신 할 수 있습니다.



swarm을 초기화(swarm init)하거나 Docker 호스트를 기존 swarm에 가입시키면(swarm join) 해당 Docker 호스트에 두 개(ingress, docker_gwbridge)의 새로운 네트워크가 생성됩니다.


ingress 

swarm 서비스와 관련된 제어 및 데이터 트래픽을 처리합니다.


docker_gwbridge

bridge 네트워크로 서로 다른 Docker daemon(물리적으로 다른 위치에 있는 서버)간에 브리지 네트워크를 만들어 통신할 수 있도록 합니다.


overlay 네트워크를 사용하기 위해서는 다음의 방화벽 규칙이 필요합니다.

  • port 2377 : 클러스터 관리 통신

  • port 7946 : 노드 간 통신을 위한 TCP, UDP 포트

  • port 4789 : Overlay 네트워크 트래픽용


$ docker swarm init


$ docker network create -d overlay --subnet 10.1.0.0/24 --attachable overlay

$ docker network ls


overlay 네트워크로 생성하면 10.1.0.0/24 subnet으로 순차적으로 ip를 할당받습니다. 이에 따라 여러 대의 서버에서 hadoop, spark, tensorflow distributed를 구현하기 쉬워지죠.

$ docker run -d --name server --network overlay -p 8080:8080 kimjeongchul/node-app-server

$ docker network inspect overlay


$ curl locahost:8080


실제 여러 대의 노드를 묶어보는 docker swarm 테스트를 위해서는 kubernetes 클러스터를 만들어야 합니다.


다음과 같이 Kubernetes 클러스터를 설정해주세요.


VM 인스턴스 메뉴로 들어가 첫 번째 VM을 SSH로 접속합니다.


$ sudo vi /etc/docker/daemon.json

$ sudo systemctl restart docker


$ docker swarm init


2번째 VM을 SSH로 접속합니다.

$ sudo vi /etc/docker/daemon.json

$ sudo systemctl restart docker

$ docker swarm join \

    --token SWMTKN-1-23b2ay3qnleop4bc7h5tzoidf33c90c5f2z9yzq6lzy0wxxvwa-c4lpq1wycfwfss7zzl48vyoj1 \

    10.128.0.7:2377



$ docker node ls

$ docker node ls --filter role=manager

$ docker node ls --filter role=worker

첫 번째 VM에서 overlay network를 하나 생성해봅시다.

$ docker network create -d overlay --subnet 10.1.0.0/24 --attachable overlay


두 개의 VM 모두에서 container를 시작해봅시다.

첫 번째 VM

$ docker run -d --name node-1-server --network overlay -p 8080:8080 kimjeongchul/node-app-server


2 번째 VM

$ docker run -d --name node-2-server --network overlay -p 8080:8080 kimjeongchul/node-app-server


2개의 컨테이너가 실행 중이지만 Containers에서는 각기 Host에서 동작중인 container 목록만 보여집니다. Peers에서는 현재 swarm으로 연결된 node의 IP들이 보여집니다.

$ docker network inspect overlay


1번째 VM(10.1.0.3)에서 container로 접속해 2번째 VM에서 생성한 container(10.1.0.2)로 curl을 날려봅시다.


마찬가지로 2번째 VM의 container에서 1번째 VM(10.1.0.3)로 통신해봅시다.


공개 IP 없이도 통신이 잘되는 것을 볼 수 있습니다.

물론 공개 IP를 이용해 포트를 맵핑했기 때문에 container 안의 웹서버로 접속이 가능합니다.


Overlay 네트워크의 추가적인 설정에 대해서는 다음의 링크를 참고해주세요.

docker-docs/network/overlay-network


Macvlan 네트워크

일부 응용 프로그램, 특히 네트워크 트래픽을 모니터링하는 레거시 응용 프로그램이나 응용 프로그램은 실제 네트워크에 직접 연결될 것으로 예상됩니다. 이러한 유형의 상황에서는 macvlan 네트워크 드라이버를 사용하여 MAC 주소를 각 컨테이너의 가상 네트워크 인터페이스에 할당하여 실제 네트워크에 직접 연결된 실제 네트워크 인터페이스처럼 보이게 할 수 있습니다. 이 경우 Macvlan의 서브넷과 게이트웨이뿐만 아니라 macvlan에 사용할 Docker 호스트의 물리적 인터페이스를 지정해야합니다. 다른 물리적 네트워크 인터페이스를 사용하여 macvlan 네트워크를 격리 할 수도 있습니다..


자세한 사항은 다음의 링크를 참고해주세요.

https://docs.docker.com/network/macvlan/

none 네트워크

container의 네트워킹을 불가능하게 설정하기 때문에 container 안에서는 네트워크를 이용한 인터넷 사용이 불가능합니다.

$ docker run -d --name server --network none kimjeongchul/node-app-server

$ docker exec -it server bash

# ping google.com


각 네트워크에 대한 튜토리얼은 공식 Docker docs에서도 정리가 잘되어있습니다.


좀 더 네트워킹에 대해 깊게 공부하고 싶으시다면 다음의 링크를 추천합니다.


https://success.docker.com/article/networking




'Docker' 카테고리의 다른 글

Portainer.io  (0) 2020.02.24
Docker run 명령어 in AWS EC2  (0) 2018.11.21
Docker AWS EC2 설치  (3) 2018.11.20
Google Cloud with Docker  (0) 2018.03.06
An Updated Performance Comparison of Virtual Machines and Linux Containers  (0) 2017.07.07
Comments