[MSA][Docker] 효율적인 도커 이미지 만들기 #2 - 도커 레이어 캐슁을 통한 빌드/배포 속도 높이기  

효율적인 도커 이미지 만들기

#2 도커 레이어 캐슁을 통한 빌드/배포 속도 높이기

조대협 (http://bcho.tistory.com)

 

도커는 이미지 단위로 빌드를 하고 배포를 하지만, 도커의 이미지는 여러개의 레이어로 되어 있다. 아래와 같은 자바 애플리케이셔을 패키징한 도커 컨테이너 이미지가 있다고 하자

FROM openjdk:8-jre-alpine

ARG ./target/hellospring-0.0.1-SNAPSHOT.jar

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

 

이 이미지가 어떤 레이어로 구성되어 있는지를 보려면 %docker history {컨테이너 이미지명} 을 실행하면 이미지의 레이어를 볼 수 있는데,   각각의 명령항에 따라서 레이어가 생성된것을 볼 수 있다. 

 

 

그리고 각각의 크기를 확인할 수 있다. 위의 history를 보면, 

 

 

 

  • 맨 아래 5.53M가 알파인 리눅스의 베이스 이미지

  • 그리고 위에서 4번째 79.4M가 JRE 설치

  • 위에서 2번째가 33.8M로, 애플리케이션 파일 Jar을 복사한 내용

으로 확인할 수 있다. 계층은 여러개이지만, 주로 용량을 많이 사용하는 이미지는 이 3개의 계층임을 확인할 수 있다.

 

이 컨테이너에서 애플리케이션을 다시 컴파일 하고 패키징해서 push를 해보면 아래와 같이 33.82M에 해당하는 애플리케이션 Jar 만을 복사하고 나머지는 “Layer already exist”와 함께 별도로 레이어를 푸쉬하지 않는 것을 확인할 수 있다. 

 

도커 컨테이너는 효과적인 배포를 위해서 pull/push 시에, 레이어별로 캐슁을 해서, 변경이 없는 레이어에 대해서는 다시 pull/push를 하지 않는다

자바 애플리케이션을 여러개의 레이어로 나눈 경우

이 레이어별 캐슁 기능을 잘 활용하면, 애플리케이션 컨테이너의 push/pull 시간을 많이 단축시킬 수 있다. 첫번째 push/pull은 전체 이미지를 올려야하기 때문에 시간 차이는 없겠지만, 그 후 애플리케이션만을 업데이트할 경우에는 애플리케이션에 관련된 파일만 실제로 복사되도록하고, 나머지 레이어는 캐슁된 이미지를 사용하도록 하는 방법이다.

 

Springboot와 같은 자바 애플리케이션은 애플리케이션 파일은 /classes에 저장되지만, 나머지 참조하는 여러 jar 파일들이 있다. 이러한 jar 파일들은 변경이 없기 때문에, 다시 재배포할 필요가 없기 때문에 캐슁을 하도록 하는 것이 좋다.

 

그러나 앞의 예제에서는 이 모든 라이브러리 jar 파일들을 하나의 app.jar 에 묶어서 복사하는 구조이기 때문에, 라이브러리 jar 파일만을 별도로 캐슁할 수 없다. 

그래서, 아래와 같이 애플리케이션 jar 파일을 푼 다음에, 각각의 디렉토리를 별도로 복사하는 방법을 사용한다. mvn package 에 의해서 생성된 jar 파일을 target/depdency 라는 디렉토리에 풀고, 각 디렉토리를 Dockerfile에서 각각 복사하도록 설정하였다. 

 

FROM openjdk:8-jre-alpine

ARG DEPENDENCY=target/dependency

COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib

COPY ${DEPENDENCY}/META-INF /app/META-INF

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

COPY ${DEPENDENCY}/BOOT-INF/classes /app

COPY ${DEPENDENCY}/org /org

 

ENTRYPOINT ["java","-cp","app:app/classes/*","com.terry.HellospringApplication"]

 

이렇게 하게 되면, 사용자가 작성한 코드는 /classes 에 컴파일 된 상태로 저장되고, 나머지 라이브러리들은 /BOOT-INF/lib  등의 디렉토리에 저장된다. 이를 각각 Dockerfile에서 COPY 명령으로 복사하게 되면 별도의 레이어로 생성된다. 

아래는 위의 Dockerfile을 이용해서 빌드한 이미지의 레이어이다. 

 

 

앞의 예제의 경우 애플리케이션 jar 파일이 33.82M의 단일 레이어로 생성되었지만, 이 컨테이너는 176k,1.34k,1.84k,16.7M  4개의 레이어로 생성된것을 확인할 수 있다. 

 

 

 

이중에서 1.84k,16.7M 레이어는 Springboot 라이브러리이기 (jar파일) 때문에 변경이 없다. 그래서 캐슁이 가능한데, 

 

아래는 이 컨테이너를 한번 등록해놓고, 그 다음 애플리케이션 코드를 변경해서 새로 빌드하고 푸슁하는 과정이다. 

 

보는 것과 같이 위의 2 레이어만 새롭게 푸슁되는 것을 확인할 수 있다. 

이렇게 하면, 아래 OS 레이어, JRE, 그리고 Spring boot의 jar 라이브러리들은 모두 캐슁되고, 배포시에는 실제로 애플리케이션 class 파일만 전송되게 되기 때문에 배포 시간을 많이 단축할 수 있다.

 

이때 주의 할점은 기존 디렉토리에

BOOT-INF/classes

BOOT-INF/lib

META/lib

org

 

이런 디렉토리들이 있는데, mvn으로 새롭게 jar를 빌드한후 target/dependecy 파일에 전체 파일을 풀어버리게 되면 4개의 디렉토리가 모두 업데이트가 된다. BOOT-INF/lib,META/lib,org 디렉토리의 실제 파일 내용이 변경이 되지 않았다 하더라도, 새로운 파일로 업데이트하였기 때문에, 파일의 해쉬값이 변경되게 되고, Docker 는 빌드시에, 이 디렉토리가 변경이 되었다고 판단하고 기존의 캐슁된 레이어를 재활용하지 않고 새롭게 레이어를 생성해서 push 하기 때문에, 실제 캐쉬 효과를 볼 수 없다. 

그래서 빌드 과정에서 기존에 변경되지 않은 파일과 디렉토리는 건들지 않고, 변경된 파일만 업데이트 하도록 빌드를 구성해야 한다. 

 

여기서는 자바 애플리케이션을 기준으로 설명하였지만, Javascript나, 이미지와 같은 정적 파일이 있거나 라이브러리나 드라이브 설치등의 중복되는 부분이 많은 애플리케이션의 경우에는 같은 원리로 각각 레이어를 나눠 놓으면, 캐슁을 통한 push/pull 속도 절약의 효과를 볼 수 있다.

 

예제 파일은 스프링부트 홈페이지를 참고하였습니다. :)



