Post

도커로 애플리케이션 배포하

kbo.png

도커 이미지로 배포한다?
도커가 무엇이고 이것을 어떻게 왜 사용하는지, 배포가 어떻게 이루어지는지에 대해 알아보자.

그 전에 도커는 어떻게 등장했고, 기존에는 어떤 방식으로 배포가 이루어졌을까?

기존 가상화 기술은 가상 머신을 실행하기 위해 각 가상환경 마다 별도의 운영체제와 하드웨어 드라이버를 설치해야 했다. 불필요하게 운영체제를 반복 설치해야 하기 때문에 호스트 컴퓨터의 자원에 부담을 주었다. 이를 개선하기 위해 도커 엔진을 이용하여 컨테이너라는 가상 환경을 띄우는 방식이 등장했다.

컨테이너는 애플리케이션을 실행하기 위한 가상 환경으로, 별도의 운영체제를 설치할 필요 없이 호스트 OS의 커널을 공유하기 때문에 가볍고 효율적이다. 또한, 이미지 형태로 애플리케이션을 패키징하여 저장할 수 있다. 도커 엔진이 설치된 환경에서는 이 이미지만으로 별도의 운영체제 설치 없이도 애플리케이션을 쉽게 실행할 수 있다. 이러한 특성 덕분에, 예를 들어 스프링부트 애플리케이션을 배포하는 것이 훨씬 간편해진다.



가상 머신과 컨테이너는 뭐야?

둘 모두 배포 기술로 로컬에서 개발한 프로젝트를 네트워크 환경에 배포할 수 있도록 도와준다. 두 기술은 동작 방식에 차이가 존재한다. VM은 독립된 환경을 제공하며, 며, 각 VM은 자체 운영체제를 실행한다. 반면, 컨테이너는 운영체제를 공유하면서 애플리케이션을 격리하여 실행한다. 이를 통해 로컬에서의 개발 환경과 동일하게 다양한 서버 환경에서 애플리케이션을 실행할 수 있다.


가상 머신

image

하이퍼바이저는 여러 개의 가상 머신(VM) 을 실행하며, 각 VM은 독립된 실행 환경을 제공한다. 즉, 각각의 VM이 동일한 운영체제를 사용하더라도, 서로 데이터와 코드를 공유하지 않는다.

이로 인해 각 VM은 최소 GB 단위의 공간을 필요로 하고, VM 수가 늘어날수록 필요한 자원도 비례해서 증가한다. 또한, 부팅 시에도 상당 시간이 소요된다.

컨테이너

image

기존의 무겁고 느린 가상화 방식을 해결하기 위해, 프로세스 격리라는 새로운 접근 방식이 나타났다. 이 방식은 각 애플리케이션을 독립된 환경에서 실행할 수 있게 하여, 가상화의 효율성을 높였다. 그 대표적인 기술이 바로 컨테이너화이다.

컨테이너화는 여러 애플리케이션이 하나의 커널을 공유하면서도, 격리된 환경을 제공한다 따라서 부팅 속도가 빠르고, 컨테이너 수가 증가해도 디스크 공간을 많이 차지하지 않는다.

각 컨테이너 내의 프로세스들은 자신이 운영체제의 모든 자원을 독점한다고 생각하지만, 실제로는 자원을 공유하고 공유한다.

하지만, 물리적으로 격리된 가상 머신에 비해 컨테이너는 보안에 취약한 단점이 있을 수 있다. 가상 머신은 하드웨어 수준에서 완전히 격리되므로 보안성이 더 강한 반면, 컨테이너는 커널을 공유하기 때문에 만약 커널에 취약하다. 따라서 여러 컨테이너가 보안 위험에 노출될 수 있기 때문에 신중하게 고려해야 한다.




이제, 가상화와 컨테이너 방식의 차이를 알았으니,
이러한 컨테이너 기술을 구현하고 관리할 수 있도록 도와주는 도커에 대해 알아보자.



도커 (Docker) ?

컨테이너 기반의 오픈 소스 가상화 플랫폼으로, 애플리케이션을 실행하기 위한 가상 환경인 컨테이너를 만들어주는 도구이다.

컨테이너는 애플리케이션과 그에 필요한 라이브러리, 설정 파일을 포함하여 하나의 단위로 실행된다. 이를 통해 어떤 환경에서든 일관되게 실행할 수 있다. 가상머신 보다 빠르고 가볍고, 배포와 관리가 용이하다.

