본문 바로가기

Infra

[Infra] Docker Network 개념

Docker Network

각자만의 격리된 network 공간을 할당받은 Container 끼리 통신을 주고받기 위해 만들어진 개념

Docker Network 구조도

docker0

docker Host를 설치하고, "ifconfig" 를 통해 network interface 를 확인하면 docker0를 확인할 수 있다.

이 interface는 docker 내부 로직에 의해 자동으로 할당받는 가상의 이더넷 브릿지이다.

 

가상이더넷 브릿지가 뭐고 왜 생겨난것일까 ?

각각의 컨테이너는 격리된 네트워크 공간을 할당받는다. 그럼 컨테이너가 외부와의 통신을 하려면 외부와 연결되어 있는 무언가의 도움이 필요한데, 이를 가상이더넷 브릿지가 관리하게 된다.

위의 그림처럼 가상이더넷 브릿지는 각각의 컨테이너마다 가상 네트워크 인터페이스을 만들어 컨테이너의 네트워크 인터페이스와 매핑을 시킨다.

이렇게 만들어진 가상 네트워크 인터페이스는 veth 로 시작하고 ifconfig 명령어를 통해 확인할 수 있다.

 

그럼 컨테이너는 외부와의 소통을 위해 매핑된 이더넷을 통해 패킷을 주고받게 된다. (통신은 DataLink Layer 기반 통신을 기본으로 한다)

docker0 의 Private IP 대역은  172.17.0.0/16 으로 자동설정되게 된다. 그럼 docker0 라는 가상이더넷 브릿지가 관리하는 컨테이너는 172.17.x.x 로 하나의 내부 IP를 할당받게 된다.

 

"docker network ls" 명령어를 치게되면 bridge라는 docker network가 있는 것을 볼 수 있다.

 

bridge라는 네트워크의 구성을 "docker network inspect bridge" 명령어를 쳐 자세히 봐보자

일반적으로 아래의 Subnet 대역과 GateWay IP 를 할당 받게 된다.

 

실행중인 컨테이너가 있다면 Containers 에 실행중인 컨테이너의 정보가 나올텐데 IPv4Address가 172.17.A.B/16 의 형식으로 되어있을 것이다.

의심이 많은 개발자들은 고민에 빠지게 되는데, "네트워크에 할당 받은 IP 대역이 172.17.0.0/16인데 어찌 컨테이너의 IP 대역의 SubnetMask 가 255.255.0.0 인거지?" 와 같은 생각을 하게된다.

 

오해하지말자. 컨테이너는 가상이더넷 브릿지로부터 하나의 내부 IP를 할당 받는다. 뒤의 CIDR 값은 생략하고 읽으면 편하다.

 

컨테이너가 통신하는 또 다른 방법

이제까지 설명한 가상이더넷 브릿지를 통한 통신방법은 bridge 방식이라고 부른다.

"docker network ls" 명령어를 치게됐을 때, bridge 만 있던게 아니었다. host 라는 네트워크도 존재했는데 이는 무엇일까

 

inspect 로 찍어본 결과이다. 

Scope 를 보면 local 이라고 적혀있다. 이는 host 방식이라고 표현한다.

말그대로 특정 가상 브릿지가 각각의 고립된 컨테이너를 관리하는 방식이 아닌 host 와 네트워크를 함께쓰는 방식이다.

외부에서 접근하기

지금까지 말한 IP 앞에는 항상 "내부" 라는 표현이 붙어있었다. 이 내부 IP는 외부에서 접근하진 못한다. 그럼 어떻게 특정 컨테이너에 접근할 수 있을까?

컨테이너는 run 할 때 -p 옵션으로 포트포워딩을 할 수 있다. 

docker run -p {외부에서 접근하길 원하는 Port}:{실행 시킨 컨테이너의 Port} ...

이렇게 설정하고 netstat -nlp 를 찍어보면 외부에서 접근하길 원하는 Port가 LISTEN 상태가 되어있을 것이다.

iptables

그럼 이렇게 포트포워딩된 정보들은 iptable 에서 관리하게된다.

"iptables -t nat -L -n" 명령어를 통해 확인해보면 Chain PREROUTING을 통해 Chain Docker로 오게되고, 외부에서 접근한 Port 로 포워딩 할 컨테이너의 내부 IP와 Port로 매핑되는 것을 확인할 수 있다.

 

컨테이너끼리의 통신

이 글의 핵심키워드 도커 네트워크는 컨테이너와의 통신을 위해 만들어졌다고 했다.

근데 이전내용들은 실제로 어떻게 통신하는지의 내용이 없다.

 

Link 방식

DNS는 다들 알고 있을 것이다. 동적으로 바뀌는 IP 를 DNS 에서 관리함으로써 원하는 서버에 정적인 도메인을 가지고 동적인 IP에 접근하는것이다.

컨테이너 연동의 Link 방식도 비슷한 방식으로 구현된다. 동적으로 변경되는 컨테이너 IP를 대처하기 위해 컨테이너를 run 할 때, link 를 걸어 컨테이너 이름을 통해 통신할 수 있다.

 

하지만 Link 방식은 docker host 에 존재하는 컨테이너 사이에서만 유효하다. 만일 아래와 같이 docker host가 다른 컨테이너끼리는 Link 방식으로 통신할 수 없다.

Docker Network 구조도

 

Docker Network GateWay

가상이더넷 브릿지를 한번 살펴보자. 가상이더넷 브릿지엔 GateWay가 존재한다.

GateWay가 존재하므로 해당 GateWay주소를 토대로 Docker Host 내에서 내부통신을 할 수 있다. 

 

Target 주소 : {Docker Network Gateway}:{외부에서 접근하기 원하는 Port}

하지만 이 방법도 타 Docker Host로 통신할 수 있는 수단은 될 수 없다.

 

애초에 통신을 원하는 컨테이너끼리 모아둔 집합이 Docker Network 이니, 타 Docker Host와의 통신을 원한다면 Host의 주소를 바라보고 외부로 나가서 라우터를 타고 다시 Host, PortForwarding 을 통해 컨테이너에 접근하는 방법을 고려해야 할 것이다.

 

 

'Infra' 카테고리의 다른 글

[Infra] MSA 개념편  (0) 2024.02.26