Simple is IT, 누구나 보고 누구나 깨닫는 IT

Docker Network 구조는 어떨까, 그리고 종류는? (2/2) 본문

Simple is IT/Cloud & Container

Docker Network 구조는 어떨까, 그리고 종류는? (2/2)

currenjin 2020. 6. 2. 23:13

Docker Network 구조와 종류는 어떨까? - 2/2

 

많은 엔지니어, 개발자들이 사용하는 도커임에도 추상적인 네트워크에 대해 이해가 어려울 때가 많을 거에요.

 

그런 분들을 위해

이 두루뭉실한 네트워크 구조와 종류를 확실하게 파악하는 것이 포스팅의 목적이에요.

 

 

- Docker Network의 종류를 알아보자 !

 

저번 포스팅에서 컨테이너를 생성하면 기본적으로 docker() 브리지를 통해 외부와 통신할 수 있는 환경을 사용할 수 있다는 설명을 드렸어요.

 

그렇지만, 사용자의 선택에 따라 다양한 네트워크 드라이버를 사용할 수 있답니다.

 

Docker에서 제공하는 네트워크 드라이버 중 대표적인 것은 브리지, 호스트, 논, 컨테이너, 오버레이가 있어요.

저는 이 중 오버레이를 제외한 드라이버에 대해 설명을 드릴게요!

 

 

 

먼저 도커의 네트워크 리스트를 볼까요?

docker network ls

 

output:

NETWORK ID          NAME                DRIVER              SCOPE
82624d630045        bridge              bridge              local
2531da1527a7        host                host                local
b4a85ae68d7c        none                null                local

 

이미 bridge, host, none 네트워크가 존재함을 알 수 있어요.

 

bridge 네트워크는 아시다시피 컨테이너를 생성하면 docker() 브리지를 자동으로 연결하는데 활용해요.

 

 

docker network inspect [network]

: 네트워크의 자세한 정보를 살펴볼 수 있어요!

docker network inspect bridge

 

output:

...
"Config": [
{
	"Subnet": "172.17.0.0/16"
}
]
...
"Containers": {
...

Config

: 서브넷과 게이트웨이 등을 확인할 수 있어요.

 

Containers

: 해당 네트워크를 사용 중인 컨테이너를 확인할 수 있어요.

 

 

역시 아무런 설정 없이 컨테이너를 생성하면 docker() 브리지를 사용하겠죠?

 

 

Bridge Network

저번 포스팅에서 설명한 docker() 브리지와 비슷한 구조에요. 브리지 네트워크는 사용자가 새로 정의한 브리지를 각 컨테이너에 연결하는 네트워크 구조랍니다. (마찬가지로 외부와 통신을 할 수 있죠!)

 

 

새로운 브리지를 생성하려면 아래의 명령어를 입력해주세요.

docker network create --driver bridge newbr

 

output:

e163895231fc2f8995026a7b9d29b556626517c7a624e1fdc8869990c023a2e8

생성이 완료되었어요. 여기서 'newbr'는 생성한 브리지 네트워크의 이름이랍니다.

 

 

손수 만든 네트워크를 생성하는 컨테이너에 적용하고 싶나요?  --net [network] 옵션만 붙여주면 된답니다!

docker run -itd --name ubuntu_test --net mybr ubuntu

 

 

호스트에 네트워크 인터페이스를 확인해보면

ifconfig

 

output:

br-e163895231fc Link encap:Ethernet  HWaddr 02:42:29:51:f4:30
          inet addr:172.18.0.1  Bcast:172.18.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:29ff:fe51:f430/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:648 (648.0 B)

와우..! 브리지 형태의 새로운 네트워크 대역을 가진 인터페이스가 생성된 것을 확인할 수 있네요.

 

 

컨테이너에 정의한 네트워크는 'docker network disconnect/connect' 명령으로 유동적이게 붙이고 뗄 수 있어요.

docker network disconnect mybr ubuntu_test
docker network connect mybr ubuntu_test

정말 간단한 것 같아요.

 

 

아래는 네트워크의 서브넷과 게이트웨이, IP 할당 범위 등을 임의로 설정해 네트워크를 생성하는 명령이에요.

docker network create --driver=bridge \
--subnet=192.168.0.0/24 \
--ip-range=192.168.0.0/25 \
--gateway=192.168.0.1 \
mybr

mybr이라는 이름의 브리지 네트워크를 생성했어요! subnet 대역은 '192.168.0.0/24'를 사용하며, 할당에 대한 범위를 'prefix 25'만큼 주었고 게이트웨이는 '192.168.0.1'이 되겠네요.

 

 

 

Host Network

호스트 네트워크는 간단합니다.

docker run -itd --name ubuntu_test --net host ubuntu

위 브리지 네트워크같이 별도로 생성할 필요 없이 'host'라는 이름의 네트워크를 바로 사용이 가능하기 때문이죠.

 

 

컨테이너 내부의 아이피를 확인해볼게요.

br-e163895231fc: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
...

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
...

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.100  netmask 255.255.255.0  broadcast 192.168.10.255
...

신기한 노릇이네요. 호스트 머신의 네트워크 인터페이스의 내용이 일치합니다!

더군다나 호스트 머신에서 설정한 호스트 이름도 컨테이너가 그대로 가져갔네요.

 

바로 이 점에서 호스트 네트워크의 특징이 주목되는데요.

컨테이너의 네트워크를 'Host'로 설정하게 된다면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩없이 바로 서비스 할 수 있어요. 마치 실제 호스트 머신에서 동작하는 것과 같이요!

 

ex) 호스트 네트워크를 사용하는 컨테이너에서 웹 서버를 구동한다면 호스트의 IP와 컨테이너의 아파치 웹 포트인 80번 포트로 바로 접근이 가능합니다.

 

 

이런 구조를 그림으로 표현해보자면 이런 형식이지 않을까요?

 

 

 

None Network

단어 그대로 아무런 네트워크를 사용하지 않아요. 무슨말이냐고요?

다음과 같이 컨테이너를 생성해봅시다.

docker run -itd --name ubuntu_test --net none ubuntu

 

이렇게 생성한 호스트의 내부 네트워크를 확인해보면

docker exec ubuntu_test ifconfig

 

output:

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo 인터페이스 외에는 존재하지 않는 것을 알 수 있어요. 이는 곧 외부와의 단절이라는 뜻입니다!

 

 

 

Container Network

다른 컨테이너의 네트워크 네임스페이스 환경을 공유할 수 있어요. 공유되는 속성은 내부 IP, 네트워크 인터페이스의 MAC주소 등이에요.

 

 

컨테이너를 생성할 때 --net 옵션으로 container:[container ID]를 입력해주면 돼요!

docker run -itd --name ubuntu_test1 ubuntu
docker run -itd --name ubuntu_test2 --net container:ubuntu_test1 ubuntu

 

 

네트워크 인터페이스를 확인해볼까요?

docker exec ubuntu_test1 ifconfig
docker exec ubuntu_test2 ifconfig

 

output:

# ubuntu_test1
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        
        
# ubuntu_test2
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0

결과는 동일하네요.

 

마치 Host Network의 특징에서 관계만 Host - Container가 아닌 Container1 - Container2로 바뀐 것 같아요!

 

 

이해하기 쉽게 그림으로 표현하자면 이런 모습이랍니다.

 

 

 

마냥 어렵다고, 이해하기 힘들다고 생각한 도커 네트워크

여러분들이 제 글을 통해서 얻어가는 내용이 충분히 많으셨으면 좋겠어요.

 

감사합니다.

 

 

Comments