MSA Dockerizing 1

letthem·2025년 3월 17일

LG CNS AM CAMP 1기

목록 보기
33/42
post-thumbnail


초록: 로컬 환경 / 파랑: 가상 환경


위는 이때까지 인텔리제이로 했던 Microservices다. 이를 배포해보자 !

cf)

docker container ls -> docker ps
docker image ls
docker volume ls
docker network ls

🎀 Docker Network

하나의 네트워크에 우리가 인텔리제이에서 했던 MicroServices를 넣어보자

1️⃣ Bridge 네트워크

host 네트워크에 다리를 놓아서(포트로 연결해서 : 포트 맵핑, 포트 바인딩) 외부로 통신할 수 있게 해준다. 주로 이걸 사용. default 네트워크.

  • 포트 : 0~65535 X 컨테이너 : 0~65535

2️⃣ Host 네트워크

Host - 도커 데스크탑 - Container 이렇게 있다면, 공유해서 같이 쓴다. 포트의 연결 없이 바로 사용. but, host PC가 사용하는 자원을 같이 쓴다. => 충돌 가능성 O

  • 포트 : 0~65535

3️⃣ None 네트워크

사용하지 않는다.

👽 명령어

docker network create --driver bridge [브릿지 이름]

  • 새로운 브릿지 네트워크(Bridge Network)를 생성하는 명령어
  • --driver bridge 옵션은 브리지 네트워크를 사용하겠다는 의미다.
  • 이 네트워크를 사용하면 여러 컨테이너가 같은 네트워크 안에서 서로 통신할 수 있다.

docker network create ecommerce-network

  • ecommerce-network라는 이름의 브리지 네트워크를 생성하는 명령어다.
  • 예를 들어, 전자상거래 서비스의 backend, database, frontend 같은 여러 컨테이너가 서로 통신할 수 있도록 이 네트워크를 만들 수 있다.

docker network ls

  • 현재 도커에 존재하는 네트워크 목록을 출력하는 명령어다.
  • ecommerce-network가 잘 생성되었는지 확인할 때 사용할 수 있다.
  • 실행하면 NETWORK ID, NAME, DRIVER, SCOPE 등의 정보가 출력된다.

docker network inspect [네트워크 이름]

  • 해당 네트워크 상세정보 출력
  • Subnet, Gateway

예제

RabbitMQ를 ecommerce-network에 연결해보기

docker run -d --name rabbitmq --network ecommerce-network -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=guest -e RABBITMQ_DEFAULT_PASS=guest rabbitmq:4.0-management

  • -p: 포트 포워딩
  • -e: 환경 설정 (username, password 지정)


카프카 실행시키고 정보 열어보기 실행시키고 정보 열어보기

docker run -d -p 9092:9092 --name broker apache/kafka:latest: 카프카 run

docker container inspect broker : 카프카 정보 확인
기본적으로 생성되는 bridge network이다. (!= ecommerce-network)

RabbitMQ와 kafka 네트워크가 다르다 ! => 현재는 통신 불가
=> Ecommerce-network를 만들어서 kafka와 RabbitMQ를 동시에 품어서 통신 가능하도록 만들어보자

  • 카프카 지우고 다시만드는데, 네트워크 ecommerce-network 쓰겠다고 지정하여 생성해보자

docker volume: 데이터 저장 공간을 연결하기 위한 용도

컨테이너 삭제되면 volume은 안 지워짐. -> 새로 만들면 volume mount 걸어줘서 다시 연결해주면 되지만 위험함

즉, 삭제하지 말고 그냥 ecommerce-network와 connect만 하면 됨! 🔽

docker network connect ecommerce-network broker

  • ecommerce-network에다가 broker(kafka)를 추가하겠다

docker network inspect ecommerce-network

  • rabbitmq와 broker가 ecommerce-network에 들어와 있다.

docker container inspect broker

  • kafka에는 기본 network인 bridge와 ecommerce-network 둘 다 붙어 있는 것을 확인할 수 있다.

실습

지난 주엔 localhost로 가능했다. 왜냐하면 Host PC를 거쳐서 MariaDB로 접속했기 때문!

  • connector 등으로.. datagrip 써서.. 돌아돌아가기..

이번엔 다이렉트로 가는 방법을 해보고 싶다! 로컬을 통해 요청을 하는 것이 아니라 도커로 배포 환경에서 직접.

1. MySQL(클라이언트)에서 MariaDB(서버)로 연결

🪄 my-network 생성
docker network create --driver bridge my-network

  • "Gateway": "172.19.0.1"

