본문 바로가기
Gradle

[Gradle] Jib Build 에 대해서 알아보자

by 곰민 2024. 3. 31.
728x90

Gradle Jib Build를 활용한 Image Build를 Jenkins를 활용해서 사용하고 있다.
Jib을 활용한 Image Build가 갖는 장점과 속도점 이점에 대해서 한번도 확인해 본 적이 없어서 이번 기회해 한번 정리하면서 확인해 보았다.


gradle 은 jib으로 어떻게 image를 잘 말고 있을까?

Jib 이란?


Jib은 Docker 데몬 없이 Java 애플리케이션을 컨테이너화하여 Docker Hub, Google Container Registry 등 원하는 레지스트리로 직접 푸시할 수 있는 Gradle 및 Maven 플러그인.
애플리케이션을 빌드함과 동시에 컨테이너 이미지를 생성하고 푸시까지 할 수 있게 하여, 빌드와 Dockerfile 작성 과정을 단일화하는 파이프라인을 제공.

 

간략하게 미리 보는 Jib 의 주요 장점


 

1. 간편함(Simple and Demonless) : Java로 구현 되며 Maven or Gradle Build의 일부로 실행.
  DockerFile 유지, Docker 데몬 실행, Fat 한 Jar를 Build 할 걱정을 할 필요가 없음.
2. 속도 (Fast) : Jib은 Image layering , Registry caching 를 활용하여 빠르게 빌드함.
   image layering : dependencies, resources, classes로 layer 나누고 변경 부분만 Rebuild 함.
3. Reproducible : Jib으로 생성된 컨테이너 이미지는 동일한 콘텐츠로 다시 빌드할 경우 항상 동일한 결과를 생성 한다는 것.

 

 

DockerFile을 사용한 Image 생성과의 차이점


출처:https://cloud.google.com

 

전통적인 Dockerfile 기반의 빌드 프로세스는 일반적으로 전체 Java 애플리케이션을 하나의 JAR 파일로 빌드하여 단일 이미지 레이어로 처리.
이러한 접근 방식은 Docker의 레이어 캐싱 기능을 충분히 활용하지 못하며, 애플리케이션의 소스 코드에 작은 변경이 발생하더라도 전체 JAR 파일을 다시 빌드하고 재배포해야 하는 단점이 존재.

 

그렇다면 Container Layering 은 어떤 식으로 할까? 🤔

Container LayerIng

출처:https://towardsdatascience.com/docker-storage-598e385f4efe

 

Docker Build 시 DockerFile의 각 명령어에 대해 하나의 레이어를 빌드를 하기 시작.
이러한 이미지 Layer 는 ReadOnly 임.
 
Docker Run시 에는 Container Layer를 Build 하기 시작함. (Read/Write 가능한)

 

출처:https://towardsdatascience.com/docker-storage-598e385f4efe

 

Container에 test.txt 라는 새로운 파일을 생성, 수정, 할 수 있음.
이렇게 되면 해당 파일의 로컬 복사본이 Container Layer에 생성되고 변경사항은 Container Layer에 만 적용되며 Copy-On-Write라고 불림.
데이터를 유지하기 위해서는 Volumn 을 활용할 수 있으며 그게 아니라면 파일은 컨테이너가 죽으면 사라지게 됨.

동일한 이미지에서 일관된 환경을 보장할 수 있음.

 

Docker 빌드는 레이어 캐싱을 활용하여 후속 빌드 속도를 높임.
그러나 레이어 캐싱 메커니즘은 제한될 수 있는데, 애플리케이션 코드가 변경되거나 Docker파일 외부의 종속성이 변경되는 경우 Docker 빌드는 모든 레이어를 다시 빌드하는 방식으로 빌드 시간이 느려질 수 있음.
(일부가 수정되었으나 jar file을 build 하고 image를 만드는 case)

 

당연히 Docker Layer 순서도 자주 변경되지 않는 레이어가 하단인 것이 좋음.
하위 수준에 Layer의 변경으로 인한 상위 수준의 Layer 재빌드가 생길 수 있기 때문.

 

 

Jib은?


 

 

출처:https://cloud.google.com

 

Jib은 크게 보면 일단 Jar File Build 후 Docker Daemon을 통해서 Docker Context기반의 Docker Image 생성 후 Push 하는 과정을 거치지 않고.
Jib 명령어를 통해서 설정된 Registry로 Image Push 가 가능함.

 

Jib은 Project 구성정보를 기반으로 OCI(Open Container Initiative) 호환 이미지를 생성하며 DockerFile이 필요하지 않고 Docker Daemon이 필요하지 않음.

즉 Image를 생성하기 위해서 DockerDaemon이 실행되고 있을 필요가 없음.