기존의 서버 관리 방식은 물리적 서버에 애플리케이션을 직접 설치하고 관리하는 방식으로 환경설정이나 라이브러리 호환성 등의 문제가 자주 발생했었다. 하지만 도커는 애플리케이션을 독립된 컨테이너로 실행하여 환경의 일관성을 유지하고, 배포 과정을 단순화하기 때문에 어떤 서버에서도 애플리케이션을 쉽게 실행할 수 있으며, 클라우드 환경과의 통합도 용이하다.


도커에서의 배포 과정은 어떻게 이루어질까?

docker_process.png

도커에서 애플리케이션을 배포하는 과정은 다음과 같다.

  1. Dockerfile 작성: 애플리케이션의 환경과 실행 방식을 정의하는 Dockerfile을 작성한다.
  2. 이미지 생성: 작성한 Dockerfile을 바탕으로 도커 이미지를 생성한다.
  3. 컨테이너 실행: 생성된 이미지를 기반으로 컨테이너를 만들어 실행한다.
  4. 이미지 공유: 이미지를 도커 허브나 레지스트리에 업로드하여 다른 환경에서 사용할 수 있도록 한다.
  5. 서버 배포: 서버에 이미지를 다운로드받아 컨테이너를 실행하여 애플리케이션을 배포한다.

도커를 사용하면, 애플리케이션 실행 환경을 표준화하여 어디서든 동일하게 실행할 수 있고, 애플리케이션을 쉽게 배포하고 관리할 수 있다.

도커 이미지?

컨테이너를 실행하기 위해 컨테이너에 로드되는 템플릿으로, 애플리케이션을 실행하는 데 필요한 프로그램, 소스코드 및 라이브러리, 컴파일 실행 파일 등이 포함되어 있다. 도커 이미지는 애플리케이션을 실행할 수 있는 필수적인 환경을 완벽하게 갖춘 상태이다.

하지만 이미지는 실행 가능한 상태가 아니라, 단지 컨테이너를 생성할 수 있는 템플릿으로, 애플리케이션과 가상 환경을 묶은 일종의 스냅샷이기 때문에, 이미지만으로는 직접 실행할 수 없다. 실행은 이 이미지를 바탕으로 만들어진 컨테이너에서 이루어진다.

도커 이미지는 읽기 전용 템플릿으로, 한번 만들어지면 수정할 수 없다. 수정하려면 새로운 이미지를 빌드해야 한다. 계층 구조를 가지며, 베이스 이미지 위에 필요한 파일과 설정이 추가된다. 이 계층 구조는 재사용이 가능하도록 하여, 동일한 베이스 이미지를 공유하는 여러 컨테이너들 간에 중복되는 부분을 최소화한다.

즉, 도커 이미지는 실행 가능한 컨테이너를 만드는 기본 틀의 역할을 하며, 애플리케이션을 배포하는 데 중요한 역할을 한다.

도커 컨테이너

애플리케이션과 그 실행에 필요한 모든 환경을 하나로 묶어 격리된 공간에서 실행되는 가상화 기술이다. 애플리케이션을 실행하기 위한 독립적인 환경을 제공하는 상자와 같은 역할을 한다.

도커에서는 이미지를 바탕으로 컨테이너를 생성하고, 생성된 컨테이너는 곧바로 실행 상태가 되어 애플리케이션을 동작시킬 수 있다.

각 컨테이너는 CPU, 메모리, 네트워크 등의 자원을 독립적으로 사용하고, 다른 컨테이너와 격리되어 독립적으로 동작한다.

컨테이너는 가상머신(VM)에 비해 훨씬 빠르게 시작할 수 있으며, 자원을 적게 사용하기 때문에 효율적이다. 이를 통해 애플리케이션을 가볍고 빠르게 배포하고 실행할 수 있다.

Dockerfile

도커 이미지를 생성하기 위한 설계도로 컨테이너가 어떻게 동작해야 하는지에 대한 정보가 있다. OS, 실행 코드, 필요한 라이브러리 및 환경 변수 설정을 포함해 특정 애플리케이션을 실행하는데 필요한 모든 것을 정의한다.

Docker Compose

여러 도커 컨테이너를 정의하고 실행하기 위한 도구로 Yaml파일 형식으로 저장된다. 여러 컨테이너가 어떻게 상호 작용하는지, 네트워크와 볼륨 설정은 어떻게 되어야 하는지 등을 정의한다. 여러 컨테이너를 동시에 관리하고 구성하는데 적합하다. 예를 들어, 하나의 웹 애플리케이션 서버, 데이터베이스 서버, 캐시 서버 등 각각 다른 컨테이너로 실행하고 이들이 함께 동작하도록 Docker Compose를 사용해 구성할 수 있다.

Dockerfile은 단일 이미지를 구축하여 컨테이너 만드는 방법을 정의하고, Docker Compose는 여러 컨테이너의 구성과 관리에 초점을 두고 여러 컨테이너가 어떻게 함께 동작할지에 대한 외부 설정을 다룬다.


