이전글에서 여러 image를 한 번에 생성 후 실행까지 하는 docker-compose에 대해 알아보았다.
간단하게 단일, 또는 여러 개의 container와 docker-compose가 어떻게 다른지 정리하겠다.
0. multiple container vs docker-compose
dockerfile을 통한 다중 컨테이너 실행 방식 | docker-compose를 통한 실행 방식 | |
image 빌드 명령 | docker build 명령 | docker-compose up 명령어를 통해 여러개의 컨테이너의 빌드와 실행이 동시에 진행됨. |
container 실행 명령 | docker run 명령 | |
선언형 툴 | Dockerfile.yml | docker-compose.yml |
container끼리 통신 | 직접 컨테이너 별 네트워크 설정 필요. (각각의 컨테이너는 docker bridge network에 연결되나 컨테이너간의 연결은 직접적인 연결이 필요함.) |
docker-compose로 부터 한 번에 네트워크 정의 |
의존성 관리 | 의존성에 맞게 특정 순서대로 실행되도록 수동으로 제어해야함. | docker-compose의 depends_on 키워드로 의존성을 정의할 수 있음. |
환경 변수 및 설정 | 각 컨테이너 별로 Dockerfile에 일일이 지정해야한다. | docker-compose로 전체 스택을 한 번에 설정 가능. |
데이터 및 볼륨 관리 | 각 컨테이너 별로 명령어를 통한 수동 설정 | docker-compose.yml에서 볼륨을 선언 후 공유 가능. |
(multiple container는 말 그대로 단일 컨테이너를 여러 개 띄운 것을 말하는 것이다. 따로 정의된 container는 아니다.)
전자의 경우는 모든 컨테이너에 대해 개별적인 관리를 해주어야 하기 때문에 일관된 관리를 하기 어렵다.
후자의 경우는 여러개의 컨테이너 간 일어나는 모든 상호 작용에 대한 관리를 할 수 있기에
여러개의 컨테이너를 사용한 서비스를 사용한다면 docker-compose가 압도적으로 편리하도록 구성되어 있다.
https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-docker-compose/
지난번 글부터 docker 내부의 네트워크가 있고, 이를 사용한다는 얘기를 했었다.
그렇지만 계속해서 docker 내부의 네트워크에 대해 따로 정리하지는 않았었다.
사실 이번 글은 docker의 네트워크에 대한 얘기를 하고자 한다.
1. NAT(Network Address Translation)
private network와 public network의 각각의 ip를
라우터를 통해 매핑해서 트래픽을 주고 받는 기술을 통틀어 NAT라고 한다.
가령 private network를 구축한다고 가정해보자.
네트워크 내부의 여러 호스트에 대해 각각의 public IP를 할당하게 된다면,
IP v4를 기준으로 할 때, public IP는 아마 남아나지가 않을 것이다.
그러나 이러한 일은 발생하지 않고, 앞으로도 일어나지 않을 것이다.
하나의 공인 IP 주소를 private network의 여러 host가 사용하기 위해 사용하는 NAT의 기술 중 하나가
IP Masquerade 이다. 이 방식을 통해서 public IP를 절약할 수 있게 된다.
이 기술은 private network의 host가 외부와 통신할 때 모든 private IP가 단일 public IP로 매핑되도록 변환한다.
그러나 이러한 방식에는 단점이 있다.
바로 외부에서 내부 private network의 특정 host로 매핑이 안되기 때문에, 호스트의 구분을 할 수가 없다.
따라서 이를 구분하기 위해 port정보를 추가해 NAT를 보완한 기능이 NAPT이다.
2. NAPT(Network Address Port Translation)
말 그대로, NAT에 Port 정보 해석을 추가한 기법이다.
외부 공인 IP로 전송하는 방식은 기존과 동일하나, 사설IP의 정보와 이 IP의 Port를 기록한다.
이 두개가 외부 공인 IP의 어떤 포트에 매핑될지를 명시한다.
그렇기 때문에 외부에서 내부로 접근할 시 기존에는 private IP의 구분이 불가능했지만
이번에는 Port의 정보를 통해서 정확한 매핑이 되기 때문에 양방향 통신이 가능해진다.
예시)
- 내부 네트워크에서 192.168.1.2:5000이라는 장치가 외부로 요청을 보낼 때,
NAT는 이 장치를 공인 IP 203.0.113.1로 변환하지만,
NAPT는 포트 번호도 함께 변경하여 203.0.113.1:30001로 보낸다. - 동일한 내부 네트워크에서 192.168.1.3:6000이라는 장치가 또 다른 요청을 보내면,
NAPT는 이를 203.0.113.1:30002로 변환하여 보낸다. - 외부에서 203.0.113.1:30001로 들어오는 트래픽은 다시 192.168.1.2:5000으로,
203.0.113.1:30002로 들어오는 트래픽은 192.168.1.3:6000으로 라우팅된다.
2.5. Port Forwarding
포트 포워딩이란 기본적으로 private network와 public의 port를 매핑시켜 통신할 수 있도록 열어주는 것을 의미한다.
위에서 설명한 NAPT의 매핑과정이 바로 포트 포워딩이 된다.
사설 IP의 특정 포트로 포워딩 하기 위해서는 반드시 (public IP의 Port) : (private IP + Port)의 1:1 매핑 정보가 필요하다.
3. Docker의 Network 구성
소프트웨어 기반의 가상 브릿지, docker0 라는 L2 Switch를 중심으로 네트워크를 구성한다.
Docker의 container는 가상 OS를 사용하는 것이고, 가상의 머신을 사용하는 것이므로
이때 NIC(Network Interface Controller : 네트워크 카드) 또한 가상으로 사용한다.
이 가상 NIC와 실제 물리 컴퓨터의 NIC를 연결하는 방식으로 내부의 네트워크를 구성한다.
그리고 외부와의 네트워크 연결은 NAPT와 ip masquerade를 사용한다.
4. Docker Network Option
- Bridge 옵션 : 하나의 호스트 컴퓨터 내에서 여러 컨테이너가 소통할 수 있도록 (Default 옵션)
- Default Bridge (기본 제공 Bridge)
- 따로 명시하지 않았다면, Docker의 기본 네트워크 구성은 Docker bridge network이다.
- User-defined Bridge
- 컨테이너간 Automatic DNS Resolution 제공
- Default Bridge (기본 제공 Bridge)
- Host 옵션 : 컨테이너와 호스트 컴퓨터가 동일한 네트워크에서 가동
- Bridge는 컨테이너와 호스트 네트워크를 분리하지만, 이 옵션은 분리하지 않고 같이 사용.
5. docker compose 내 포트 포워딩을 통한 연결
방법 1.
1) Bridge 네트워크 정의
networks:
{user_defined_network_name}:
driver: bridge
2) docker-compose.yml에서 포트포워딩
version: "3"
services:
postgres:
...
ports:
- 5432:5432 // 앞이 host 네트워크의 포트, 뒤가 bridge의 내부 포트
networks:
- {user_defined_network_name} // 앞서 지정한 네트워크 이름을 입력
...
docker_tutorial:
build: .
ports:
- 8080:8080
networks:
- {user_defined_network_name}
...
방법 2.
Hostname 만 명시적으로 등록하는 것으로도 충분하다.
version: "3"
services:
postgres:
container_name: postgres_host
hostname: postgres_host // 이처럼 통신을 하기 위한 이름을 명시적으로 지정한다.
image: postgres:15
ports:
- 5432:5432
...
docker_tutorial:
build: .
ports:
- 8080:8080
...
이후 docker_tutorial에서 postgres로 접근하려면 postgres_host:5432 로 접근하면 된다.
https://docs.docker.com/compose/how-tos/networking/
https://docs.docker.com/engine/network/drivers/bridge/
https://docs.docker.com/engine/network/
https://ooeunz.tistory.com/104
https://imjeongwoo.tistory.com/107
'정보 > Dev' 카테고리의 다른 글
Github Action을 이용한 CI/CD Workflow (1) | 2024.10.24 |
---|---|
Docker (5) - CI/CD with Docker Workflow (3) | 2024.10.21 |
Docker (3) - 다중 컨테이너를 묶어 정의하기 : docker-compose (0) | 2024.10.18 |
Docker (2) - Hypervisor와 Docker의 가상화 방식 (2) | 2024.10.16 |
Docker (1) - Docker? (1) | 2024.10.15 |