Jib은 Java 애플리케이션을 위한 이미지 레이어를 직접 구성하고, OCI 표준에 맞게 이미지를 레지스트리에 푸시함.

 

Jib Image

 

distroless

https://github.com/GoogleContainerTools/distroless

 

GitHub - GoogleContainerTools/distroless: 🥑 Language focused docker images, minus the operating system.

🥑 Language focused docker images, minus the operating system. - GitHub - GoogleContainerTools/distroless: 🥑 Language focused docker images, minus the operating system.

github.com

 

Distroless image(language Focused 한 Basic Image(java, python....)) 로 applicationLayer를 구성함.
Distroless image 활용 시 필수 런타임과 애플리케이션 코드만 포함되어 이미지의 크기를 줄이고 보안을 강화할 수 있음.

 

 

간단하게 알아보는 일반 적으로 권장하는 경량 한 Linux Base Image Alphine 과의 비교


Distroless vs Alphine

기준 Distroless Alpine
기본 구성 최소한의 파일만 포함 경량화 된 Linux 배포판
목적 보안 강화, 이미지 크기 축소 작은 크기, 확장성, 기본 쉘 및 패키지 관리자
사용 사례 애플리케이션 실행에 필요한 최소한만 포함 일반적인 용도의 경량 컨테이너 생성
쉘 및 도구 포함하지 않음 포함

 

Jib Speed

출처:https://www.youtube.com/watch?v=H6gR_Cv4yWI&ab_channel=GoogleCloudTech

 

위 그림을 보면 100MB의 Fat 한 Base Image Layer가 필요가 없고.
40MB의 Base를 갖고 9MB의 추가된 Layer를 가진 상태에서 1MB 가 수정 되었다면. 
실질 적으로 1MB의 변경한 layer 만 send 함으로 속도를 올리는 방식.

 

즉 코드 변경 시, 전체 애플리케이션이 아닌 변경된 부분만 재빌드하고 그 부분만을 컨테이너 이미지로 교체.
이는 레이어 별로 캐싱을 적용하여 변경된 부분만을 빌드하고 이미지로 배포하는 방식임.

 

어떻게?? 🤔

 

Jib은 Jar File를 하나의 Layer로 두는 것이 아닌,
Java 애플리케이션을 여러 레이어로 분리하여 빌드함.

dependencies, resources, classes

 

아래는 Jib이 Build를 Optimized 하는 예시.

FROM gcr.io/distroless/java
COPY target/dependencies /app/dependencies
COPY target/resources  /app/resources
COPY target/classes  /app/classes
ENTRYPOINT java -cp /app/dependencies/*:/app/resources:/app/classes test.app.Main

 

예를 들면 의존성이 변경되지 않았다면 의존성 레이어는 재빌드 되지 않고 오직 리소스나 클래스만 빌드되어 푸시됨.

출처 : https://www.youtube.com/watch?v=H6gR_Cv4yWI&ab_channel=GoogleCloudTech

 

Single Layer Build (Ex: Jar)와 Build 속도를 비교했을 때 Rebuild 시점에서 많은 차이가 나는 것을 확인할 수 있다.

 

출처 : https://www.youtube.com/watch?v=H6gR_Cv4yWI&ab_channel=GoogleCloudTech

 

당연히 Resource 가 많은 큰 사이즈의 application의 경우 그 차이가 더 명확하게 드러난다.

 

Jib은 어떻게 Reproducible를 보장해줄 까?


 

Reproducible은 Same Code일 경우 언제나 Same Image를 제공하는 것을 의미한다.

 

어떻게?

Jib은 빌드 간에 변할 수 있는 모든 메타데이터(예: 타임스탬프, 사용자 ID, 그룹)를 제거하여 Reproducible Builds를 보장함.
빌드가 언제 어디서 수행되든 동일한 소스 코드에서 항상 동일한 이미지 결과를 생성.

 

Quick Start


Build 한 Image 를 Push 하는 저장소가 다양하기 때문에 (GCR, ECR, Docker Hub, JCR, ACR)

원하는 환경에 맞춰서 설정 할 수 있도록 Quick Start 가이드 링크를 첨부한다.

 

https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#quickstart

 

jib/jib-gradle-plugin at master · GoogleContainerTools/jib

🏗 Build container images for your Java applications. - GoogleContainerTools/jib

github.com

 

 

참고 링크


https://cloudplatform.googleblog.com/2018/07/introducing-jib-build-java-docker-images-better.html
https://towardsdatascience.com/docker-storage-598e385f4efe
https://jh-labs.tistory.com/509

https://www.youtube.com/watch?v=H6gR_Cv4yWI&ab_channel=GoogleCloudTech

https://contact-rajeshvinayagam.medium.com/build-containers-with-jib-simplify-containerization-workflow-da5f3d192e64

 

 

728x90

댓글