• 배포하기 위해 중요한 점은 예상치 못한 호환성 문제나 환경 의존성 문제를 방지하기 위해 일관된 환경으로 배포하는 것입니다.
  • Docker을 사용하면 각 구성 요소를 컨테이너로 패키징하여 일관된 배포 환경을 유지할 수 있습니다.
  • 이미지 생성 시 버전을 명시하면 호환성 문제를 방지할 수 있으며, 해당 이미지를 컨테이너로 배포하면 애플리케이션을 보다 간편하게 배포할 수 있습니다.

Docker

출처 : https://www.itworld.co.kr/insight/110748

가상 머신은 호스트 시스템에서 독립적인 환경을 갖는 게스트 운영 체제를 실행하여, 호환성 문제나 환경 의존성 문제가 발생할 수 있습니다. 또한, 여러 가상 머신이 호스트 시스템의 자원을 공유하면서 자원 충돌이 발생할 수도 있습니다. 그러나 Docker는 각 컨테이너가 필요한 모든 환경을 자체적으로 갖고 있고, 호스트 시스템과 격리되어 있어 이러한 문제를 방지합니다.

  • 컨테이너 기반 가상화 기술을 제공해주는 오픈소스 프로젝트
  • 여러 운영체제에서 어플리케이션을 실행할수 있도록 해주는 가상화 플랫폼
  • 가상화된 환경에서 실행되는 응용 프로그램을 실행하기 위해 필요한 모든 것이 포함된 경량화된 컨테이너 이미지를 만들 수 있습니다.
    • 컨테이너 이미지는 OS, 실행환경, 어플리케이션 등이 패키지화되어 있습니다.
    • 도커 컨테이너 이미지는 도커에서 실행되는 컨테이너를 생성하기 위한 불변의 템플릿
    • 각 이미지는 도커 이미지 레지스트리에 저장되며, 이미지를 실행하면 해당 이미지의 컨테이너가 만들어짐
    • 이미지는 소프트웨어 애플리케이션, 라이브러리, 의존성, 설정 등을 모두 포함하는 것이 일반적
    • 독립적으로 실행되거나 다른 이미지와 결합하여 실행
      • 예를 들어, 웹 애플리케이션을 위한 이미지와 데이터베이스를 위한 이미지를 결합하여 실행
    • 이미지는 계층적으로 구성됩니다. 각 계층은 이전 계층을 기반으로 새로운 계층을 추가하는 방식으로 작성
      • 이미지의 크기를 줄이고 공통적인 부분을 재사용
    • 도커는 이전의 가상화 기술과 비교하여 경량화되어 있어, 더 빠르게 실행되며, 실행 중인 어플리케이션과 호환성이 높음
    • 도커 컨테이너는 각각이 격리된 공간에서 실행되므로, 서로 다른 환경에서 실행되는 어플리케이션을 컨테이너로 분리하여 실행하면 충돌이나 문제가 발생할 가능성이 적어짐
  • 도커는 다양한 운영 체제와 클라우드 플랫폼에서 지원

가상화

  • 하나의 물리적 서버 또는 리소스를 가상적으로 분할하여 여러 대의 가상 서버 또는 가상 환경을 만드는 기술
  • 하나의 물리적인 서버 자원을 논리적인 단위로 나누어서 사용할 수 있게 하기 때문에 물리적인 서버의 자원 활용도를 높일 수 있으며, 가상 서버를 쉽게 생성, 삭제, 이동할 수 있기 때문에 유연하게 인프라를 운영
    • 예를 들어 서버의 리소스가 절반을 사용할때 사용하지 않은 리소스를 사용함에 따라 효율적으로 사용할수 있습니다.
  • 하드웨어 가상화와 소프트웨어 가상화로 나눌수 있음
    • 하드웨어 가상화는 하이퍼바이저(Hypervisor)라는 소프트웨어를 이용하여 하드웨어를 가상화
      • 하이퍼바이저는 호스트OS(Host OS) 위에서 동작하는 소프트웨어로, 하드웨어 자원을 가상 머신(VM, Virtual Machine)에 할당하여 각각의 가상 머신이 독립적으로 운영
    • 소프트웨어 가상화는 운영체제 수준에서 가상화를 수행
      • 운영체제의 커널을 공유하여 여러 개의 가상 서버를 구성하고, 각각의 가상 서버는 독립적으로 동작
      • 대표적으로 리눅스 컨테이너(Linux Container) 기술
  • 가상화는 서버, 스토리지, 네트워크 등 다양한 분야에서 활용되고 있습니다.
    • 스토리지 가상화는 스토리지 리소스를 가상화하여 스토리지의 효율성을 높이고 유연하게 관리할 수 있게 합니다.
    • 네트워크 가상화는 가상 네트워크(Virtual Network)를 구성하여 하나의 물리적 네트워크를 가상으로 분할하고, 각각의 가상 네트워크를 독립적으로 운영할수 있다.
  • 서버 가상화 기술은 대규모 서버 운영을 위한 서버 통합 관리, 시스템 이중화, 비즈니스 연속성, 비용 절감 등을 위해 활용됩니다.

