이 글은 도커 공식문서(Docker workshop)를 기반으로 정리되었습니다.
공식 튜토리얼에서 이렇게 설명한다.
'컨테이너 시작 시 네트워크를 할당하거나, 이미 실행 중인 컨테이너에 네트워크를 할당할 수 있다.'
$ docker network create todo-app
네트워크를 할당하는 것치고 명령어가 너무 간단하다.
내가 아는 그 네트워크가 맞는 건가 싶어 공식 문서의 설명을 읽어보았다.
Networking
Learn how networking works from the container's point of view
docs.docker.com
❓네트워킹 : 컨테이너의 관점에서.
컨테이너 네트워킹은 컨테이너들이 서로 또는 Docker 외부의 워크로드와 연결 및 통신할 수 있도록 하는 기능을 의미한다.
- 기본적으로 컨테이너는 네트워킹이 활성화된 상태로 실행되며, 외부로 연결을 할 수 있다.
- 컨테이너는 자신이 어떤 네트워크에 연결되어 있는지, 혹은 통신 대상이 Docker 컨테이너인지 아닌지에 대해 알지 못한다.
- 컨테이너는 단순히 네트워크 인터페이스(IP 주소, 게이트웨이, 라우팅 테이블, DNS 서비스 등) 를 인식할 뿐이다.
- 따라서, 컨테이너간 통신을 위해서는 네트워크 연결 설정이 필요하다.
- 단, 컨테이너가 none 네트워크 드라이버를 사용할 경우 네트워크가 비활성화된다.
사용자 정의 네트워크 (User-defined Networks)
Docker에서는 사용자 정의 네트워크를 생성해 여러 컨테이너를 동일한 네트워크에 연결할 수 있다.
즉, 컨테이너들은 서로의 IP 주소 또는 컨테이너의 이름으로 통신할 수 있다.
아래와 같이 브리지 네트워크 드라이버를 사용해 네트워크를 만들고 컨테이너를 해당 네트워크에 추가하면 된다.
# "my-net"이라는 사용자 정의 네트워크 생성 (브리지 네트워크 드라이버 사용)
$ docker network create -d bridge my-net
# "my-net" 네트워크에 연결된 "container3" 컨테이너 실행
$ docker run --network=my-net -itd --name=container3 busybox
* BusyBox: 작고 가벼운 리눅스 유틸리티 모음을 제공하는 소프트웨어
❓브리지는 꼭 써야 하나? 아까 명령어에서는 bridge를 적어주지 않았는데.
네트워크를 생성할 때 네트워크 드라이버를 명시하지 않으면 기본값(default) 이 사용된다.
$ docker network create todo-app # 기본값이 bridge
$ docker network create -d bridge todo-app # 명시적으로 bridge 사용
생성된 네트워크 리스트 확인
$ docker network ls
네트워크에 연결된 모든 컨테이너와 그 IP 주소를 확인
$ docker network inspect <network id>
<네트워크 공유 예시 >
$ docker network create -d bridge my-net
$ docker run -d --name container1 --network my-net busybox sleep 3600
$ docker run -d --name container2 --network my-net busybox sleep 3600
$ docker exec -it container1 ping container2
$ docker network inspect my-net
❓기본적으로 Docker에서 컨테이너는 실행할 명령어가 끝나면 즉시 종료되기 때문에 컨테이너를 일정 시간 동안 실행 상태로 유지하기 위해 sleep 3600 명령을 사용한다.
Bridge와 같은 다양한 네트워크 드라이버
Docker는 여러 가지 네트워크 드라이버를 지원하며, 사용 목적에 따라 선택할 수 있다.
네트워크 드라이버 | 설명 |
bridge(기본값) | 독립적인 네트워크를 생성하여 컨테이너끼리 통신할 수 있도록 함 (기본적으로 $docker network create 시 사용됨) |
host | 컨테이너와 Docker host간 격리를 없애고, 컨테이너가 호스트의 네트워크를 직접 사용하도록 설정 (localhost로 직접 접근 가능) |
overlay | 여러 Docker 호스트에 걸쳐 컨테이너를 연결할 때 사용 (주로 Swarm 모드에서 사용) |
none | 네트워크를 비활성화하여 외부와 통신하지 않도록 설정 |
macvlan | 컨테이너가 고유한 MAC 주소를 가지도록 설정하여 실제 네트워크에 직접 연결 |
ipvlan | macvlan과 유사하지만, 컨테이너가 동일한 MAC 주소를 공유하고 IP 주소만 분리하여 사용 |
❓Swarm 모드
여러 개의 Docker 호스트(서버)를 하나의 클러스터로 묶어 컨테이너를 배포하고 관리할 수 있도록 하는 오케스트레이션(Orchestration) 기능. google에 Kubernetes가 있다면, Docker에는 Swarm이 있다.
좀 더 상세한 사용자 정의 네트워크 생성 예시
# 서브넷 및 게이트웨이 지정
$ docker network create --driver bridge --subnet 10.5.0.0/24 --gateway 10.5.0.1 todo-app
# IP 범위 설정
$ docker network create --driver bridge --subnet 10.5.0.0/24 --ip-range 10.5.0.100/30 --gateway 10.5.0.1 todo-app
$ docker network create \
--driver bridge \
--subnet 10.5.0.0/24 \
--gateway 10.5.0.1 \
--ip-range 10.5.0.100/30 \
--dns 8.8.8.8 \
--internal \
todo-app
컨테이너 네트워크 (Container networks)
일반적으로 컨테이너는 각자 고유한 네트워크 인터페이스를 갖지만, --network container : <name | id> 옵션을 사용해 컨테이너를 다른 컨테이너의 네트워크에 직접 연결할 수 있다.
즉, 네트워크 환경을 완전히 공유하여 두 컨테이너가 같은 IP 주소, 같은 네트워크 인터페이스를 사용하도록 한다.
네트워크를 공유하는 컨테이너는 이미 다른 컨테이너의 네트워크 설정을 그대로 사용하므로, 당연하게도 다음과 같은 옵션을 사용할 수 없다.
- --add-host (호스트 추가)
- --hostname (컨테이너 호스트 이름 설정)
- --dns, --dns-search, --dns-option (DNS 관련 설정)
- --mac-address (MAC 주소 설정)
- --publish, --publish-all, --expose (포트 매핑 관련 설정)
<네트워크 공유 예시>
$ docker run -d --name redis-container redis --bind 127.0.0.1
$ docker run --rm -it --network container:redis-container redis redis-cli -h 127.0.0.1
포트를 외부에 공개 (Published Ports)
브리지 네트워크의 컨테이너들의 내부 포트는 기본적으로 비공개로 설정되어있기 때문에, 직접 외부에서 접근할 수 있도록 별도 설정을 해주어야한다.
컨테이너의 포트를 외부에서 사용할 수 있도록 하려면 --publish (-p) 옵션을 사용해야 한다.
이 옵션은 host와 컨테이너 간의 포트 매핑을 설정하며, Docker는 내부적으로 방화벽 규칙을 추가하여 외부에서 접근할 수 있도록 한다.
포트매핑 예시
-> 왼쪽이 호스트, 오른쪽이 컨테이너 (호스트:컨테이너)
명령어 | 설명 |
-p 8080:80 | 호스트의 8080포트를 컨테이너의 80포트에 매핑(TCP) |
-p 192.168.1.100:8080:80 | 특정 호스트 IP(192.168.1.100)의 8080포트를 컨테이너의 80포트에 매핑 |
-p 8080:80/udp | 호스트의 8080포트를 컨테이너의 80포트에 매핑(UDP) |
-p 8080:80/tcp -p 8080:80/udp | TCP 및 UDP 포트 둘 다 8080->80으로 매핑 |
'Cloud > Docker' 카테고리의 다른 글
[Docker] Multi-stage Build (0) | 2025.02.12 |
---|---|
[Docker] Node.js 경량 웹서버 컨테이너화 및 MySQL 연동 (0) | 2025.02.10 |
[Docker] 볼륨(Volume)을 이용한 데이터 영속성 관리 (0) | 2025.02.05 |
[Docker] 도커를 이용한 애플리케이션 컨테이너화 및 배포 과정 (0) | 2025.02.05 |