
도커에는 가상 컨테이너 기술이 있는 것처럼 가상 네트워크 기술이 존재한다.
이번 포스트에서는 도커의 네트워크에 대해서 알아보자.
도커의 가상 네트워크 기술은 서버 한 대 안에서 네트워크를 구성하는 기술이다.
이 네트워크 안에서 컨테이너끼리 통신이 가능하고 바깥에 서버와도 통신이 가능하다.

이 도커 네트워크의 구성을 알아보자.
도커를 설치하고 실행을 시키면 도커 네트워크 브릿지를 생성을 한다.
이 네트워크 브릿지를 docker0라고 부르는데 공유기 역할을 한다.
이 때, docker0에 네트워크를 연결할 가상의 인터페이스가 호스트 OS에 생성이 된다.
docker0는 ip를 할당을 받고 네트워크 안에서 생성이 된 컨테이너에 ip를 할당을 해준다.
마찬가지로 컨테이너가 생성이 될 때, 네트워크 통신을 위한 가상 인터페이스 Veth가 생성이 된다.
(이것도 호스트 OS에 생성이 된다.)
이 가상 인터페이스로 전달되는 네트워크는 각각에 해당하는 브릿지나 컨테이너로 전달이 된다.
만약 컨테이너1에서 컨테이너2로 네트워크를 전달한다고 해보자.
그러면 Veth1에서 Veth2로 네트워크가 보내지는데 이 가상네트워크는 물리 네트워크 기기가 아니기 때문에 물리적으로 전달하는 기기가 없고 소프트웨어적으로 전달을 해주어야 한다.
이 때, 가상 인테페이스간의 네트워크를 전달하기 위한 규칙이 정해지는데 이 규칙이 호스트 OS의 커널 영역에 iptable에 저장이 된다.
이 iptables에 라우팅 규칙이 정의가 되고 네트워크는 이 규칙대로 전달이 된다.
이를 바탕으로 정리를 하면 컨테이너1과 연결된 Veth1에서 컨테이너2와 연결이 된 Veth2의 ip주소를 도착지로 정하고 iptables에 규칙대로 Veth1에서 Veth2로 네트워크를 보내면 컨테이너2로 네트워크가 전달이 된다.
가상 네트워크 안에서 실행한 컨테이너끼리는 통신이 가능하다.
하지만 가상네트워크 밖이나 호스트OS에서 접근을 하기 위해서 이 포트포워딩 기술이 필요하다.
그러면 먼저 포트포워딩이 무엇인지 알아보자.

포트포워딩은 공인ip주소의 포트와 사설ip주소의 포트를 사용자가 직접 연결하는 기술이다.
위 그림 처럼 공인ip 12.34.56.78의 80포트와 사설ip 192.168.0.2의 80포트를 연결을 시키면 공인 ip 12.34.56.78:80으로 요청을 내면 포트포워딩 룰의 맞춰서 192.168.0.2:80 요청을 보낸다.
이 포트포워딩을 아래 명령어로 도커에서 사용을 할 수 있다.
docker run -p {HostOS의 포트}:{컨테이너의 포트}
위 그림에서 docker run -d -p 8001:80 --name nginx nginx을 실행하고 HostOS 자신을 가르키는 localhost의 8001로 요청을 보내고 있다.
그러면 docker의 포트포워딩 기술로 인해서 localhost:8001로 들어온 요청을 172.17.0.2:80로 변경을 해서 전달을 하는 것이다.
도커는 컨테이너들이 사용할 수 있는 DNS서버를 제공한다.
DNS 서버는 외우기 힘든 ip를 도메인 주소와 맵핑을 시켜서 도메인 주소 접속을 할 수 있도록 하는 서버이다.
이 도커 DNS서버에도 ip주소와 도메인 주소가 저장이 되어 있는데 도메인 주소는 컨테이너의 이름으로 저장이 된다.
이 때문에 컨테이너들은 ip 주소가 아닌 컨테이너의 이름으로 통신을 할 수 있다.
다만 도커 실행시 기본으로 생성이 되는 docker0 브릿지에 경우 DNS 서버 기능을 사용할 수 없다.
그래서 DNS 서버 기능을 사용하기 위해서 사용자 직접 네트워크를 생성을 해야 한다.
컨테이너를 재시작을 하면 ip 주소는 변경이 된다. 변경이 된 ip주소는 자동으로 DNS 서버에 업데이트가 된다. 그래서 컨테이너의 이름만 잘 알고 있으면 재시작이 되어도 요청을 보낼 수 있다.