도커와 가상머신의 장단점

가상머신(Hypervisor)

  • 장점
    • 완전한 격리 환경을 제공하여, 안전한 환경에서 애플리케이션을 실행
  • 단점
    • 무겁고 느리기 때문에, 실행 속도가 느림
    • 여러 개의 가상 머신을 운영하기 위해서는, 많은 리소스가 필요
    • 호스트 운영 체제와 완전히 분리되어 있기 때문에, 호스트 운영 체제와의 통합이 어려움

도커(Container)

  • 장점
    • 경량화된 컨테이너를 사용하기 때문에, 실행 속도가 빠름
      (가상머신과 다르게 커널을 공유하기 때문에 실행 속도가 빠름)
    • 호스트 운영 체제와 컨테이너 운영 체제가 같은 커널을 공유하기 때문에, 리소스 사용량이 적음
    • 개발 환경과 운영 환경의 차이를 최소화
      (도커의 이미지를 기반으로 애플리케이션을 배포하기 때문에)
  • 단점
    • 호스트 운영 체제와 같은 운영 체제를 사용해야 하므로, 다양한 운영 체제를 지원하지 않음
    • 완전한 격리 환경을 제공하지는 않으므로, 보안 취약점이 있을 가능성이 있음

컨테이너

  • 가상화 기술 중 하나로, 하나의 운영 체제에서 여러 개의 격리된 공간을 만들어 다양한 애플리케이션을 구동할 수 있도록 하는 기술
  • 하나의 호스트 운영 체제 위에 여러 개의 격리된 공간을 만들어 각각 독립적인 환경에서 애플리케이션을 실행
  • 각 컨테이너는 격리된 파일 시스템, 네트워크, 프로세스, 사용자 공간 등을 갖추고 있어 서로 독립적으로 동작하며, 하나의 컨테이너에 문제가 발생해도 다른 컨테이너에는 영향을 미치지 않음
  • 가상머신과는 다르게 운영 체제를 가상화하지 않고, 호스트의 운영 체제를 공유하므로 빠르고 가벼움
  • 대표적인 컨테이너 기술로는 도커(Docker)

도커 이미지

  • 가상머신에서 사용하는 이미지와 비슷한 역할
  • 어떤 애플리케이션을 실행하기 위한 환경
  • 이 환경은 파일들의 집합입니다. 도커에서는 애플리케이션을 실행하기 위한 파일들을 모아놓고, 애플리케이션과 함께 이미지로 만들 수 있습니다.
  • 이미지를 기반으로 애플리케이션을 바로 배포
  • 만일, 호스트 OS의 커널과 컨테이너의 OS 커널이 다르면 다른 부분만을 패키징함

위의 내용을 바탕으로 Docker을 사용하지 않을 때와의 차이를 작성하고자 합니다.

 

Docker를 사용하지 않을 때

  • 환경 불일치 문제
    • 배포할 서버 환경마다 사용되는 Java 버전이나 라이브러리 버전이 다를 수 있습니다.
    • 이로 인해 애플리케이션이 예상대로 동작하지 않을 가능성이 높습니다.
    • 예를 들어, 개발 환경에서는 Java 8을 사용하지만, 운영 환경에서는 Java 11을 사용한다면, 특정 기능이나 라이브러리가 서로 호환되지 않아 문제를 일으킬 수 있습니다.(UnsupportedClassVersionError , ClassNotFoundException등 예외 상황 발생)
  • 복잡한 배포 과정
    • 서버마다 각기 다른 설정 파일을 관리하고, 수동으로 의존성을 설치해야 하며, 환경 변수를 일일이 설정해야 합니다.
    • 이 과정에서 인재에 의한 실수가 발생할 가능성이 높고, 배포 속도가 느려질 수 있습니다.

