티스토리 뷰
[Spring Boot] Container image 만들기 !
KimDoubleB 2021. 6. 24. 23:46이 글에서는 Spring boot 프로젝트를 Container image로 만드는 법에 대해 알아보겠습니다.
Spring Boot 공식문서에서는 2가지 방법을 소개하고 있습니다.
1. Dockerfiles
2. Cloud Native Buildpacks
이 2가지 방법에 대해 자세히 살펴보도록 하죠!
Dockerfiles
일반적으로 container image로 만들 때 활용하는 Dockerfile을 정의해 사용하는 방법
Spring project의 결과물을 container image로 만들 때, 아주 간단히 Dockerfile 을 작성하면 다음과 같이 작성할 수 있습니다.
- Gradle인 경우, ./gradlew bootJar 을 통해 쉽게 jar로 패키징할 수 있습니다.
- 패키징 이후, docker build 명령어를 통해 도커 이미지를 만들 수 있습니다.
FROM openjdk:11-jre-slim
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
위 Dockerfile 대로 동작하면 이상은 없겠지만, 프로젝트가 커질 수록. 즉, 의존성 및 코드의 양이 증가되어 jar 파일이 무거워질수록 Container image를 만드는 시간이 오래걸리게 됩니다.
Docker는 layer를 활용하여 기존 layer가 local에 있으면 재사용하는 식(캐쉬)으로 진행되어 효율화를 이룬 아키텍처를 가지고 있 는데, 위 Dockerfile처럼 구성하면 Java의 모든 구조가 jar 파일로 되는 것이기 때문에 layer를 재사용하기 어렵습니다. 다시 말해서, 코드를 한 줄이라도 수정하게 되면 캐쉬 해놓은 layer를 사용할 수 없기 때문에 다시 만드는 작업이 필요하게 됩니다.
이러한 문제를 해결하기 위해서 layering feature를 사용합니다. 쉽게 말하면 하나로 이루어졌던 구조를 4개의 Layer로 나눔으로써 변경이 적은 부분은 캐싱된 것을 사용하게 만들고, 변경이 잦은 부분만을 새로 구축해 효율적으로 container image를 만들 수 있는 방법입니다.
4개의 Layer는 아래의 표의 4가지로 구성되어져 있습니다.
- dependencies가 제일 변경이 적고, application이 제일 변경이 잦은 부분이라고 보시면 됩니다.
그럼, 이제 jar 파일을 위의 4가지 Layer로 분리해보도록 하겠습니다. 아래의 명령어를 통해 jar 파일을 4개의 layer로 분리할 수 있습니다.
$ java -Djarmode=layertools -jar my-app.jar extract
이제 이 분할한 layer를 Dockerfile에서 사용한다면, 다음과 같이 작성할 수 있습니다.
FROM adoptopenjdk:11-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM adoptopenjdk:11-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
docker build 명령어를 통해 Optimized container image를 생성해낼 수 있습니다.
Cloud Native Buildpacks
위 방식처럼 Dockerfile을 직접 만들어 Container image를 생성할 수 있지만 최근에는 Maven, Gradle에서 바로 Container image를 생성할 수 있도록 방법을 제공하고 있습니다. 즉, Dockerfile을 정의할 필요 없이 어디서든 실행할 수 있도록 Container image를 만들 수 있도록 지원하고 있는 것입니다. 그게 바로 Buildpack 입니다.
Cloud Native Buildpacks은 어플리케이션 코드를 어느 클라우드에서나 돌아갈 수 있도록 이미지로 전환을 해주는 기술입니다.
Cloud Native Buildpacks transform your application source code into images that can run on any cloud.
위에서 직접 Dockerfile로 생성하는 것처럼 효율적으로 Container image를 생성해줍니다.
Buildpack은 CNCF 프로젝트 중 하나로 표준의 기술의 하나로 인정받고 있습니다.
Maven
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- mvn spring-boot:build-image
Gradle
- ./gradlew bootBuildImage
bootBuildImage 에서는 여러 파라미터를 추가해 여러 설정들을 바꿀 수 있습니다.
- https://docs.spring.io/spring-boot/docs/2.5.0/gradle-plugin/reference/htmlsingle/#build-image.examples.builder-configuration
- Spring native 문서에서도 Container image 생성 시, bootBuildImage를 사용하고 있는데요. builder 옵션을 통해 base image를 변경할 수도 있습니다.
'Development > Java, Kotlin, Frameworks' 카테고리의 다른 글
[JPA] 영속성 전이 CASCADE (0) | 2021.08.09 |
---|---|
Java vm -Xmx -Xms option (2) | 2021.06.30 |
Maven Profile 설정 (0) | 2021.06.04 |
[Spring Reactive] WebClient (2) | 2021.04.24 |
Intellij GET/POST HTTP (0) | 2021.04.10 |
- Total
- Today
- Yesterday
- gradle
- 쿠버네티스
- Istio
- 로그
- tag
- container
- MySQL
- Kubernetes
- boj
- java
- WebFlux
- Spring
- Algorithm
- docker
- python
- Intellij
- 백준
- HTTP
- 하루
- 비동기
- jasync
- Clean Architecture
- 일상
- k8s
- hexagonal architecture
- Spring boot
- Log
- 알고리즘
- 클린 아키텍처
- c++
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |