[캡스톤디자인] Docker로 배포하기

Dev_Sanizzang·2023년 6월 9일
0

캡스톤디자인

목록 보기
10/15

📕 개요

현재 캡스톤디자인I 최종 발표까지 얼마 남지 않아 현재까지 만든 프로젝트를 마무리하고 이제 배포를 해야될 때가 됐다..!
배포환경 같은 경우는 AbleCloud의 클라우드에 배포할 예정이며 Docker Container 가상화를 통해 배포를 할 예정이다.
현재 배포해야할 서비스는 discovery, config, apigateway, board, chatting, club, schedule, user로 8개 이고 추가로 MariaDB, RabbitMQ, Redis가 있다.
오늘은 이들을 Docker를 통해 배포해보는 시간을 가져보겠다.

Docker 이미지 저장소 변경법

Bridge Network 생성

docker network create --gateway 172.18.0.1 --subnet 172.18.0.0/16 clubplatform-network

network 정보 확인 커맨드

docker network inspect clubplatform-network

💡 docker logs를 통해 해당 컨테이너의 로그를 확인할 수 있다.

RabbitMQ

RabbitMQ 도커 생성 및 실행

docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -p 15671:15671 -p 5671:5671 -p 4369:4369 -e RABBITMQ_DEFAULT_USER=guest -e REBBITMQ_DEFAULT_PASS=guest rabbitmq:management

Redis

Redis 도커 생성 및 실행

docker run -d --name redis -p 6379:6379 redis

config-service

jar 파일 빌드

  1. gradle에서 version을 바꿔준다.

  2. bootjar 실행

  3. jar 파일 생성 완료

Dockerfile 생성 및 이미지 빌드

  1. config-service 폴더에 Dockerfile 생성
FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY apiEncryptionKey.jks apiEncryptionKey.jks
COPY build/libs/config-service-1.0.jar ConfigServer.jar
ENTRYPOINT ["java","-jar","ConfigServer.jar"]
  1. 이미지 빌드
docker build -t sanizzang/config-service:1.0 .
  1. 이미지 생성 확인

아래의 커맨드로 이미지 생성을 확인할 수 있다.

docker iamges

이미지 실행

docker run -d -p 8887:8887 --network cloud-network -e "spring.rabbitmq.host=10.1.1.34" -e "spring.profiles.active-default" --name config-service sanizzang/config-service:1.0

여기서 spring.rabbitmq.host를 172.17.0.2로 한 이유는 현재 docker container로 실행되고 있는 rabbitmq 이미지가 172.17.0.2 ip address에 올라와 있기 때문에 해당 IP로 설정한 것이고 IP가 바뀐다면 변경을 해줘야한다.

💡 또한 같은 docker network를 사용시 rabbitmq와 같이 docker container 이름으로도 설정이 가능하다.

Eureka Discovery Service

Dockerfile 생성 및 이미지 빌드

FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY build/libs/discovery-service-1.0.jar DiscoveryService.jar
ENTRYPOINT ["java","-jar","DiscoveryService.jar"]
docker build --tag sanizzang/discovery-serivce:1.0 .

Docker Hub에 push

discovery-service

docker push sanizzang/discovery-service:1.0

config-service

docker push sanizzang/config-service:1.0

Apigateway Service

Dockerfile 생성 및 이미지 빌드

위의 방법들과 동일하므로 생략

이미지 실행

apigateway-service 같은경우 설정해줘야할 ip값이 4개나 되서 실행 코드가 좀 길다.

docker run -d -p 8000:8000 --network cloud-network -e "spring.cloud.config.uri=http://config-service:8887" -e "spring.rabbitmq.host=10.1.1.34" -e "spring.redis.host=10.1.1.34" -e "eureka.client.service-url.defaultZone=http://discovery-service:8761/eureka/" --name apigateway-service sanizzang/apigateway-service:1.0

MariaDB

mariaDB DB 데이터 복사

현재 MariaDB/data에 들어가보면 DB 데이터와 관련된 파일들이 들어있는 것을 볼 수 있다.
이 폴더를 아래와 같이 maridDB의 Dockerfile을 만들 위치에 복사해놓는다.

Dockerfile 생성 및 이미지 빌드

Dockerfile

FROM mariadb 
ENV MYSQL_ROOT_PASSWORD mariadb1234
ENV MYSQL_DATABASE mydb
COPY ./data /var/lib/mysql
EXPOSE 3307
ENTRYPOINT ["mysqld"]