🪄 MySQL (my-network와 연결)
docker run -d --name mysql-server --network my-network -p 13306:3306 -e MYSQL_ROOT_PASSWORD=test1357 mysql:8.0.41

🪄 MariaDB (my-network와 연결)
docker run -d --name mariadb-server --network my-network -p 23306:3306 -e MARIADB_ROOT_PASSWORD=test1357 mariadb:latest

이제, 1) Direct connect, 2) Host connect 둘 다 해보자

🪄 터미널 2개 (mysql, mariadb)

  • mysql 컨테이너 내부 진입
    docker exec -it mysql-server bash
    bash-5.1# mysql -hlocalhost -uroot -p

    • 여기서 host가 localhost: 자기 자신한테 접속

    • mysql에서 db 확인
      mysql> show databases;

    • exit

  • mariadb 컨테이너 내부 진입
    docker exec -ti mariadb-server bash
    root@5edadc046217:/# mariadb -hlocalhost -uroot -p

  • mariadb에서 db 확인
    MariaDB [(none)]> show databases;

  • 💫 mysql에서 자기자신 말고 host를 mariadb로 해서 다시 접속
    bash-5.1# mysql -hmariadb-server -uroot -p

  • mysql에서 mydb_from_mysql 하나 만들기
    mysql> create database mydb_from_mysql;

  • mariadb에서 database 확인하기
    MariaDB [(none)]> show databases;

    mydb_from_mysql이 생성된 것을 확인할 수 있다!

네트워크가 같이 묶여있기 때문에 IP주소나 컨테이너 ID 뿐만 아니라 변경되지 않는 컨테이너 이름으로도 접속할 수 있다.

컨테이너 간 통신 🔽

  • IP 주소
  • 컨테이너 ID
  • 컨테이너 NAME

지우는 방법

mysql-server를 my-network로부터 분리
docker network disconnect my-network mysql-server

mariadb에서 mydb_from_mysql 지우기
drop database mydb_from_mysql

mariadb-server, mysql-server 컨테이너 stop 하기
docker stop mariadb-server
docker stop mysql-server

stop된 컨테이너, 네트워크 전부 다 지우기
docker system prune

PS C:\Users\user> docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache

Are you sure you want to continue? [y/N] y
Deleted Containers:
5edadc0462172999bb5e0ac88621fb7f06c28e475a47219f55af7c9a0ba1949b
75481eb786bfc1a9a2a7e55ae6319d00aa12fdee6e53b0e423c9247e456252ee

Deleted Networks:
my-network
ecommerce-network

Total reclaimed space: 65.54kB

컨테이너의 name으로 접속할 수 있게 !

👻 config service 도커로 만들기

Dockerfile

FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY Windows_apiEncryptionKey.jks apiEncryptionKey.jks
COPY target/config-service-1.0.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
  • base Image: JDK(JRE 필요)
  • 현재 디렉토리의 Windows_apiEncryptionKey.jks 파일을 컨테이너 내부 apiEncryptionKey.jks 이름의 파일로 복사
  • target/config-service-1.0.jar(스프링 빌드 파일)도 컨테이너 내부로 복사
  • java -jar app.jar 명령어 실행 → 스프링 실행

도커 파일로 이미지 빌드 (Spring Build + Docker Build)

config-server로 cd
🔽
스프링 빌드 파일 만들기
mvn clean compile package -DskipTests=true
🔽
도커 파일로 이미지 빌드
docker build --tag config-service:1.0 -f Dockerfile .

config-service 실행

포트번호: 8888
네트워크: ecommerce-network
docker network create --driver bridge ecommerce-network : ecommerce-network 다시 만들고
docker run -d -p 8888:8888 --network ecommerce-network --name config-service config-service:1.0
config-service를 ecommerce-network에 연결해서 run

전체적인 docker 명령어 🔽

docker ps -a
Up -> 잘 기동되는 것 확인

config-service 컨테이너 진입 후
docker exec -it config-service bash

ls -al로 파일 확인 🔽

POSTMAN에서 확인
http://localhost:8888/encrypt 에 body 아무거나 넣고 POST

에러가 난다.

config-server는 컨테이너 안에서 돌아가니까 컨테이너 내부에서 apiEncryptionKey.jks를 읽을 수 있다.
즉, 기존의 컴퓨터 로컬 파일 경로 대신 location: /apiEncryptionKey.jks로 변경해줘야 encrypt 오류가 안 난다.

config-service>bootstrap.yml

encrypt:
#      key: abcdefghijklmnopqrstuvwxyz0123456789
    key-store:
