개요
이번 게시글에서는 도커 환경에서 중요한 개념 중 하나인 서비스 디스커버리 에 대해서 자세하게 기록해보려고 합니다.
이 글은 컨테이너 기반 환경에서 서비스 간 통신을 어떻게 효율적으로 관리할 지 고민하는 분들에게 큰 도움이 될 수 있을거예요!
서비스 디스커버리란?
서비스 디스커버리는 분산 시스템에서 동적으로 실행 중인 서비스(또는 컨테이너)를 찾아내고,
그 서비스에 접근할 수 있도록 정보를 제공하는 메커니즘입니다.
도커와 같은 컨테이너 환경에서는 컨테이너가 생성되고 삭제되는 일이 빈번하게 발생하며,
IP 주소나 포트가 동적으로 할당되기 때문에 고정된 위치로 서비스를 호출하기가 어렵습니다.
이때 서비스 디스커버리가 이 문제를 해결해줍니다.
쉽게 말해, 서비스 디스커버리는 "내가 필요한 서비스가 어디에 있는지, 어떻게 연결해야 하는지" 를 자동으로 알려주는 똑똑한 전화번호부 같은 역할을 합니다.
왜 필요할까?
- 동적 IP 할당: 도커 컨테이너는 실행될 때마다 IP가 새로 할당되므로, 고정된 IP로 통신하면 연결이 끊어질 수 있습니다.
- 스케일링: 서비스가 확장되거나 축소될 때마다 컨테이너 수가 변동되며, 이를 수동으로 추적하기 어렵습니다.
- 장애 복구: 컨테이너가 실패하고 재시작될 때, 새로운 인스턴스를 빠르게 찾아 연결해야 합니다.
이제 도커에서 서비스 디스커버리가 어떻게 동작하는지, 그리고 어떤 방법들이 있는지 살펴볼게요!
도커의 서비스 디스커버리 방법
도커는 기본적으로 서비스 디스커버리를 지원하며, 이를 구현하는 주요 방법은 다음과 같습니다!
1. 도커 네트워크와 DNS 서버
도커는 기본적으로 컨테이너 간 통신을 위해 **브리지 네트워크(Bridge Network)**를 제공합니다.
사용자 정의 네트워크를 생성하면, 도커는 내부 DNS 서버를 통해 컨테이너 이름을 기반으로 서비스를 찾을 수 있게 해줍니다.
- 특징: 같은 네트워크에 속한 컨테이너는 서로의 이름을 호스트명으로 사용해 통신 가능.
- 장점: 설정이 간단하고 별도의 외부 툴 필요 없음.
- 단점: 단일 호스트에 국한되며, 멀티 호스트 환경에서는 추가 설정 필요.
2. Docker Compose
Docker Compose는 다중 컨테이너 애플리케이션을 정의하고 실행하는 도구로, 기본적으로 네트워크를 생성하며 서비스 이름을 통해 디스커버리를 지원합니다.
- 특징: docker-compose.yml 파일에서 서비스 이름을 정의하면 자동으로 DNS 기반 디스커버리 가능.
- 장점: 개발 환경에서 사용하기 편리.
- 단점: 프로덕션 환경에서는 제한적.
3. Docker Swarm
Docker Swarm은 도커의 오케스트레이션 도구로, 멀티 호스트 환경에서 서비스 디스커버리를 제공합니다.
- 특징: Swarm 모드에서 서비스 이름으로 로드 밸런싱과 디스커버리 지원.
- 장점: 네이티브 도구로 확장성 좋음.
- 단점: 복잡한 설정 필요.
Docker Compose로 서비스 디스커버리 연습해보기!
이제 이론은 충분히 다뤘으니, 실제로 Docker Compose를 사용해 서비스 디스커버리를 구현해보겠습니다.
간단한 웹 애플리케이션과 데이터베이스를 연결하는 예제를 만들어볼게요.
예제 시나리오
- 웹 서비스: Flask로 만든 간단한 서버
- 데이터베이스: Redis를 사용해 데이터 저장
1. 프로젝트 구조
service-discovery-example/
├── docker-compose.yml
├── app/
│ └── app.py
└── Dockerfile
2. 코드 작성
app/app.py
(Flask 애플리케이션)
from flask import Flask
import redis
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = cache.incr('hits')
return f'Hello World! I have been seen {count} times.\n'
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
여기서 redis
는 Redis 컨테이너의 서비스 이름으로, Docker Compose가 자동으로 이를 IP로 변환해줍니다.
Dockerfile
(웹 서비스 빌드)
FROM python:3.9-slim
WORKDIR /app
COPY app/ .
RUN pip install flask redis
CMD ["python", "app.py"]
docker-compose.yaml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- redis
redis:
image: "redis:alpine"
3. 실행
터미널에서 다음 명령어를 실행해줘요!
docker-compose up --build
4. 결과확인
브라우저에서 http://localhost:5000
에 접속하면,
페이지 조회 수가 증가하는 것을 볼 수 있습니다!
여기서 웹 서비스는 redis
라는 이름으로 Redis 컨테이너를 찾아 통신합니다. 이게 바로 서비스 디스커버리 의 마법입니다!