개요
- 도커 이미지 크기를 줄일 수 있는 방법에 대해 찾아본다.
- 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
...

결과

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

'CICD' 카테고리의 다른 글
[Skaffold] JIB Sync (0) | 2024.01.04 |
---|