#        location: file:///C://Work//git-local-repo//Windows_apiEncryptionKey.jks
#        location: file:/Windows_apiEncryptionKey.jks
        location: /apiEncryptionKey.jks
        password: test1234
        alias: apiEncryptionKey

cf) docker logs -f config-service 하면 실시간 로그 볼 수 있음

근데 이렇게 해도 오류남!! 왜냐하면

스프링 빌드하면 jar 파일이 생기는데, jar 파일 내부 디렉토리가 있음. 그 안에 Windows_apiEncryptionDey.jks가 있음
도커파일에서 Windows_apiEncryptionDey.jks를 apiEncryptionKey.jks로 복사했음

config-service 컨테이너 자체의 apiEncryptionKey.jks인데

/apiEncryptionKey.jks 이건 jar 파일 내부에 있는 Windows_apiEncryptionKey.jks 를 가리키는 것이다.

  • /apiEncryptionKey.jks: jar 파일 내부 디렉토리에 apiEncryptionKey.jks 파일이 있다는 의미
    • jar 파일 내부 디렉토리

    • 도커파일에 명시한 복사된 apiEncryptionKey.jks 파일은 컨테이너 루트 디렉토리에 생성됨
    • 컨테이너 내부 app.jar 파일 내부 디렉토리에는 Windows_apiEncryptionKey.jks 이름으로 존재

🪄 해결 방법

  1. location: /Windows_apiEncryptionKey.jks 이렇게 바꾸면 app.jar 내부 Windows_apiEncryptionKey.jks를 호출한다.

  2. location: file:///apiEncryptionkey.jks 이렇게 바꾸면 현재 컨테이너 디렉토리 안에 있는 apiEncryptionKey.jks를 호출한다.

  3. docker run -d -p 8888:8888 -e encrypt.key-store.location=file:///apiEncryptionKey.jks --network ecommerce-network --name config-service config-service:1.0
    bootstrap.yml 파일을 수정하지 않고(location: /apiEncryptionKey.jks 그대로) -e 옵션으로 docker run 시점에 yml 설정 내용 직접 수정

💡 방법 2로 하고, Spring Build + Docker Build + config-service RUN

 
방법 2. location: file:///apiEncryptionkey.jks 이렇게 바꾸면 현재 컨테이너 디렉토리 안에 있는 apiEncryptionKey.jks를 호출한다.

  • mvn clean compile package -DskipTests=true
  • docker build --tag config-service:1.0 -f Dockerfile .
  • docker run -d -p 8888:8888 --network ecommerce-network --name config-service config-service:1.0

POSTMAN 확인


Eureka 서버(service-discovery) 도커로 만들기

service-discovery>Dockerfile

FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY target/service-discovery-1.0.jar service-discovery.jar
ENTRYPOINT ["java", "-jar", "service-discovery.jar"]

👻 Eureka (service-discovery) 도커로 만들기

service-discovery로 가서 스프링 빌드 & 도커 빌드
mvn clean compile package -DskipTests=true
docker build --tag service-discovery:1.0 -f Dockerfile .

현재 이미지들 보기
docker images

이름 달기
docker tag service-discovery:1.0 letthem/service-discovery:1.0

도커 허브에 푸시하기
docker push letthem/service-discovery:1.0

service-discovery RUN
docker run -d -p 8761:8761 --name service-discovery service-discovery:1.0

docker ps -a
-> Up 확인

ecommerce-network에 service-discovery 연결하기
docker network connect ecommerce-network service-discovery

docker network inspect ecommerce-network


👻 API gateway 도커로 만들기

apigateway-service>application.yml

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://service-discovery:8761/eureka

apigateway-service>bootstrap.yml

spring:
  cloud:
    config:
      uri: http://config-service:8888
      name: user-service
#  profiles:
#    active: dev

Dockerfile 만들어서 아래와 같이 작성

FROM openjdk:17-ea-11-jdk-slim
VOLUME /tmp
COPY target/apigateway-service-1.0.jar apigateway-service.jar
ENTRYPOINT ["java", "-jar", "apigateway-service.jar"]

apigateway-service로 cd한 후
스프링 빌드 & 도커 빌드
mvn clean compile package -DskipTests=true
docker build --tag apigateway-service:1.0 -f Dockerfile .

cf) 캐시 없이 빌드하고싶으면 --no-cache 붙이면 됨
-> 이게 좋다! 캐시 돼서 반영 안 될 수도 있으므로
docker build --no-cache --tag apigateway-service:1.0 -f Dockerfile .

apigateway-service RUN
docker run -d -p 8000:8000 --network ecommerce-network --name apigateway-service apigateway-service:1.0

0개의 댓글