현재 캡스톤디자인I 최종 발표까지 얼마 남지 않아 현재까지 만든 프로젝트를 마무리하고 이제 배포를 해야될 때가 됐다..!
배포환경 같은 경우는 AbleCloud의 클라우드에 배포할 예정이며 Docker Container 가상화를 통해 배포를 할 예정이다.
현재 배포해야할 서비스는 discovery, config, apigateway, board, chatting, club, schedule, user로 8개 이고 추가로 MariaDB, RabbitMQ, Redis가 있다.
오늘은 이들을 Docker를 통해 배포해보는 시간을 가져보겠다.
docker network create --gateway 172.18.0.1 --subnet 172.18.0.0/16 clubplatform-network
docker network inspect clubplatform-network
💡 docker logs를 통해 해당 컨테이너의 로그를 확인할 수 있다.
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
docker run -d --name redis -p 6379:6379 redis
gradle에서 version을 바꿔준다.
bootjar 실행
jar 파일 생성 완료
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"]
docker build -t sanizzang/config-service:1.0 .
아래의 커맨드로 이미지 생성을 확인할 수 있다.
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 이름으로도 설정이 가능하다.
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 .
discovery-service
docker push sanizzang/discovery-service:1.0
config-service
docker push sanizzang/config-service:1.0
위의 방법들과 동일하므로 생략
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/data에 들어가보면 DB 데이터와 관련된 파일들이 들어있는 것을 볼 수 있다.
이 폴더를 아래와 같이 maridDB의 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
docker exec -it mariadb /bin/bash
grant all privileges on *.* to 'root'@'%' identified by 'password';
: 어떤 IP를 사용해도 접근 가능하게
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 이미지를 실행을 할때 꼭 해줘야할 것이 있다.
-e "eureka.instance.hostname=10.1.1.46"
docker로 마이크로서비스를 배포하는 경우 eureka에 ip가 아닌 dockerid로 등록이 된다.
그래서 저 옵션을 지정해줬을 때 API-GATEWAY가 user-service를 찾지 못하는 현상이 일어났다.
위 옵션을 추가함으로써 User-service가 있는 IP를 찾아갈 수 있도록 해줬다.
-p 8765:8765 -e "server.port=8765"
현재 user-service는 아래와 같이 서비스 기동시 랜덤으로 포트가 설정된다. (server.port = 0으로 설정했기 때문)
하지만 docker에 포트포워딩을 해주지 않으면 또 user-service를 찾지 못하는 현상이 발생하는 것이다.. 그래서 어쩔 수 없이 포트를 임의를 지정해주고 해당 포트를 포트포워딩까지 해주니 서비스가 정상 작동하였다.
-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를 마무리해보자.
잘보고갑니다^^