이전 포스트에선 프로젝트에 netflix eureka와 reactive gateway를 적용했다.

적용하기 전엔 각각의 마이크로 서비스가 담당하는 기능을 테스트하기 위해선 Postman에 서비스 별 포트번호를 직접 적어줘야했다.
적용 후, 8080번에서 대기중인 api gateway을 통해 더이상 어떤 서비스가 어디에 열려있는지 알지 못해도 요청할 수 있게 되었다..!
기능 개발을 진행하면서 로컬 환경에서 어플리케이션을 실행하고, Postman을 통해 구현한 기능이 의도한대로 동작하는지 확인하는 과정이 있었다.
api gateway를 적용하기 전엔 테스트하기 참 단순했다.
테스트할 마이크로서비스 실행하고.. 열린 포트로 요청을 날리자!
api gateway를 적용한 후, 하나의 마이크로서비스를 실행하기 위해선 다음과 같은 과정이 추가되었다.
유레카 서버 실행하고.. api gateway 실행하고.. 테스트할 마이크로서비스 실행하고... api gateway로 요청을 날리자!
물론 프로필을 구분하여 로컬에선 단일로 실행되도록 할 수 있지만, 결국 클라우드에 올려 사용할 것이므로 이참에 Docker를 적용해보기로 했다.
먼저, 도커 이미지를 생성하기 위해 Dockerfile을 작성했다.
# 빌드 환경 구성
FROM amazoncorretto:21
WORKDIR /workspace/app
# JAR 파일 복사
COPY ./build/libs/user-service-0.0.1-SNAPSHOT.jar /workspace/app/user-service.jar
ENTRYPOINT ["java", "-jar", "user-service.jar"]
Dockerfile은 간단하게 작성했다. 다른 분들이 작성한 예시를 보니 Dockerfile 내부에서 직접 빌드하는 경우도 있었지만, 빌드된 jar 파일을 복사하는것으로 간단하게 작성했다.
위와 같은 Dockerfile을 유레카 서버, api gateway, 마이크로서비스들 모두 작성해주었다.
도커의 컨테이너는 내부적으로 각각의 IP와 Port를 배정받는다.
문제는 api gateway와 마이크로서비스들이 유레카 서버를 알고 있어야 한다는 것인데, 현재 하나의 NCP 서버 인스턴스를 사용중이며, 각 서비스마다 별도의 인스턴스를 할당할 것이 아니므로 docker compose를 이용해 관리하기로 했다.
docker-compose.ymlversion: '3'
services:
eureka-discovery:
build:
context: ./eureka-discovery
dockerfile: Dockerfile
container_name: eureka-discovery
ports:
- "8761:8761"
networks:
- eureka-network
api-gateway:
build:
context: ./api-gateway
dockerfile: Dockerfile
container_name: api-gateway
ports:
- "8080:8080"
environment:
- EUREKA_SERVER_URI=http://eureka-discovery:8761/eureka/
depends_on:
- eureka-discovery
networks:
- eureka-network
user-service:
build:
context: ./user-service
dockerfile: Dockerfile
container_name: user-service
ports:
- "8081:8081"
environment:
- EUREKA_SERVER_URI=http://eureka-discovery:8761/eureka/
depends_on:
- eureka-discovery
networks:
- eureka-network
group-service:
build:
context: ./group-service
dockerfile: Dockerfile
container_name: group-service
ports:
- "8082:8082"
environment:
- EUREKA_SERVER_URI=http://eureka-discovery:8761/eureka/
depends_on:
- eureka-discovery
networks:
- eureka-network
networks:
eureka-network:
driver: bridge
이제 브릿지 네트워크를 통해 모든 서비스가 유레카 서버에 접근할 수 있게 되었다..!
docker-compose를 통해 서비스들을 실행시켰다.
명령어 한번으로 모든 서비스가 실행되고, 관리할 수 있다니...!

하지만 문제가 발생했다. 유레카 서버에 아무 서비스도 등록되지 않았다.
로그를 확인해보니 유레카 서버를 찾을 수 없다고 나와있었다.
stack overflow - there is not are not services registered in eureka server 와 완전히 동일한 문제가 발생했다.
다만 위에선 eureka의 defaultZone 설정을 localhost로 해놨지만, 필자의 경우 도커 네트워크의 유레카 서비스의 이름으로 정상적으로 등록되어 있었다. 그럼에도 불구하고 유레카 서버를 향한 요청이 localhost로 나갔다.
결론부터 말하자면 Dockerfile 생성의 문제였다. 기존의 Dockerfile을 다시 보자.
# 빌드 환경 구성
FROM amazoncorretto:21
WORKDIR /workspace/app
# JAR 파일 복사
COPY ./build/libs/user-service-0.0.1-SNAPSHOT.jar /workspace/app/user-service.jar
ENTRYPOINT ["java", "-jar", "user-service.jar"]
jar 파일을 실행하면서 설정 파일을 로드하는데, 컨테이너 내부에 application.yml 파일이 존재하지 않아 설정이 적용되지 않았던 것이었다.
이후 Dockerfile을 수정하고 실행했더니 잘 등록되었다..!
# 빌드 환경 구성
FROM amazoncorretto:21
WORKDIR /workspace/app
# JAR 파일 복사
COPY ./build/libs/api-gateway-0.0.1-SNAPSHOT.jar /workspace/app/api-gateway.jar
COPY ./src/main/resources/application.yml /workspace/app
COPY ./src/main/resources/application-route.yml /workspace/app
ENTRYPOINT ["java", "-jar", "api-gateway.jar", "--spring.config.location=file:/workspace/app/application.yml"]
Docker와 docker-compose를 적용해 컨테이너 기반의 배포 환경을 준비했다.
이를 기반으로 CI/CD 또한 적용해봐야지..!
stack overflow - there is not are not services registered in eureka server
생활코딩 - 도커 입구수업
생활코딩 - 도커
Contributor9 - Docker 환경설정