mariaDB를 컨테이너로 가동시키면 기본적으로 /var/lib/mysql 폴더가 데이터가 저장되는 폴더이다.

docker build -t sanizzang/my_mariadb:1.0 .

이미지 실행

docker run -d -p 3307:3307 --name mariadb sanizzang/my-mariadb:1.0

mariaDB 접근

docker exec -it mariadb /bin/bash
grant all privileges on *.* to 'root'@'%' identified by 'password';

: 어떤 IP를 사용해도 접근 가능하게

User-Service

Dockerfile 생성 및 이미지 빌드

FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
RUN mkdir /image
COPY build/libs/user-service-1.0.jar UserService.jar
ENTRYPOINT ["java","-jar","UserService.jar"]

이미지 실행

docker run -p 8765:8765 -d --name user-service -e "server.port=8765" -e "spring.cloud.config.uri=http://10.1.1.132:8887" -e "spring.rabbitmq.host=10.1.1.34" -e "spring.redis.host=10.1.1.34" -e "eureka.client.service-url.defaultZone=http://10.1.1.132:8761/eureka/" -e "eureka.instance.hostname=10.1.1.46" -v /image:/image sanizzang/user-service:1.0

유의할 점

현재 내가 구상한 아키텍쳐는 아래와 같다.

위의 아키텍쳐를 보면 discovery, api-gateway와 각 마이크로서비스들은 클라우드가 분리되어 있다. 그렇기 때문에 docker network를 공유하지 못한다.(방법이 있는 것 같긴한데 모름)
그래서 user-service 이미지를 실행을 할때 꼭 해줘야할 것이 있다.

  1. -e "eureka.instance.hostname=10.1.1.46"
    docker로 마이크로서비스를 배포하는 경우 eureka에 ip가 아닌 dockerid로 등록이 된다.
    그래서 저 옵션을 지정해줬을 때 API-GATEWAY가 user-service를 찾지 못하는 현상이 일어났다.
    위 옵션을 추가함으로써 User-service가 있는 IP를 찾아갈 수 있도록 해줬다.

  2. -p 8765:8765 -e "server.port=8765"
    현재 user-service는 아래와 같이 서비스 기동시 랜덤으로 포트가 설정된다. (server.port = 0으로 설정했기 때문)
    하지만 docker에 포트포워딩을 해주지 않으면 또 user-service를 찾지 못하는 현상이 발생하는 것이다.. 그래서 어쩔 수 없이 포트를 임의를 지정해주고 해당 포트를 포트포워딩까지 해주니 서비스가 정상 작동하였다.

  3. -v /image:/image
    현재 user-service/signup API를 사용할 때 프로필 이미지를 저장하기 위해서 multipart/form-data를 사용하고 있다. 고로 이미지를 저장하는 폴더가 필요한데 현재 이미지를 저장하기 위해서 클라우드의 /image 디렉토리에 nfs-server를 연결시켜 놨다. docker로 배포할 시 호스트PC의 폴더에 접근을 못하기 때문에 -v 옵션을 통해 마운트를 시켜줘야 호스트PC의 /image 폴더에 접근할 수 있다.

이것 때문에 하루를 삽질했다.. 이유가 뭔지도 모르겠고 분명 폴더가 있는데 폴더가 존재하지 않는다고 떠서 코드가 문제인가 싶어 코드도 계속 바꿔주고 경로가 문제인가 싶어서 경로도 바꿔주고 권한때문에 안되는건가 싶어서 권한도 바꿔줬는데 안되길래 곰곰히 생각해보니까 docker로 배포를 하고 있었다는걸 인지하고 이에 관련된 내용을 찾아보니 -v 옵션이라는게 있었다..

이와 같이 swagger도 정상 작동한다.

나머지 서비스들을 배포하는 것은 지금까지 한 것들과 차이가 별로 없기 때문에 생략한다.

🚪 마무리

이로써 Docker를 통해 프로젝트를 배포해 볼 수 있었다. 아직 Docker에 대한 지식이 겉핥기 수준이라 Docker를 완전히 이용하지 못하고 많이 헤맸다....
MSA를 제대로 구축하기 위해서는 Docker에 대한 공부도 더 필요할 것같다.
이제 프론트엔드와 연결해봄으로써 캡스톤디자인I를 마무리해보자.

profile
기록을 통해 성장합니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 24일

잘보고갑니다^^

답글 달기