CICD

[skaffold] Docker image 크기 및 빌드 시간 줄이기

dongb 2024. 1. 4. 16:51
반응형

개요

  1. 도커 이미지 크기를 줄일 수 있는 방법에 대해 찾아본다.
  2. skaffold dev 명령어로 이미지 초기 생성시 필요한 패키지를 설치하는 과정이 빌드 과정의 많은 시간을 차지하는 문제가 있어 이를 줄일 수 있는 방법에 대해 찾아본다.

기술 스택

  • Docker Multi stage build
  • Docker Buildkit in Skaffold
  • Python Wheel

 

구현 방법

Multi stage build 및 buildKit 사용

도커 이미지를 빌드 할 때 소스 코드만 변경해도 필요한 패키지들을 모두 설치하는 과정이 포함되어 빌드 시간이 길게는 15초까지 소모됐다. 이를 해결하기 위해 Docker에서 지원하는 Multi stage build 및 buildKit을 사용한다.
Multi stage build란 하나의 Dockerfile에 여러 이미지를 정의하고, 이미지끼리 결과물을 복사할 수 있는 기능이다.
BuildKit은 변경 내용과 관련 없는 stage를 캐시 처리 해주고 stage간 빌드 병렬 처리를 지원하는 기능이다.
(BuildKit VS Legacy builder)

Docker 공식 문서

BuildKit

Introduction and overview of BuildKit

docs.docker.com

Multi-stage builds

Learn about multi-stage builds and how you can use them to improve your builds and get smaller images

docs.docker.com

 
이를 사용하면 중간 이미지들은 최종 이미지에 포함되지 않으므로 용량을 줄일 수 있다. 또 중간 이미지를 캐시 처리 할 수 있기 때문에 빌드 시간도 줄일 수 있다.
예를 들어 개발환경, 배포환경 각각 이미지를 하나씩 만들고, 개발환경에서는 컴파일러 등 빌드에 필요한 패키지들을 설치하고 이미지를 빌드한다. 배포용 이미지에서는 깨끗한 OS 이미지에 개발환경 이미지로부터 빌드된 바이너리 파일만 복사해오는 형태로 용량을 줄일 수 있다.
 
아래 예시에서는 필요한 패키지들을 base 이미지에서 wheel 확장자로 설치하고, runtime 이미지에서는 wheel 패키지들을 복사해서 설치한 후 소스 코드를 복사한 뒤 실행시킨다.

ARG WHEEL_DIST="/tmp/wheels"

# Install requirements as wheel
FROM python:3.9-slim-buster AS base
ARG WHEEL_DIST
ENV PYTHONUNBUFFERED 1

# Install python pakcages 
COPY ./backend/requirements.txt .
RUN apt-get update \
    && pip install --upgrade pip  \
    && apt-get install -y libpq-dev gcc \
    && python3 -m pip wheel -w "${WHEEL_DIST}" -r requirements.txt \
    && rm -rf /var/lib/apt/lists/*

# Application runtime using installed wheel
FROM python:3.9-slim-buster AS runtime
ENV PYTHONUNBUFFERED 1
ARG WHEEL_DIST

# Load installed wheel
WORKDIR "${WHEEL_DIST}"
COPY --from=base "${WHEEL_DIST}" .
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && pip install --upgrade pip \
    && pip install --no-cache ./*

# Copy backend source
WORKDIR /backend
RUN mkdir -p /var/log/containers \
    && mkdir -p /backend
COPY ./backend /backend/

# Start this container with environment argument
...

적용 후 소스 코드를 변경하고 재빌드 하면 결과 화면처럼 패키지 설치 layer들은 캐시 처리 되고, 소스 변경과 관련된 layer만 실행되는 것을 볼 수 있다.

Python wheels: Python Wheels

 

Base image 경량화 및 캐시 처리

도커 이미지 크기 중 대부분은 base image인 python 3.9와 패키지를 설치하는 빌드 과정이 차지를 하고 있다.
먼저 python 3.9 대신3.9-slim-buster 버전을 사용하여 이미지 크기를 낮춘다.

또한 이미지를 빌드 할 때 base image를 캐시 처리하여 python 이미지를 불러오는 시간을 줄인다.

docker에서는 빌드 시 --cache-from 옵션을 사용하고, skaffold 에서는 build.artifacts.docker.cacheFrom 옵션을 사용한다.

apiVersion: skaffold/v2beta15
kind: Config
build:
  artifacts:
    - context: src
      image: backend
      docker:
        dockerfile: ./backend/Dockerfile.k8s
        target: runtime
        # target: runtime
        cacheFrom:
          - python:3.9-slim-buster
...

 
 

결과

 
소스 코드만 변경하여 빌드 할 경우 아래 로그에서 볼 수 있듯 소스 코드와 관련된 부분만 처리를 하고 패키지 설치 등과 같은 작업들은 캐시 처리된다.
 

반응형