우당탕탕 개발일지
[MSA] Docker-Compose(2) 본문
도커 컴포즈를 사용하려면 도커 컴포즈가 관리할 docker-compose 파일을 생성해야 한다. 물론 각 서비스들의 도커 파일이 생성되어 있어야 한다.
1. Docker-Compose 파일 작성
로컬에서 MSA를 구성했을 때는 호스트 이름이 localhost 포트 번호가 모두 달랐다. 이전 글에서는 단일 마이크로서비스만 실행했기에 포트 번호를 다르게 해도 됐었지만, MSA는 핵심 서비스를 찾아야 하기에 도커에서 실행할 때는 각 서비스의 호스트 이름이 모두 다르고 포트 번호가 8080으로 같다.
현재 내가 구성하려는 서비스의 각 포트 번호는 다음과 같다.
Service | Port |
Eureka | 8761 |
Api-Gateway | 8000 |
Hospital-Service | 9001 |
User-Service | 9002 |
Emergency-Service | 9003 |
Reservation-Service | 9004 |
Mypage-Service | 9005 |
Config-Server | 8888 |
version: '3.8'
services:
eureka-server:
image: tirtir0827/service-discovery
container_name: eureka-container
networks:
- docker-network
ports:
- 8761:8761
environment:
- EUREKA_SERVER_NAME=eureka-server
- PORT=8761
api-gateway:
image: tirtir0827/api-gateway
container_name: gateway-container
networks:
- docker-network
ports:
- 8000:8000
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=8000
depends_on:
- eureka-server
- hospital-service
- reservation-service
- emergency-service
- mypage-service
- user-service
hospital-service:
image: tirtir0827/hospital-service
container_name: hospital-container
networks:
- docker-network
ports:
- 9001:9001
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9001
depends_on:
- eureka-server
user-service:
image: tirtir0827/user-service
container_name: user-container
networks:
- docker-network
ports:
- 9002:9002
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9002
depends_on:
- eureka-server
emergency-service:
image: tirtir0827/emergency-service
container_name: emergency-container
networks:
- docker-network
ports:
- 9003:9003
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9003
depends_on:
- eureka-server
reservation-service:
image: tirtir0827/reservation-service
container_name: reservation-container
networks:
- docker-network
ports:
- 9004:9004
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9004
depends_on:
- eureka-server
mypage-service:
image: tirtir0827/mypage-service
container_name: mypage-container
networks:
- docker-network
ports:
- 9005:9005
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9005
depends_on:
- eureka-server
config-server:
image: tirtir0827/config-server
container_name: config-container
networks:
- docker-network
ports:
- 8888:8888
networks:
docker-network:
external: true
2. Docker-Compose 실행
docker compose up -d
잘 실행이 되었으나, 애플리케이션 실행 유지 시간이 3분을 넘기지 못하였다. 네트워크에 이상이 있는 것 같아서 다음 커맨드를 실행시켜 연결시킨 docker-network를 확인했다.
docker network inspect docker-network
네트워크는 생성이 되어있지만, 도커 컴포즈로 실행시킨 컨테이너가 연결되어 있지 않았다. 임시 방편으로 수동으로 네트워크를 연결했다.
수동 네트워크 연결
docker network connect docker-network <컨테이너 ID>
애플리케이션 application.yml 수정
각 서비스가 Eureka Server와 통신이 되도록 설정이 되어 있어야 한다.
eureka:
client:
serviceUrl:
defaultZone: http://eureka-container:8761/eureka/
두 방법으로 진행 시 잘 실행이 되었으나, 도커 컴포즈를 종료 후 다시 시작할 때 네트워크가 생성되지 않는게 문제였다.
도커 네트워크 명시적 설정
docker-network 네트워크를 명시적으로 만들어주니 Eureka나 Api-Gateway와 같은 주요 서비스는 연결되었다.
docker network create --driver=bridge --subnet=172.72.0.0/16 --ip-range=172.72.0.0/24 --gateway=172.72.0.1 docker-network
문제는 Config-Server가 시작되고 네트워크에 연결 후 나머지 서비스들이 연결되어야 하지만 도커 컴포즈의 실행 순서가 보장되지 않아 순서가 꼬이며 다른 서비스들이 동작하지 않았다.
dockerize 사용
depends_on은 서비스의 의존성을 명시하더라도 서비스의 준비 상태를 보장하지는 않는다. 그렇기에 도커 컴포즈의 healthcheck를 사용하려고 하였지만, 나의 경우에는 컨테이너 이미지 자체가 최소한의 실행 환경만 포함하고 있어서 curl, wget, nc 명령어를 모두 사용할 수 없었다. 이를 해결하기 위해 dockerize 도구를 사용하였다.
dockerize란?
Docker 컨테이너의 서비스가 준비되었는지 확인하는 도구이다. 이를 이용해 config-server가 준비되었는지 검사할 수 있다.
Dockerfile
# Stage 1: Build
FROM openjdk:21-jdk-slim as builder
# dockerize 설치
RUN apt-get update --allow-releaseinfo-change && apt-get install -y wget \
&& wget https://github.com/jwilder/dockerize/releases/download/v0.6.1/dockerize-linux-amd64-v0.6.1.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-v0.6.1.tar.gz \
&& rm dockerize-linux-amd64-v0.6.1.tar.gz
# 작업 디렉토리 설정
WORKDIR /app
# Gradle Wrapper 및 소스 복사
COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY settings.gradle .
COPY src src
# Gradle 빌드 수행 (테스트 제외)
RUN ./gradlew clean build -x test
# Stage 2: Runtime
FROM openjdk:21-slim
# 작업 디렉토리 설정
WORKDIR /app
# 암호화 키 전달
COPY config-key.pub config-key.pub
# 빌드 스테이지에서 생성된 JAR 파일 복사
COPY --from=builder /app/build/libs/config-service.jar .
# 애플리케이션 실행
ENTRYPOINT ["java", "-jar", "config-service.jar"]
docker-compose.yml
version: '3.8'
services:
eureka-server:
image: tirtir0827/service-discovery
container_name: eureka-container
networks:
- docker-network
ports:
- 8761:8761
environment:
- EUREKA_SERVER_NAME=eureka-server
- PORT=8761
config-server:
image: tirtir0827/config-server
container_name: config-container
networks:
- docker-network
ports:
- 8888:8888
api-gateway:
image: tirtir0827/api-gateway
container_name: gateway-container
networks:
- docker-network
ports:
- 8000:8000
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=8000
depends_on:
- eureka-server
- config-server
command: ["dockerize", "-wait", "tcp://config-server:8888", "-timeout", "120s", "java", "-jar", "hospital-service.jar"]
hospital-service:
image: tirtir0827/hospital-service
container_name: hospital-container
networks:
- docker-network
ports:
- 9001:9001
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9001
depends_on:
- eureka-server
- config-server
command: ["dockerize", "-wait", "tcp://config-server:8888", "-timeout", "120s", "java", "-jar", "hospital-service.jar"]
user-service:
image: tirtir0827/user-service
container_name: user-container
networks:
- docker-network
ports:
- 9002:9002
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9002
depends_on:
- eureka-server
- config-server
command: ["dockerize", "-wait", "tcp://config-server:8888", "-timeout", "120s", "java", "-jar", "hospital-service.jar"]
emergency-service:
image: tirtir0827/emergency-service
container_name: emergency-container
networks:
- docker-network
ports:
- 9003:9003
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9003
depends_on:
- eureka-server
- config-server
command: ["dockerize", "-wait", "tcp://config-server:8888", "-timeout", "120s", "java", "-jar", "hospital-service.jar"]
reservation-service:
image: tirtir0827/reservation-service
container_name: reservation-container
networks:
- docker-network
ports:
- 9004:9004
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9004
depends_on:
- eureka-server
- config-server
command: ["dockerize", "-wait", "tcp://config-server:8888", "-timeout", "120s", "java", "-jar", "hospital-service.jar"]
mypage-service:
image: tirtir0827/mypage-service
container_name: mypage-container
networks:
- docker-network
ports:
- 9005:9005
environment:
- EUREKA_SERVER_NAME=eureka-server
- EUREKA_SERVER_PORT=8761
- PORT=9005
depends_on:
- eureka-server
- config-server
command: ["dockerize", "-wait", "tcp://config-server:8888", "-timeout", "120s", "java", "-jar", "hospital-service.jar"]
networks:
docker-network:
external: true
'Cloud' 카테고리의 다른 글
[MSA] Dcoker-Compose (1) (4) | 2024.12.15 |
---|---|
[AWS] ECR + Lambda + API Gateway(feat. Cold Start) (1) | 2024.12.11 |
[AWS] S3 + CloudFront + Route53 (feat. AccessDenied) (1) | 2024.12.10 |
Typescript + Firebase 환경 설정 (0) | 2024.08.11 |
네이버 클라우드 Micro Server (0) | 2024.07.10 |