Docker에서 서브넷을 적용할 수 있을까?

fever·2026년 4월 24일

개발고찰

목록 보기
8/8

배경

기존 서비스는 Windows 서버에서 JAR 파일을 직접 실행하는 방식으로 운영되고 있었다. 서버가 자주 불안정했고, Windows 환경 특성상 운영 자체가 불편한 점이 많았다. 결국 리뉴얼을 결정하면서 Linux + Docker 환경으로 전환하기로 했다.

전환을 준비하던 중 감사 일정이 잡혔다. 감사에서 가장 중요한 요구사항은 개인정보가 저장된 DB에 대한 접근 제한이었다.

요구사항을 정리하면:

  • DB는 외부에서 직접 접속 불가
  • API 서버만 외부에 노출
  • 나머지 서비스와 DB는 내부에서만 접근 가능
  • DB 접근은 반드시 서버 SSH 접속 후 컨테이너를 통해서만 가능

서브넷(Subnet)이란?

서브넷은 하나의 네트워크를 더 작은 단위로 나눈 것이다. 쉽게 말하면 같은 건물 안에서도 층별로 독립된 내선 전화망을 구성하는 것과 비슷하다. 같은 층(서브넷) 안에서는 자유롭게 통신할 수 있지만, 다른 층(서브넷)과는 별도의 경로를 통해야 한다.

예를 들어 172.10.0.0/24 라는 서브넷은:

  • 172.10.0.0 — 네트워크 주소
  • /24 — 앞 24비트가 네트워크 대역, 나머지 8비트가 호스트 대역
  • 172.10.0.1 ~ 172.10.0.254 범위의 IP를 사용할 수 있음

Docker 네트워크란?

Docker는 컨테이너 간 통신을 위한 가상 네트워크를 직접 구성할 수 있다. 기본적으로 컨테이너를 실행하면 bridge 라는 기본 네트워크에 연결되는데, 이 경우 모든 컨테이너가 같은 네트워크에 있어 서로 통신이 가능하다.

커스텀 네트워크를 만들면:

  • 같은 네트워크 안의 컨테이너끼리만 통신 가능
  • 컨테이너에 고정 IP 부여 가능
  • 네트워크 단위로 격리 가능

서브넷을 Docker에 적용할 수 있는 이유

전통적인 서버 환경에서 서브넷은 물리적인 네트워크 장비로 구성한다. 하지만 Docker는 소프트웨어적으로 가상 네트워크를 만들 수 있어서, 서브넷 개념을 컨테이너 레벨에서 그대로 구현할 수 있다.

즉 Docker 네트워크에 서브넷을 지정하면:

  • 같은 서브넷 안의 컨테이너끼리만 통신 가능
  • 다른 서브넷의 컨테이너는 접근 불가
  • 물리적인 네트워크 장비 없이 소프트웨어로 격리 가능

이 특성을 활용해서 외부에 노출할 서비스(API)내부에서만 동작할 서비스(Batch, DB 등) 를 분리했다.


적용

네트워크 생성

docker network create \
  --driver bridge \
  --subnet 172.10.0.0/24 \
  --gateway 172.10.0.1 \
  app-network
  • --driver bridge — 단일 호스트 내 컨테이너 간 통신
  • --subnet — 네트워크 대역 지정
  • --gateway — 게이트웨이 IP 지정

컨테이너 IP 고정

각 컨테이너에 고정 IP를 부여했다. IP가 고정되어 있으면 컨테이너가 재시작되어도 IP가 유지되기 때문에 서비스 간 통신 설정이 흔들리지 않는다.

docker run \
  --name app-api \
  --network app-network \
  --ip 172.10.0.11 \
  ...
컨테이너IP외부 노출
nginx-
app-api172.10.0.11❌ (nginx 통해서만)
app-a172.10.0.12
app-b172.10.0.13
app-mysql172.10.0.10

nginx를 통한 외부 노출

기존 nginx 컨테이너가 있다면 app-network에 추가로 연결할 수 있다. nginx는 여러 네트워크에 동시에 연결될 수 있기 때문에 외부 네트워크와 app-network 사이의 리버스 프록시 역할을 할 수 있다.

docker network connect app-network nginx
외부 요청 흐름
외부 → nginx → app-api (172.10.0.11)

내부에서만 접근 가능
app-a     (172.10.0.12)
app-b     (172.10.0.13)
app-mysql (172.10.0.10)

DB 접근 제한

DB는 app-network 내부에서만 접근 가능하기 때문에 외부에서 직접 접속할 수 없다. 반드시 서버에 SSH로 접속한 후 컨테이너를 통해 접근해야 한다.

# 서버 SSH 접속
ssh user@server-ip

# 컨테이너 진입 후 DB 접속
docker exec -it app-mysql bash
mysql -u root -p

마무리

처음에는 네트워크를 별도로 구성해야 한다는 게 번거롭게 느껴졌다. 그냥 포트를 열고 닫는 것만으로도 충분하지 않을까 싶었는데, 직접 구성해보니 생각보다 훨씬 명확하게 서비스를 격리할 수 있었다.

서브넷이라는 개념이 물리적인 네트워크 장비에서만 가능한 줄 알았는데, Docker에서 소프트웨어적으로 동일하게 구현할 수 있다는 게 인상적이었다.

다만 이 방식은 단일 호스트에서의 격리에 한정된다는 점을 염두에 두어야 한다. 서비스가 커지거나 멀티 호스트 환경이 필요해진다면 Docker 네트워크만으로는 한계가 있다. Kubernetes는 이런 네트워크 격리와 서비스 디스커버리를 훨씬 정교하게 다룰 수 있고, 실제로 이 부분이 Docker와 Kubernetes의 가장 큰 차이 중 하나라고 생각한다.

Docker 네트워크를 직접 구성해보면서 네트워크 격리의 개념을 이해할 수 있었고, 이게 Kubernetes에서는 어떻게 추상화되어 동작하는지 더 공부해보고 싶어졌다.

profile
선명한 삶을 살기 위하여

0개의 댓글