Docker 사용시

  • 일관된 환경 제공
    • Docker 컨테이너는 애플리케이션과 그 의존성을 포함한 이미지를 사용하므로, 모든 환경(개발, 테스트, 운영)에서 동일하게 실행됩니다. 이는 환경 불일치로 인한 문제를 최소화합니다.
    • Docker를 사용하여 환경 불일치 문제를 최소화할 수 있지만, Docker 컨테이너는 호스트 시스템에서 실행되기 때문에 호스트 시스템의 설정이나 자원 사용량 등이 Docker 컨테이너에 영향을 줄 수 있습니다.
  • 자동화된 배포 과정
    • Docker를 사용하면 서버 설정, 의존성 설치, 환경 변수 관리가 자동화되어 배포 과정이 단순해지고 일관성이 높아집니다.
    • Docker 이미지를 빌드할 때 모든 필요한 의존성과 설정이 포함되므로, 추가적인 설정이나 설치 과정이 필요 없습니다.
  • 확장성과 자원 효율성
    • Docker 컨테이너는 가상 머신보다 가볍고 빠르게 실행되며, 자원 효율성이 높습니다.
    • 이는 동일한 호스트에서 더 많은 컨테이너를 실행할 수 있게 해주며, 자원 충돌 문제를 최소화합니다.

Docker 설치

Docker 공식 홈페이지을 통해 windows 버전으로 docker을 설치 하였습니다. 

 

WSL2를 설치하고 활성화하는 방법

WSL2는 Windows Subsystem for Linux 2의 약자로, Microsoft Windows 운영 체제에서 Linux 커널을 실행할 수 있도록 하는 기술입니다.이는 Windows에서 Docker는 Linux 기반으로 실행되기 때문에 현재 Local 환경인 Windows에서 docker을 사용하기 위해서는 WSL2를 설치하여야 합니다. 

 

간단하게 WSL2를 설치하는 방법을 설명하도록 하겠습니다. 윈도우 10 버전 2004(빌드 19041 이상)이나 윈도우 11에는 기본적으로 wsl 명령어가 포함되어있습니다. Powershell(or CMD)을 관리자 모드로 열고 다음 명령어를 실행해주세요.

$ wsl --install

설치가 끝나고 다음 명령어를 실행해, WSL 버전 기본값을 2로 변경해줍니다.

$ wsl --set-default-version 2

WSL2로 리눅스를 사용하고자 하는 경우, 리눅스 배포판 설치하는 등 추가 설정이 필요합니다만, Docker만 사용하는 경우 여기까지만 설정하면 됩니다.


Dockerfile 구성

# Amazon Corretto 17을 베이스 이미지로 사용
FROM amazoncorretto:17

# 개발 환경에서 실행하려면 환경 변수를 설정합니다.
ENV SPRING_PROFILES_ACTIVE=live

# Gradle Wrapper를 복사하여 사용
COPY gradlew .
COPY gradle gradle

# Gradle 프로젝트 파일들을 복사
COPY . .

# Gradle Wrapper를 초기화하고 종속성을 다운로드
RUN ./gradlew clean build

