Docker Network
Docker Network는 컨테이너들이 서로 통신하거나 외부와 연결되는 방식을 관리하는 가상 네트워크입니다. 각 컨테이너는 기본적으로 격리된 네트워크 네임스페이스를 갖고, Docker Network를 통해 필요한 컨테이너끼리만 선택적으로 연결합니다.
▶아키텍처 다이어그램
🔍 구조 다이어그램점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다
컨테이너는 각자 격리된 네트워크 공간에서 실행됩니다. 그런데 실제 서비스는 웹 서버가 API를 호출하고, API가 데이터베이스에 접속하는 식으로 여러 프로세스가 통신해야 합니다. 컨테이너의 IP 주소는 재시작할 때마다 바뀔 수 있어서 IP를 직접 설정에 박아 넣으면 컨테이너를 새로 띄울 때마다 설정이 깨집니다. 또한 모든 컨테이너가 아무런 제한 없이 서로 통신할 수 있다면, 데이터베이스에 접근할 필요가 없는 프런트엔드 컨테이너까지 DB 포트에 접근 가능해져 보안 경계가 무너집니다.
초기 Docker에서는 `--link` 옵션으로 컨테이너를 연결했습니다. 한 컨테이너의 환경 변수에 다른 컨테이너의 IP를 주입하는 방식이었는데, 컨테이너 수가 늘어나면 링크 관계가 복잡해지고 순서 의존성도 생겼습니다. Docker 1.9에서 사용자 정의 네트워크가 도입되면서 이 문제가 정리됐습니다. 사용자 정의 Bridge 네트워크에 연결된 컨테이너는 서비스 이름으로 서로를 찾을 수 있는 내장 DNS를 제공받습니다. 이후 Docker Swarm과 함께 Overlay 네트워크가 추가되면서 여러 물리 호스트에 걸친 컨테이너 통신까지 하나의 네트워크 추상화로 다룰 수 있게 됐습니다.
Docker Network는 드라이버별로 통신 경로를 다르게 만듭니다. Bridge는 같은 호스트 안의 가상 스위치 방식이고, 사용자 정의 Bridge를 쓰면 Docker의 내장 DNS가 켜져 컨테이너 이름을 그대로 호스트명처럼 찾을 수 있습니다. 기본 bridge인 `docker0`는 Docker가 만드는 기본 네트워크 인터페이스이고, 사용자 정의 Bridge보다 서비스 이름 해석과 격리 설정이 단순하지 않습니다. Host 모드는 호스트 네트워크 스택을 그대로 써서 NAT, 즉 컨테이너 주소와 외부 주소를 중간에서 바꿔 연결하는 단계가 줄어드는 대신 포트 충돌을 직접 감수합니다. Overlay는 VXLAN, 즉 여러 호스트 위에 가상 네트워크를 한 겹 더 씌우는 방식으로 멀티 호스트 통신을 이어 줍니다. 결국 드라이버 선택은 이름 기반 통신이 필요한지, 성능을 위해 격리를 얼마나 포기할지, 여러 호스트를 하나의 네트워크처럼 다뤄야 하는지에 따라 갈립니다.
Docker Network와 Docker Volume은 둘 다 컨테이너의 격리 경계를 선택적으로 열어주는 메커니즘이지만 대상이 다릅니다. 네트워크는 통신 경로를, 볼륨은 데이터 저장 경로를 관리합니다. 네트워크 안에서 Bridge와 Host의 차이도 중요합니다. Bridge는 컨테이너마다 별도 IP를 갖고 NAT를 거쳐 외부와 통신하므로 격리가 유지됩니다. Host는 격리를 포기하고 호스트의 IP와 포트를 직접 쓰므로 성능은 좋지만 포트 충돌 위험이 있습니다. 격리와 보안이 우선이면 사용자 정의 Bridge를, 네트워크 성능이 결정적이면 Host를 선택합니다.
Docker Compose 프로젝트에서는 보통 사용자 정의 Bridge 네트워크를 선언하고 서비스들을 연결합니다. 웹 서버는 `api:8080`, API는 `db:5432`처럼 서비스 이름으로 통신하므로 IP를 관리할 필요가 없습니다. 프런트엔드와 백엔드를 별도 네트워크에 두면 프런트엔드 컨테이너가 데이터베이스에 직접 접근하는 것을 네트워크 수준에서 차단할 수 있습니다. 포트 포워딩(`-p 8080:80`)은 외부에서 컨테이너로 들어오는 진입점을 만들 때 사용합니다. 컨테이너 간 내부 통신에는 포트 포워딩이 필요 없고, 같은 네트워크에 연결되어 있으면 바로 통신됩니다. 이 구분을 놓치면 불필요하게 포트를 외부에 노출하게 됩니다.