자바/MSA

Docker를 이용한 Microservice 이미지 만들기

UroJem 2024. 1. 7. 19:36

Dockerfile을 이용하여 개발한 마이크로서비스를 docker image로 만들어서 컨테이너로 실행하는 과정을 알아본다.

 

 

마이크로서비스가 실행될 컨테이너와 연동할 mariadb 컨테이너 실행

Docker Desktop이 실행중인 것을 확인하고 커맨드 창을 연다.

 

 

각 컨테이너간 통신을 하기위해 docker network 생성

컨테이너 실행시 'msa-network'를 통해 실행하면 컨테이너간 통신이 쉬워진다.

보통 통신시 ip와 port를 이용하여 통신을 하는데 컨테이너명을 통해서 실행할 수 있다.

 

 

docker run --network msa-network -d -p 3307:3306 --restart=always -e MYSQL_ROOT_PASSWORD=!qwer1234 --name mariadb mariadb

mariadb 이미지를 내려받고 컨테이너를 실행한다.

mariadb 이미지가 없기 때문에 가장 최신버전의 mariadb이미지를 자동으로 내려받은 후 컨테이너로 실행하게 된다.

  • --network: 어떤 네트워크를 사용할 것인지 설정. msa-network를 통해 실행되도록 설정
  • -d: 백그라운드로 실행
  • -p: 3307 외부접속 포트, 3306 컨테이너 내부 실행 포트. 로컬에 설치된 mariadb와 충돌 방지를 위해 외부 접속포트를 3307로 설정
  • --restart: docker 실행시 설정하는 옵션으로 always 옵션은 자동으로 컨테이너가 실행되도록 설정
  • -e: 환경변수 세팅 설정으로 MYSQL_ROOT_PASSWORD 옵션을 통해 mariddb root 계정의 비밀번호를 '!qwer1234'로 적용
  • --name: 컨테이너 명을 'mariadb'로 설정
  • 맨 마지막 'mariadb'는 이미지명 설정

 

 

exec 명령어로 컨테이너 접근 후 mariadb에 접속

mysql 명령어가 들지않아 mariadb 명령어로 변경하여 접속하였다. 생성된 컨테이너명으로 되는건지 최신 mariadb 컨테이너 접속명이 변경된 것인지 모르겠지만 일단 접속 성공

 

 

데이터베이스 생성

컨테이너에 생성된 mariadb 에도 msa 데이터베이스를 생성하고 mariadb 접속을 끊고 컨테이너를 빠져나온다.

 

 

 

프로젝트별 이미지 생성

config-server