출처: https://bcho.tistory.com/1357?category=731548 [조대협의 블로그]

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
206 [MSA][Docker][Kubernetes] [Kubernetes] 윈도우10에 도커, 쿠버네티스 설치 (docker desktop) file 졸리운_곰 2021.05.23 32
205 [C/C++, graphics] SDL Tutorial Basics 졸리운_곰 2021.05.15 51
204 C++ Simple BOOST Asynchronous ASIO Reverse Proxy file 졸리운_곰 2021.05.10 21
203 [MSA] [Docker] Docker File을 이용하여 Docker Image만들기 file 졸리운_곰 2021.04.27 28
202 [MSA][Docker] Docker 개념, 관리, 이미지생성까지 한번에!! file 졸리운_곰 2021.04.27 64
201 [죽기전에 경험해봐야 하는 미니 코어 리눅스 5가지] 5 tiny Linux distros to try before you die file 졸리운_곰 2021.04.25 14
200 [C/C++ 자료구조] 5일만에 뚝딱 스크립트 언어 만들기 PGLight (1/5) file 졸리운_곰 2021.04.12 23
199 [linux] vi 단축키 정리 / vim 학습자료 file 졸리운_곰 2021.04.04 42
198 [linux] VIM Editor 단축키 / 명령어 모음 졸리운_곰 2021.04.04 44
197 [MSA] 서비스 경량화를 위한 MSA 설계 시 고려사항 file 졸리운_곰 2021.03.21 72
» [MSA][Docker] 효율적인 도커 이미지 만들기 #2 - 도커 레이어 캐슁을 통한 빌드/배포 속도 높이기 file 졸리운_곰 2021.03.21 22
195 [MSA][Docker] 효율적인 도커 이미지 만들기 #1 - 작은 도커 이미지 file 졸리운_곰 2021.03.21 25
194 [MSA] 오픈소스 모니터링 툴 - Prometheus #3 그라파나를 이용한 시각화 file 졸리운_곰 2021.03.21 186
193 [MSA] 오픈소스 모니터링 툴 - Prometheus #2 Hello Prometheus file 졸리운_곰 2021.03.21 27
192 [MSA] 오픈소스 모니터링툴 - Prometheus #1 기본 개념과 구조 file 졸리운_곰 2021.03.21 70
191 [MSA] API 게이트 웨이 & Google Cloud Endpoints file 졸리운_곰 2021.03.21 26
190 [MSA] Kong API gateway #3 - Kong on Kubernetes file 졸리운_곰 2021.03.21 45
189 [MSA] Kong API gateway #2 - 간단한 아키텍쳐와 API 테스트 file 졸리운_곰 2021.03.21 35
188 [MSA] Kong API gateway #1 - 설치와 둘러보기 file 졸리운_곰 2021.03.21 167
187 [MSA] Istio Traffic management file 졸리운_곰 2021.03.21 26
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED