[Docker] 네트워킹과 Docker Compose
도커는 다른 환경으로부터 격리된 환경에서 작동하고, 도커를 통해 만든 애플리케이션을 배포하게 되면 localhost가 더 이상 호스트 머신의 localhost를 의미하지 않게 된다.
백엔드 / 프론트엔드 / 데이터베이스 각 애플리케이션을 도커를 통해 배포했다고 해보자.
로컬에서 도커를 사용하지 않고 배포한 경우 백엔드에서 데이터베이스로 통신할 때 localhost:27017처럼 localhost로 데이터베이스와 연결할 수 있지만, 각 애플리케이션을 도커를 사용해 배포한 경우 컨테이너들은 호스트 운영체제와 독립된 환경에서 동작하기에 localhost 말고 다른 방법으로 접속해야 한다.
docker run -p 8000:80 my_image
여기서 -p 8000:80 부분은 호스트 머신에서 사용할 포트 : 컨테이너 내부에서 사용할 포트를 의미한다.
즉, 외부에서 호스트 머신의 8000번 포트로 요청을 보내면 그 요청은 컨테이너의 80번 포트로 전달됨을 의미하고, 따라서 백엔드를 도커를 통해 배포해도 호스트 머신에서 localhost:8000 으로 접속 시 배포한 백엔드 서버로 접근할 수 있다.
단, 컨테이너 내부에서의 localhost는 호스트 머신의 localhost가 아님에 주의하자.
컨테이너 내부에서 호스트 머신에 접근하는 방법으로는 두 가지가 있다.
1. 특별한 DNS 사용
도커는 호스트 머신을 가리키는 특별한 DNS인 host.docker.internal을 제공하고, 이 주소로 컨테이너 내부에서 호스트 머신의 서비스에 쉽게 접근할 수 있다.
2. 호스트머신의 실제 IP 사용
ipconfig 명령어 등으로 호스트 머신의 실제 IP 주소를 찾은 후 그 IP 주소를 통해 연결할 수 있다.
다시 돌아와서, Docker Network를 사용하면 세 가지 애플리케이션을 도커를 통해 배포하고 각 컨테이너끼리 효과적으로 통신할 수 있다.
docker network create my-network
docker run --name mongodb --rm -d --network my-network mongo
docker run --name backend --rm -d -p 80:80 --network my-network backend
docker run --name frontend --rm -d -p 3000:3000 frontend
네트워크를 만들고 각 컨테이너들을 네트워크를 통해 배포한다.
프론트엔드는 어차피 사용자의 브라우저에서 실행되기에 도커 네트워크 내에서 다른 컨테이너와 직접 통신할 필요가 없으니 네트워크를 사용하지 않아도 된다.
백엔드와 데이터베이스가 통신할 때는 도커 네트워크 내 서비스 이름을 사용하니 데이터베이스를 시작할 때는 컨테이너의 포트를 호스트에 노출하지 않아도 된다. (MongoDB는 표준 포트인 27017을 내부적으로 사용한다)
네트워크 드라이버는 컨테이너간 네트워킹 기능을 구현하는 방법을 정의하고 서로 어떻게 통신할지를 결정한다.
도커는 기본적으로 여러 네트워크 드라이버를 제공한다.
네트워크 드라이버는 인터페이스이고, 도커가 제공하는 여러 구현체가 있다고 이해하면 된다.
Bridge : 가장 일반적인 네트워크 드라이버로 도커를 설치할 때 기본적으로 함께 제공된다.
단일 호스트 내의 컨테이너들이 서로 통신할 때 사용되고, 컨테이너가 시작할 때 Local Bridge Network에 연결된다.
Host : 호스트의 네트워크 스택을 직접 사용해 컨테이너가 호스트 머신의 네트워크 인터페이스와 같은 인터페이스를 사용한다.
Overlay : 여러 도커 호스트간 컨테이너들이 통신할 수 있게 해 클러스터 환경에서 유용하다.
호스트를 하나만 쓸 때는 웬만하면 Bridge를 사용한다.
애플리케이션 배포 상황에 따라서 적합한 드라이버를 선택하자.
지금 상황처럼 여러 컨테이너를 정의하고 실행할 때는 각 컨테이너를 하나씩 일일히 실행해도 괜찮지만, 도커 컴포즈를 사용하면 좀 더 편하게 실행할 수 있다.
도커 컴포즈는 여러 도커 컨테이너들을 정의하고 실행하기 위한 도구로 여러 컨테이너, 네트워크, 볼륨 설정을 하나의 yaml파일로 관리하고 데이터베이스 서버를 웹 서버보다 먼저 시작하도록 설정하는 것 처럼 컨테이너의 시작 순서를 정의할 수 있다.
이전에는 각각 docker run 명령어를 수행하면서 볼륨을 설정하고 네트워크를 설정해야 했지만 도커 컴포즈를 사용하면 명령어 한줄로 미리 정의된 명세대로 컨테이너를 실행할 수 있어 편하다.
version: "3.8"
services:
mongodb:
image: 'mongo'
volumes:
- data:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: user
MONGO_INITDB_ROOT_PASSWORD: secret
# networks:
# - networkName
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- '80:80'
volumes:
- logs:/app/logs
- ./backend:/app
- /app/node_modules
env_file:
- ./env/backend.env
depends_on:
- mongodb
frontend:
build: ./frontend
ports:
- '3000:3000'
volumes:
- ./frontend/src:/app/src
stdin_open: true # input
tty: true # terminal
volumes:
data:
logs:
데이터베이스 / 프론트엔드 / 백엔드 애플리케이션을 도커 컴포즈로 묶어서 실행하는 예시이다.
기본적으로 yml형식을 사용하고, 배열 항목을 정의할 때는 - 를, 환경 변수를 맵 형태로 정의할 때는 - 를 사용하지 않는다.
각 컨테이너를 실행할 때 기반이 되는 이미지는 이전에 빌드한 이미지도 가능하고, Dockerfile을 통해 이미지를 빌드하는 것도 가능하다. (build도 항상 이미지를 빌드하지는 않고, 빌드된 결과가 있으면 재사용한다)
이미지를 빌드할 때는 도커파일 이름, 도커파일의 위치, 빌드할 때 사용할 ARG 등을 정의할 수 있다.
version은 도커 컴포즈 파일의 버전을 의미하고 3.8은 도커 컴포즈 3.8 버전을 사용함을 의미한다.
서비스 내부의 volumes는 해당 컨테이너에 볼륨을 어떻게 마운트 할 지를 정의하고, 최상위 volumes 에서는 사용할 named 볼륨을 정의한다.
컨테이너를 실행할 때 환경 변수를 지정할 수 있다. 파일에 정의하고 파일을 가져오는 것도 가능하다.
depends_on으로 컨테이너의 실행 순서를 설정한다. 데이터베이스가 먼저 실행된 후 백엔드가 실행된다.
예시에서 네트워크를 사용하는 부분이 없는데, 도커 컴포즈를 사용할 때 네트워크를 별도로 정의하지 않으면 자동으로 bridge 드라이버를 사용하는 네트워크를 생성하고 해당 도커 컴포즈 파일 내부에 있는 컨테이너들이 사용하게 된다.
이 때 서비스 이름을 통해 서로를 식별할 수 있는데, 도커 컴포즈에서 서비스를 정의할 때 사용하는 이름은 docker ps -a 명령어로 나타나는 컨테이너 이름과는 다르다.
서비스 이름은 컴포즈 파일에서 사용하는 이름으로, 네트워킹 시 사용되고 컨테이너 이름은 실행 중인 도커 컨테이너의 이름으로 도커 컴포즈는 기본적으로 프로젝트 이름과 서비스 이름을 조합해서 컨테이너 이름을 짓는다.
docker-compose up / docker-compose down 명령어로 컨테이너를 실행하고 중지할 수 있고, -d 등 다양한 옵션을 추가할 수 있다.
'DevOps > Docker && Kubernetes' 카테고리의 다른 글
[k8s] 쿠버네티스 도입 (0) | 2023.12.17 |
---|---|
[Docker] Dockerfile 프로젝트 배포하기 (2) | 2023.12.06 |
[Docker] Docker Compose (0) | 2023.03.24 |
[Docker] 도커 파일 시스템과 볼륨 (0) | 2023.03.09 |
[Docker] 도커 활용하기 (0) | 2023.03.08 |
댓글
이 글 공유하기
다른 글
-
[k8s] 쿠버네티스 도입
[k8s] 쿠버네티스 도입
2023.12.17 -
[Docker] Dockerfile 프로젝트 배포하기
[Docker] Dockerfile 프로젝트 배포하기
2023.12.06 -
[Docker] Docker Compose
[Docker] Docker Compose
2023.03.24 -
[Docker] 도커 파일 시스템과 볼륨
[Docker] 도커 파일 시스템과 볼륨
2023.03.09