# 빌드된 JAR 파일을 복사하여 이미지에 추가
ARG JAR_FILE_PATH=build/libs/*.jar
COPY ${JAR_FILE_PATH} auction-server.jar

# 애플리케이션을 실행하기 위한 명령을 지정
ENTRYPOINT ["java", "-jar", "auction-server.jar"]

도커를 이미지화 하기 위해 위의 파일을 구성해야합니다. Auction-Server 프로젝트에 맞게 베이스 이미지를 설정하였습니다.


Docker-Compose.yml 구성

version: '3'

services:

  spring-boot:
    build:
      context: ./
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://host.docker.internal:3306/auction_server?serverTimezone=Asia/Seoul
      REDIS_HOST: host.docker.internal
      REDIS_PORT: 6379
      SPRING_RABBITMQ_HOST: host.docker.internal
      AWS_SES_ACCESS_KEY: [AWS_SES_ACCESS_KEY]
      AWS_SES_SECRET_KEY: [AWS_SES_SECRET_KEY]
      TEST_API_KEY: [TEST_API_KEY]
      payment.ret.url: http://host.docker.internal:8080/payments/approve?orderNo=
      payment.ret.cancel.url: http://host.docker.internal:8080/payments/close?orderNo=
      SPRING_ELASTICSEARCH_REST_URIS: host.docker.internal:9200  # Elasticsearch 호스트 및 포트 설정

docker-compose.yml의 위치도 Dockerfile과 동일한 위치로 설정하였습니다.

 

일반적으로 여러 이미지를 통합하여 사용하려면 docker-compose.yml 파일을 작성해야 합니다. 이는 하나의 물리적인 서버에 여러 서버(DB 서버, Elasticsearch 서버 등)를 구성하거나 여러 애플리케이션 서버를 구성할 때 사용됩니다. 그러나 현재 Auction-Server 프로젝트에서는 DB 서버와 Elasticsearch 서버를 별도로 두기로 결정되어 있어 Spring Boot 이미지 하나만을 생성했습니다. 추후에 여러 애플리케이션 서버를 구성할 가능성이 있으므로 docker-compose 파일을 작성하였습니다.

 

로컬 환경에서 테스트를 위해 host.docker.internal을 사용하여 로컬 환경으로 연결하도록 설정하였습니다. 또한, 여기서 설정한 환경변수는 application.properties 파일에서 사용되는 환경변수와 동일하지만, Docker Compose에서 작성한 환경변수를 우선적으로 사용합니다.

 

Docker Compose을 사용하면 Volume과 Network을 설정할 수 있습니다. 각각은 컨테이너의 데이터 공유와 네트워킹을 관리하는 중요한 기능입니다. 보통 Docker 컨테이너는 일회성이며, 종료되면 데이터가 손실될 수 있습니다. 따라서 볼륨은 컨테이너 간 데이터 공유와 데이터 유지를 위한 중요한 메커니즘입니다. Elasticsearch의 경우, 데이터를 볼륨 경로로 파일로 저장할 수 있습니다. 대표적인 예시로  웹 애플리케이션의 로그 파일을 Docker 컨테이너 간에 공유하여, 서버가 종료되더라도 중요한 예외와 에러 정보를 보관하고 모니터링할 수 있습니다.

 

또한, Docker 컨테이너는 기본적으로 독립된 네트워크 환경에서 실행됩니다. 그러나 경우에 따라 여러 컨테이너 간 통신이 필요할 수 있으며, 이때 네트워크 기능을 사용합니다. Docker는 여러 가지 네트워크 드라이버를 제공하며, 이를 통해 컨테이너를 해당 네트워크에 연결할 수 있습니다. 예를 들어, 웹 애플리케이션 서버는 데이터베이스 서버와 캐싱 서버와 통신하기 위해 네트워크 세션을 설정하여 컨테이너 간의 통신을 가능하게 합니다.


이제 설정을 마쳤으니 docke-compose을 통해 이미지를 생성해보도록 하겠습니다. compose 파일의 위치에 cmd(or powersehll)을 실행하여야 합니다. 

[그림 1] Intellij docker-compose build 결과

위와 [그림 1] 과 같이 Intellij 에서 실행해도 됩니다. 성공적으로 마치게 되면 docker desktop을 통해 image가 생성되는 것을 확인할 수 있습니다.

[그림 2] docker desktop 이미지 생성 확인

이 이미지를 컨테이너화 하여 실행하도록 하겠습니다.

[그림 3] Intellij docker-compose up 결과

이로써 정상적으로 컨테이너화가 이루어졌음을 알 수 있으며, 해당 컨테이너를 배포할 때 환경 불일치 문제를 해결하고 복잡한 배포 과정을 거치지 않아도 됩니다.


느낀점

  • 이미지 생성 중에 실수가 발생했습니다. MySQL 이미지를 설정하고 Docker Compose 파일을 사용하여 컨테이너를 활성화할 때, Spring Boot가 MySQL 테이블을 생성하기 전에 발생하는 문제가 있었습니다. 이를 해결하기 위해 테이블이 DDL로 완료된 후에 테이블이 정상적으로 생성되었는지 확인하는 healthcheck 옵션을 사용하여 Spring Boot가 실행될 때까지 대기하도록 설정했습니다. 그러나, 현재는 애플리케이션 서버와 별도의 서버 구성을 선택했기 때문에 이러한 설정은 불필요합니다. 따라서 해당 설정을 제거했습니다.
  • 이에 대한 경험을 바탕으로 Docker설정에 익숙해졌습니다.
  • 현재는 로컬로 연결되어 있지만, 추후에는 MySQL과 Elasticsearch를 비롯한 서버를 별도로 구성하여 라이브 환경과 같이 연결하고자 합니다. 각 서버에 대한 이미지화도 구성하고 설정할 계획입니다.

출처

 

GitHub - gamsayeon/Auction-Server

Contribute to gamsayeon/Auction-Server development by creating an account on GitHub.

github.com

+ Recent posts