본문 바로가기
Docker

[Docker] Docker 개념 정리 및 Spring 환경 배포 프로세스

by 도전하는 린치핀 2024. 3. 30.

0. Docker 의 개념과 역할

먼저 Docker의 자세한 개념과 설명은 이전 포스팅에서 다루었기 때문에 이번 포스팅에서는 간단하게만 다루도록 하자.

 

[ASAC_04/Docker] Docker의 기본 개념

Docker 사용 이유 : Consistency(일관성)와 Multiple Containers(다중 컨테이너) 어플리케이션 동작의 일관성을 갖기위해 (어느 서버나 컴퓨터에서 동작해도 정상적으로 동일한 동작으로 하기 위해) 어플리

rnclf1005.tistory.com

 

Docker 컨테이너 기반 가상화 플랫폼으로, 응용 프로그램과 그 종속성을 격리된 환경인 컨테이너로 패키징하여 실행하는 기술이다.

Docker를 사용하는 가장 중요한 개념은 "어플리케이션 동작의 일관성을 가지기 위해 사용한다."는 개념이다.

여기서 동작의 일관성은 "어플리케이션의 버전, 설정 명령어의 존재 여부, 환경 변수, 실행환경 등"과 같은 환경과 어플리케이션과 함께 묶어 하나의 응용 프로그램을 다른 환경에서도 일관되게 실행할 수 있고, 개발 환경과 운영 환경 사이의 차이로 인한 문제를 해결해주는 것이다.

또한, Docker의 중요한 개념은 하나의 서버 내 독립적인 다중 컨테이너를 구동할수 있다는 점이다.

 

0-1. Docker 사용 시 자주 등장하는 단어 정리

  • Docker Engine(Docker Daemon) : Docker Container를 구동시킬 수 있는 엔진
    • 간단하게 Docker Engine위에 Image를 올리고 Run을 하면(구동시키면) 독립적인 Docker Container 생성된다고 생각하자.
  • Docker File : Docker Image를 만들기 위한 스크립트 파일(설정 파일)
    • 어떤 형태의 Docker Image를 생성할 지 정해진 문법을 통해 스크립트를 작성한다.
    • Docker의 빌드(build)는 Docker File을 기반으로 나열된 명령문을 수행하면서 Docker Image를 생성한다.
    • Docker File을 토대로 Image가 어떤 형식인지 알 수 있다.
    • Docker File의 다양한 명령문들은 추가적인 포스팅에서 다룬다.
  • Docker Image : Docker File을 기반으로 Docker Build 된 상태
    • 어플리케이션과 바이너리 파일 및 라이브러리(어플리케이션 구동 환경)을 묶어 놓은 상태
    • Docker Image를 Run하면 바로 어플리케이션이 동작할 수 있다.
    • Image에는 (Binary File / Library)가 포함되어 있기 때문에 따로 어플리케이션을 구동할 때 환경 설정을 할 필요가 없다.
  • Docker Container : Docker Image가 구동(run)한 상태로 격리된 공간에서 프로세스(어플리케이션)를 동작시킨 것
    • 간단하게 Docker Image를 프로그램 / Docker Container를 프로세스라고 생각할 수 있다.
      • 프로그램 : 소스코드를 바탕으로 작성된 어떠한 파일로 아직 메모리나 CPU에 올라가지 않은 상태의 바이너리 파일
      • 프로세스 :  프로그램을 바탕으로 실행중인 상태로 프로그램이 메모리에 올라가 CPU가 할당되어 동작
    • Docker Container 또한 메모리 CPU에 Docker Image가 동적으로 할당되어 있는 상태라고 할 수 있다.
  • Docker Compose : Dockerfile로 정의한 개별 Container들을 한번에 띄워 Multiple Container들을 하나의 완벽한 Apllication으로 서비스하게 하는것
    • 간단하게 생각하여 여러개의 Docker File과 각 Docker File의 관계 등을 하나의 Docker Compose에 정의하여 하나의 큰 Container에 여러개의 Container를 띄우는 Multiple Container의 개념
  • Docker를 사용할 때 혼용되는 용어
    • Host ~= Node ~= Instance ~= Local 컴퓨터 ~= Server 
    • 간단한 예로 "Host는 다수의 Container를 가진다."에서 Host는 위의 것들과 비슷하게 혼용되어 사용될 수 있다.

0-2. Docker 핵심 Flow

  • Docker build : Dockefile을 기반으로 명령어를 수행하는 것으로 Build가 끝나면 Docker Image가 생성된다.
  • Docker Push : 생성된 Docker Image를 Docker Registory(AWS의 ECR / Docker에서 제공하는 Registory)에 올리는 행위
  • Docker Pull : Docker가 구동될 EC2에서 Push한 Docker Image를 다운로드 받는 행위
  • Docker Run : Pull 받은 Docker Image를 구동시키는 행위로 Run을 통해 Docker Container가 구동된다.

 

1. Spring 환경에서 Docker 활용 개념

해당 목차에서는 기본적인 프로세스를 순서대로 나열하여 실제 예시를 통한 이해보다는 흐름을 파악하도록 하자.

기본적으로 Spring boot는 .java 파일들의 모음(개발자가 개발한 내용)을 build하여 JAR 파일로 변경하여 JRE(Java Runtime Environment)를 통하여 구동만 시키면 된다.

이때, spring boot가 아닌 spring에서 build를 하면 또 다를 수 있지만. 해당 포스팅에서는 꼭 알아야하는 상태에 대해서 단어로 나열하고 추후에 따로 포스팅에서 다룰 수 있다면 다루겠다.

더 좋은 개발자가 되기 위해서는 꼭 알아야하는 핵심 키워드이니 해당 키워드에 대해서 잘 모른다면 꼭 찾아보고 공부하고 넘어가자.

  • Spring boot / Spring 차이 (빌드 시 생성되는 파일의 차이에 중점)
  • JAR 파일 / WAR 파일 차이
  • JDK / JRE 차이

1-1. Docker를 활용하지 않은 Spring의 배포 프로세스 ( CI/CD )

  1. Local에서 모든 개발이 완료된 파일을 build를 통한 .jar파일을 생성한다. (CI, 앞으로 CI는 간단하게 빌드라고 생각하자)
    • 이때 build를 하는 방법은 여러가지가 있지만 해당 포스팅에서는 "./gradlew clean build" 을 통해서 build를 하겠다.
  2. 그 후, 어플리케이션이 구동될 서버에 사용할 EC2에 JRE를 설치한 뒤 JAR 파일을 업로드 한다. (CD, CD는 배포라고 생각하자)
  3. 모든 다운로드가 끝나면 JRE를 바탕으로 JAR파일을 구동시키면 Spring에서 서버가 배포되는 것이다.
이때, CI(빌드)과정을 로컬에서 직접 진행할 수 있지만 불필요한 Computing 자원을 아끼기 위해 Github Action이나 Jenkins를 사용할 수 있다.
해당 포스팅에서 모든 것을 다룰 수 없기 때문에 Github Action을 간단하게 설명하자면 Github에 개발자가 Commit한 내용을 바탕으로 자동으로 빌드를 해주는 개념이라고 생각하자. 
즉, Github Action은 개발자가 Local에서 빌드(CI 절차)를 진행하며 Computing 자원을 사용하지 않고 CI를 이관하는 것이라고 할 수 있다.

 

1-2. Docker를 활용한 Spring의 배포 프로세스

기본적인 개념은 1-1.과 비슷하지만 Docker를 사용한다면 2~3번에서 진행한 JRE 설치 및 JAR 파일 업로드를 개별적으로 진행하는 것이 아닌 Docker Image안에 담아 놓는 것이라고 생각할 수 있다.

  1. Local에서 모든 개발이 완료된 파일을 빌드하여 .jar 파일을 생성한다. (CI)
  2. 해당 프로젝트 내에 base image(기본 환경) 및 여러가지 명령(.jar 파일 copy, 구동될 때 동작할 명령어 등)을 통해 Dockerfile을 생성한다.
  3. docker file이 위치한 곳에서 docker build를 통해 Docker Image를 생성하고 Docker Registory에 Push를 진행한다. 
    • 이때 하는 build를 spring 프로젝트에서 .jar파일을 생성하는 build(CI)와 헷갈리지 말자.
    • 또한 이때 Dockefile을 기반으로 생성되는 image이기 때문에 모든 환경설정(bins / libs)가 담겨 있다.
    • 따라서, Docker Image와 Docker Engine을 설치하였다면 추가적인 JRE를 설치하거나 버전을 맞추는 등의 환경 세팅이 필요없다.
  4. 어플리케이션이 구동될 곳(EC2)에 Docker Engine을 설치하고 Docker Image를 Pull한다.
  5. Docker run을 통하여 Docker Image를 구동(메모리 / CPU 할당) 하면 독립된 공간에 Docker Container가 구동된다. (CD)

 

1-1. 과 마찬가지로 Docker를 활용해도 CI를 Github Action에게 이관할 수 있다.

 

1-3. Docker / Github / Github Action / Docker Registory / EC2를 활용한 프로세스

 

파란 표시에 집중하여 프로세스를 왼쪽에서 오른쪽으로 살펴보면 T1/T2를 구분되어 있다.

  • 두가지를 구분하는 것은 java build를 어디서 하느냐의 차이다.
  • T1 : 1-2.에서 설명한 프로세스로 Github Action을 사용하지 않고 Local에서 Java build를 진행하는 것으로 본다.
  • T2: 이번 목차에서 다뤄야 할 내용으로 모든 CI / CD를 개발자가 직접 하는 것이 아닌 자동화 프로세스가 있는 것들을 사용하는 것이다.
  1. Local에서 모든 개발이 완료된 소스코드를 개발자가 Github Repository에 업로드 한다.
  2. Github Repository에서 설정하여 Github Action과 연결되어 Github Action에서 자동으로 java build를 수행한다. (CI)
  3. Github Action에서 build통해 .jar 파일이 생성된다.
  4. Github Action에서 .jar파일과 소스코드 내 Dockerfile을 기반으로 Docker build를 통해 Docker Image가 생성된다.
  5. 생성된 Docker Image는 Docker Registory에 Push되어 저장된다.
  6. EC2 내에 Docker Engine을 설치하고 Docker Registory에서 Docker Image Pull을 진행한다.
  7. Pull을 통해 다운로드 받은 Docker Image를 Docker Run을 통해 독립된 Docker Container를 구동시킨다. (CD)

1-4. 최종 정리해본 Spring 환경에서 Docker Image를 활용한 배포 프로세스 도식

 

 

더보기

해당 내용은 매우매우 간단하게 Docker를 처음 접하는 입장에서 Docker에 대해서 헷갈린 부분들을 정리해보고 Spring에서 Docker를 활용한 간단한 프로세스를 정리해본 것으로, 틀린 내용 피드백 주시면 수정하겠습니다.