Docker Hub

hub.png

사용자가 도커 컨테이너 이미지를 저장, 공유 및 관리할 수 있는 클라우드 기반 레지스트리 서비스이다.

미리 빌드된 도커 이미지에 접근하여 협업할 수 있는 중앙 저장소 역할을 하며, Docker 환경에서 애플리케이션을 더 쉽게 빌드, 배포하고 실행할 수 있다.

Docker Hub를 통해 다른 개발자가 만든 이미지를 검색하고 다운로드할 수 있고, 자신의ㅣ 이미지를 저장하고 관리할 수 있닫. 그리고 자동 빌드를 생성하여 코드가 변경될 때마다 이미지를 자동으로 빌드하고 테스트할 수 있다.






이제 서버에 배포를 해보자.

사전 작업으로 서버에 도커를 설치하고 Docker Repository 생성해주어야 한다.



서버에 배포하기

1. DockerFile 작성

어플리케이션을 Docker 이미지로 만들기 위해서는 Docker File이 필요하다.

image

이 Dockerfile의 각 명령어와 의미는 아래와 같다.

  1. FROM openjdk:17
    • 도커 이미지의 베이스 이미지를 지정
    • OpenJDK 17 버전이 설치된 이미지를 기반으로 컨테이너를 생성한다.
  2. EXPOSE 8080 :
    • 도커 컨테이너가 외부와 통신할 포트를 지정한다.
  3. ARG JAR_FILE=build/libs/*-SNAPSHOT.jar
    • 빌드된 jar파일 경로를 변수로 설정한다.
  4. COPY ${JAR_FILE} app.jar
    • 빌드된 jar파일을 Docker 이미지안에 /app.jar로 복사한다.
  5. ENTRYPOINT
    • 컨테이너가 시작될 때 실행할 기본 명령을 지정한다.
    • java 명령어를 사용하여 Java 애플리케이션을 실행한다.
    • -javaagent는 Pinpoint 에이전트를 로드하고, -Dpinpoint.agentId-Dpinpoint.applicationName로 Pinpoint를 설정한다.
    • -jar 옵션은 /kboticket.jar 파일을 실행하는 역할을 한다.

2. Docker 이미지 생성

먼저, Dockerfile이 위치한 디렉토리에서 아래의 명령어를 실행하여 이미지를 생성한다.

  • -f : Dockerfile의 경로를 지정
  • -t : 생성할 이미지의 태그를 설정
  • . : 현재 디렉토리에서 Dockerfile을 찾는다.

docker build -f Dockerfile -t namespace/repository-name .


3. Docker 이미지 업로드 (Push)

로컬에서 생성한 이미지를 Docker Hub에 업로드하기 위해서는 먼저 Docker Hub에 로그인해야 한다.
로그인 후 push 명령어를 통해 이미지를 푸시하고 Docker Hub에 업로드한다.

docker login -u 계정이름 -p 비밀번호
docker push namespace/repository-name

CI/CD에서 Docker 이미지 배포하기

나는 CI/CD 파이프라인을 이용하여 Docker를 배포하기 위해 CD.yml 에 도커 이미지를 생성, 푸시하고 빌드하는 과정을 추가했다.

image

docker login 명령어로 Docker Hub에 로그인하고, docker build 명령어로 이미지를 빌드한 후, docker push 명령어로 이미지를 지정된 레포지토리에 업로드합니다.

이렇게 생성된 이미지는 Docker Hub에 업로드되어, 이후 배포 과정에서 사용될 수 있다.


4. 서버에서 이미지 실행하기

서버에 다시 접속해주고 아래 명령어를 입력해줍니다.

docker pull namespace/repository-name # 이미지 다운로드
docker run -d -p 서버port:컨테이너port --name 컨테이너이름 namespace/repository-name # 이미지 실행

  • d : 컨테이너를 백그라운드에서 실행
  • p : 컨테이너포트와 서버포트를 binding한다.

아까 컨테이너에서 노출시킨 8080포트를 서버의 8080포트와 연결시킨다.

image







이상 도커를 이용해 서버를 배포하는 과정을 학습해 보았다.

이 과정을 통해 도커의 가상화 기술과, 효율적으로 애플리케이션을 배포하고 관리할 수 있다는 점을 알았다. 특히, 도커를 사용하면 애플리케이션의 실행 환경을 표준화할 수 있어, 개발 환경과 실제 서버 환경 간의 차이를 최소화하고, CI/CD를 활용해 배포 과정도 자동화할 수 있다는 점이 매우 편리했던 것 같다.

This post is licensed under CC BY 4.0 by the author.