- 애플리케이션 이미지 최적화에서 꼭 필요한 것만 포함하는 이미지를 만드는 것이다.
- 소프트웨어를 설치하면 패키지 목록을 캐싱하거나 추천 패키지 등을 함께 설치하기 때문에 대부분의 경우 불필요한 요소나 설치 후 잔재가 발생한다.
- 세부적인 내용은 운영체제나 소프트웨어에 따라 다르지만, 기본적인 원칙은 크게 다르지 않다.
실습 데비안 리눅스는 소프트웨어를 설치할 때 패키지 매니저인 APT(Advanced Package Tool)를 사용한다. 이번 실습은 불필요한 패키지를 제거해 패키지 목록을 정리하면 이미지 크기를 얼마나 많이 줄일 수 있는지 확인하기 위한 것이다
➜ cd ch17/exercises/socat
# v1 이미지에서는 평범하게 apt-get 명령으로 패키지를 설치했다
➜ docker image build -t diamol/ch17-scoat:v1 .
# v2 이미지에서는 똑같은 패키지를 설치했지만 패키지 관리자에 최적화 옵션을 줬다
➜ docker image build -t diamol/ch17-scoat:v2 -f Dockerfile.v2 .
# 두 이미지의 크기를 비교한다
➜ docker image ls -f reference=diamol/ch17-scoat
- 패키지 설치 명령에 몇 가지 조정을 가했을 뿐인데 이미지 크기를 20MB 정도까지 줄였다.
- 하나는 apt에서 추천 패키지를 설치하지 않는 옵션을 사용한 것이고, 다른 하나는 설치 단계를 설치 후 패키지 목록의 캐시도 삭제하는 단계까지 하나의 RUN 인스트럭션으로 합친 것이다.
예제 17-3 패키지 설치를 통한 최적화 - 좋은 예와 나쁜 예
# Dockerfile - 일반적인 방식으로 API를 사용함
FROM debian:stretch-slim
RUN apt-get update
RUN apt-get install -y curl=7.52.1-5+deb9u16
RUN apt-get install -y socat=1.7.3.1-2+deb9u1
# Dockerfile.v2 패키지 설치 과정을 최적화함
FROM debian:stretch-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl=7.52.1-5+deb9u16 \
socat=1.7.3.1-2+deb9u1 \
&& rm -rf /var/lib/apt/lists/*
- 인터넷에서 압축된 패키지를 내려받아 압축을 해제한 후 설치하는 경우가 많다.
- 별도의 인스트럭션으로 파일을 내려받는다면 스크립트 작성 자체는 편하겠지만, 나중을 위해 다운로드 -> 압축 해제 -> 삭제까지의 단계를 모두 하나의 인스트럭션에서 수행하도록 하는 것이 좋다.
실습 머신 러닝 데이터 집합이 그러한 좋은 예다. 이들 데이터는 내려받는 용량이 크고 압축을 해제하면 더 큰 용량의 디렉터리 구조가 생기기 때문이다. 이번 실습은 캘리 포니아 주립대학교 어바인 캠퍼스(UCI)에서 배포하는 데이터 집합 압축 파일을 내려받는 에제다.
001) ➜ cd ch17/exercises/ml-dataset
002)
003) # v1에서는 압축 파일을 내려받고 압축을 해제한 다음 불필요한 파일을 제거했다
004) ➜ docker image build -t diamol/ch17-ml-dataset:v1 .
005) [+] Building 42.3s (10/10) FINISHED
006) => exporting to image 3.6s
007) => => naming to docker.io/diamol/ch17-ml-dataset:v1 0.0s
008)
009) # v2에서는 압축 파일을 내려받는 것은 같지만 필요한 파일만 압축을 해제했다
010) ➜ docker image build -t diamol/ch17-ml-dataset:v2 -f Dockerfile.v2 .
011) [+] Building 44.6s (7/7) FINISHED
012) => exporting to image 0.0s
013) => => naming to docker.io/diamol/ch17-ml-dataset:v2 0.0s
014)
015) # 이미지 크기를 비교한다
016) ➜ docker image ls -f reference=diamol/ch17-ml-dataset
017) REPOSITORY TAG IMAGE ID CREATED SIZE
018) diamol/ch17-ml-dataset v2 2b6773b1ae67 30 seconds ago 25.3MB
019) diamol/ch17-ml-dataset v1 1d7eb798b9fb About a minute ago 2.48GB
- 004: 최초 버전과 v2 버전의 Dockerfile을 사용해 이미지를 빌드했다. v2 버전에는 압축 해제와 관련한 최적화가 적용됐다.
-
018~019: 최적화된 v2 버전의 이미지가 용량이 무려 2.46GB나 적다.
-
디버깅 편의를 위해 인스트럭션을 분할해 두고 개발 작업을 진행하는 경우는 흔하다.
- 인스트럭션을 분할해 두면 중간 단계의 레이어로도 컨테이너를 실행할 수 있기 때문에 내려받은 파일을 캐시에 저장한 상태로 이후 인스트럭션을 작성할 수 있다.
- 하지만 인스트럭션이 하나로 합쳐져 있었다면 매번 파일을 다시 내려받아야 했을 것이다.
- 그래도 작업이 끝난 후에는 다시 최적화를 해 두어야 한다.
예제 17-4 압축 파일을 다루는 최적화 기법
# v1
FROM diamol/base
ARG DATASET_URL=https://archive.ics.uci.edu/ml/machine-learning-databases/url/url_svmlight.tar.gz
WORKDIR /dataset
RUN wget -O dataset.tar.gz ${DATASET_URL} && \
tar xvzf dataset.tar.gz
WORKDIR /dataset/url_svmlight
RUN cp Day1.svm Day1.bak && \
rm -f *.svm && \
mv Day1.bak Day1.svm
# v2
FROM diamol/base
ARG DATASET_URL=https://archive.ics.uci.edu/ml/machine-learning-databases/url/url_svmlight.tar.gz
WORKDIR /dataset
RUN wget -O dataset.tar.gz ${DATASET_URL} && \
tar -xf dataset.tar.gz url_svmlight/Day1.svm && \
rm -f dataset.tar.gz
- 디스크 용량이 가장 많이 절약되는 부분은 압축 파일을 삭제해서가 아니라 필요한 파일만 압축을 해제하기 때문이다.
- v1 버전에서는 전체 압축 파일을 압축 해제한 다음(2GB 의 디스크 용량이 여기에 쓰였다) 불필요한 파일을 삭제했다.