click-me프로젝트에서 github action으로 CD를 구현중에 Container Image를 만들때 Dockerfile을 통해 jar 파일을 바탕으로 이미지를 생성했다.
FROM openjdk:17-jdk
EXPOSE 8080
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod" ,"/app.jar"]
Dockerfile의 구조는 간단하다. 해당 jar 파일을 바탕으로 Image를 생성하는 것이다.
그리고 그렇게 생성한 이미지를 gcp Artifact registry에 push하기 위해 tag를 달고 push를 하는 github action yml파일을 작성했다.
- name: Docker Build
run: ../gradlew docker
- name: Docker tag
run: docker tag click-me-${{env.WORKSTATION_IMAGE}}:${{env.VERSION}} ${{env.IMAGE}}
- name: Docker Push
run: docker push ${{env.IMAGE}}
정의한 내용은 아래와 같다.
docker {
println(tasks.bootJar.outputs.files)
name rootProject.name+'-'+project.name + ":" + version
dockerfile file('./Dockerfile')
files tasks.bootJar.outputs.files
buildArgs(['JAR_FILE': tasks.bootJar.outputs.files.singleFile.name])
}
이렇게 생성한 docker image의 용량이 거의 600mb를 차지했다.
이러한 문제를 해결하기 위해 layer를 나누어 image를 빌드하는 방법도 있지만 손쉽게 하기 위해 jib를 사용해 보기로 했다.
Jib는 Dockerfile을 사용하지 않거나 Docker를 설치할 필요 없이 컨테이너를 빌드합니다. Maven 또는 Gradle용 Jib 플러그인에서 Jib를 사용하거나 Jib 라이브러리를 사용할 수 있다.
그리고 세가지 목표를 가지고 있다.
Jib는 애플리케이션을 종속 항목, 리소스, 클래스 등 별개의 레이어로 구성하고 Docker 이미지 레이어 캐싱을 활용하여 변경사항만 다시 빌드함으로써 빌드를 빠르게 유지한다.
Jib 레이어 구성과 작은 기본 이미지는 전체 이미지 크기를 작게 유지하여 성능과 휴대성을 향상시킨다.
plugins {
...
id 'com.google.cloud.tools.jib' version '3.4.0'
}
jib {
from {
image = "eclipse-temurin:17-jre-alpine@eclipse-temurin@sha256:635ec1b177ac2a587324ed5eda2b9dec197876e16d10c35a4ef9595d76c2c891"
}
to {
image = "asia-northeast3-docker.pkg.dev/sanguine-theory-406607/clickme/transfer-service:latest"
}
container {
jvmFlags = ["-Xms258m", "-Xmx1024m"]
environment = [
'REDIS_HOST': System.getenv('REDIS_HOST'),
'REDIS_PORT': System.getenv('REDIS_PORT'),
'DATASOURCE_URL': System.getenv('DATASOURCE_URL'),
'DATASOURCE_USERNAME': System.getenv('DATASOURCE_USERNAME'),
'DATASOURCE_PASSWORD': System.getenv('DATASOURCE_PASSWORD'),
'SPRING_PROFILES_ACTIVE': 'prod'
]
filesModificationTime = 'EPOCH_PLUS_SECOND'
}
}
도커계정/레포지토리이름
과 같은 형식일 것이다../gradlew jib
해당 명령어만 실행하면 이미지를 빌드한 후 build.gradle에 정의했던 레지스트리에 자동으로 푸시한다.
to {
image = "asia-northeast3-docker.pkg.dev/sanguine-theory-406607/clickme/click-service:latest"
}
이렇게 jib로 변경하고 나서 github action yml 파일에도 변화가 생겼다.
- name: Docker Build
run: ../gradlew docker
- name: Docker tag
run: docker tag click-me-${{env.WORKSTATION_IMAGE}}:${env.VERSION} ${{env.image}}
- name: Docker Push
run: docker push ${{env.image}}
- name: Docker Build
run: ./gradlew :click-service:jib
보는 바와 같이 github action yml파일도 간략해 졌다.
그렇다면 속도에는 어떤 변화가 생겼을까?
기존 Dockerfile로 했을때 Build, tag, push까지 총 57초가 걸렸다.
jib로 변경한 후 24초로 줄어든 것을 확인할 수 있다. 이렇게 속도가 줄어든 이유는 위에 잠깐 언급했듯이 애플리케이션을 종속 항목, 리소스, 클래스 등 별개의 레이어로 구성하고 Docker 이미지 레이어 캐싱을 활용하여 변경사항만 다시 빌드함으로써 빌드를 빠르게 유지한다.
이 이유때문이다.
그러면 jib가 layer를 어떻게 캐싱을 하는 것일까?
jib를 실행하면 {project dir}/build/jib-cache에 layer들이 저장된다.
그리고 jib가 기본적으로 {project dir}/build/jib-cache를 바라보도록 설정되어 있어서 여기에 있는 layer들을 캐싱한다.
처음에 github action으로 했을 당시 로컬환경과 다르기때문에 레이어 캐싱이 정상적으로 동작하지 않았다.
그 이유는 캐싱할 대상이 없기 때문이다. 따라서 github action에서 캐싱을 따로 설정해 둬야 한다.
cache actions를 활용하여 해결했다.
- name: Cache Jib layers
uses: actions/cache@v3
with:
path: ./click-service/build/jib-cache
key: ${{ runner.os }}-jib-${{ github.job }}-${{ hashFiles('**/build.gradle') }}
restore-keys: ${{ runner.os }}-jib-${{ github.job }}
위와 같이 캐싱설정을 하지 않았을 때는 47초 걸렸던 빌드 작업이 캐싱 설정 이후에 24초로 줄어들었다.
총 줄어든 시간을 살펴보면 2분 10초 걸리던 작업이 54초로 줄어들었다.
Spring Batch 파티셔닝 적용후 JVM이 종료되지 않는 문제 해결 (0) | 2024.05.03 |
---|---|
Redis의 클릭 카운트 MySQL로 데이터 동기화 (2) (0) | 2023.12.22 |
Redis의 클릭 카운트 MySQL로 데이터 동기화 (1) (0) | 2023.12.15 |
Docker와 Kubernetes를 이용한 GKE 환경에서의 CI/CD 구현 (0) | 2023.12.05 |
github에서 README.md이미지 업데이트 문제: Camo와 캐싱 이슈 해결하기 (0) | 2023.10.20 |