config-server 루트에 Dockerfile 이름의 파일을 생성하고 이미지를 생성하기 위해 필요한 스크립트를 작성한다.

  • FROM: 만들어질 이미지의 기본 바탕으로 사용될 이미지 지정
    • openjdk:18-jdk-alpine AS builder: open jdk 18 버전이 설치된 컨테이너 서버가 구성되는 이미지를 생성한다.
  • COPY: Dockerfile 파일이 존재하는 프로젝트에 있는 파일에 대해서 이미지로 복사
    • gradlew .: 현재 경로에 있는 gradlew 파일을 이미지로 복사
    • gradle gradle: 현재 경로에 있는  gradle 폴더를 이미지로 복사
    • build.gradle .: 현재 경로에 있는  build.gradle 파일을 이미지로 복사
    • settings.gradle .: 현재 경로에 있는  settings.gradle 파일을 이미지로 복사
    • src src: 현재 경로에 있는  src 폴더를 이미지로 복사
    • --from=builder build/libs/*.jar /app/app.jar: jdk18 버전을 통해 생성된 jar 파일들을 /app 폴더안에 복사
  • RUN: 명령어를 실행하는 명령어
    • chmod +x ./gradlew: gradlew 명령어를 통해 build를 진행하기 위한 실제 권한 부여
    • dos2unix ./gradlew: 윈도우 환경에서 docker를 돌리기 위해 실행하는 명령어로 gradlew 명령어가 리눅스가 아닌 윈도우 명령어로 인식되면 다음 명령어인 gradlew bootJAR 명령어가 실행이 안될 수 있어 dos2unix 명령어를 통해 gradlew 명령어를 리눅스용 명령어로 인식하게 함
    • ./gradlew bootJAR: 실제 프로젝트가 이미지안에서 build 되면서 배포자료를 생성
  • WORKDIR: 컨테이너의 홈경로 지정. 컨테이너 접속시 기본 경로를 /app으로 지정
  • EXPOSE: 이미지에서 노출될 포트 지정
  • ENTRYPOINT: 컨테이너가 실행될 때 무조건 실행해야하는 명령어를 지정하는 스크립트

 

Dockerfile로 이미지 생성

프로젝트 최상위 경로로 이동한다음 docker build 명령어를 통해 Dockerfile이 위치해 있는 config-server 경로를 지정하고 -t 옵션을 통해 config-server-image라는 이름으로 이미지 생성

 

 

docker run --network msa-network -d -p 8080:8080 --name config-server config-server-image

config-server 컨테이너 실행

  • --network: mariadb와 동일하게 msa-network 네트워크 사용
  • -p: 외부, 컨테이너 내부 8080 포트포워딩 설정
  • --nage: config-server 이름의 컨테이너 실행
  • config-server-image: 위에서 생성한 config-server-image 이미지를 사용하여 컨테이너 실행

 

 

로그내용 확인

  • docker logs: 컨테이너 실행 로그 확인 명령어
  • -f: 로그 확인 명령어 옵션으로 실시간으로 로그를 계속 확인하는 옵션

 

 

eureka-server

eureka-server에도 Dockerfile을 만든다.

config-server 에 Dockerfile과 다른점은 src/main/resources에 있는 bootstrap.yml을 삭제하고 bootstrap-docker.yml을 bootstrap.yml로 변경하는 스크립트가 추가되었다.

bootstrap.yml 내용에 config-server 연결정보가 들어있는데 docker 컨테이너안에서 사용되는 config-server 연결정보는 IDE에서 사용할 때와 다르기 때문에 yml 파일을 분리한다.

 

 

src/main/resource 하위에 bootstrap-docker.yml 파일을 생성하고 프로필과 config-server 연결정보를 변경한다.

uri에 들어간 config-server는 컨테이너명을 의미하고 컨테이너명을 통해 msa-network를 사용해서 컨테이너간 통신을 할 수 있다.

eureka-server 에서 config-server로 연결할 때 config-server:8080으로 설정하게 되면 msa-network 네트워크에 속해있는 config-server 컨테이너 정보를 찾게 되고 해당 컨테이너 정보로 연결된다.

그래서 이미지를 생성하면서 build 할 때 bootstrap.yml 파일이 아닌 bootstrap-docker.yml을 통해 컨테이너가 실행되도록 Dockerfile에서 작성한 것.

프로필 설정도 local -> docker로 변경해서 config-server에 eureka-server-local.yml 이 아닌 eureka-server-docker.yml 파일이 필요하다.

 

 

config-server에 eureka-server-local.yml을 복사하여 eureka-server-docker.yml을 추가한다. 변경사항은 없다.

 

 

Dockerfile로 이미지 생성

config-server 이미지를 만들었을 때처럼 docker build 명령어로 eureka-server 이미지 생성

 

 

 

gateway-server

gateway-server에도 Dockerfile을 만든다. 내용은 eureka-server의 Dockerfile과 같다.

 

 

src/main/resource 하위에 bootstrap-docker.yml 파일을 생성하고 프로필과 config-server 연결정보를 변경한다.

 

 

config-server에 gateway-server-local.yml을 복사하여 gateway-server-docker.yml을 추가한다.

변경사항은 datasource-local.yml 파일 import가 파일 경로로 추가했었는데 컨테이너 내부에서 찾아야하기 때문에 다시 classpath로 변경하였으며 datasource-docker.yml 파일을 바라보도록 변경하였다.

eureka 연동부분에 컨테이너명인 eureka-server의 8761 포트로 연결되도록 변경하였다.

 

 

config-server에 datasource-local.yml을 복사하여 datasource-docker.yml을 추가한다.

변경사항은 jdbc url에 localhost -> mariadb 컨테이너 명으로 설정하였다.

mariadb 외부 포트를 3307로 포트포워딩 했지만 docker network를 통해 컨테이너간 통신할 때 사용되는 연결정보는 컨테이너명과 컨테이너 안에서 실행되는 포트를 통해 연결한다.

 

 

Dockerfile로 이미지 생성

docker build 명령어로 gateway-server 이미지 생성

 

 

 

authentication-server

authentication-server에도 Dockerfile을 만든다. 내용은 eureka-server의 Dockerfile과 같다.

 

 

src/main/resource 하위에 bootstrap-docker.yml 파일을 생성하고 프로필과 config-server 연결정보를 변경한다.

 

 

config-server에 authentication-server-local.yml을 복사하여 authentication-server-docker.yml을 추가한다.

gateway-server-docker.yml과 같이 datasource 설정과 eureka-server 컨테이너 연결정보를 수정한다.

 

 

Dockerfile로 이미지 생성

docker build 명령어로 authentication-server 이미지 생성

 

 

 

item-service

item-service에도 Dockerfile을 만든다. 내용은 eureka-server의 Dockerfile과 같다.

 

 

src/main/resource 하위에 bootstrap-docker.yml 파일을 생성하고 프로필과 config-server 연결정보를 변경한다.

 

 

config-server에 item-service-local.yml을 복사하여 item-service-docker.yml을 추가한다.

gateway-server-docker.yml과 같이 datasource 설정과 eureka-server 컨테이너 연결정보를 수정한다.

 

 

Dockerfile로 이미지 생성

docker build 명령어로 item-service 이미지 생성

 

 

 

컨너테이너 실행

config-server 설정파일이 변경되어 컨테이너 중지 후 삭제한다.

config-server 이미지도 삭제한다.

 

 

config-server 이미지 생성 후 컨테이너 실행. 로그파일로 정상 작동 확인.

 

 

eureka-server 컨테이너 실행.

 

 

log 찍어봤는데 뭔가 에러가 발생...

 

 

뭐가 문제지.. 하고 보다가 config-server에 application.yml 파일에 config-server 경로를 파일경로로 해놓은게 있어서 classpath 경로를 수정하고

eureka-server 컨테이너 중지 -> config-server 컨테이너 중지 -> eureka-server 컨테이너 삭제 -> config-server 컨테이너 삭제 -> config-server 이미지 삭제 -> config-server 이미지 생성 -> config-server 컨테이너 실행 -> eureka-server 컨테이너 실행

 

 

로그찍어봤는데 컨테이너 정상 실행.

 

 

gateway-server 컨테이너 실행. 로그파일로 정상 실행 확인

 

 

authentication-server 컨테이너 실행. 로그파일로 정상 실행 확인

 

 

 

item-service 컨테이너 실행. 포트는 랜덤포트로 별도의 옵션 없이 실행하여 45009 포트로 실행된 것을 로그로 확인.

 

 

 

postman 회원 등록 요청시 정상 응답코드 확인.

 

 

 

https://www.inflearn.com/course/java-msa-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8B%A4%EC%8A%B5/dashboard

 

Java 마이크로서비스(MSA) 프로젝트 실습 강의 - 인프런

Java SpringCloud와 여러 오픈소스를 연동하여 마이크로서비스를 구축하는 세미 프로젝트를 경험해보실 수 있습니다. 마이크로서비스 구축 경험을 해보고 싶으시다면 이 강의를 추천할게요!, 마이

www.inflearn.com