17.3.이미지 레이어 수와 이미지 크기는 최소한으로

  • 애플리케이션 이미지 최적화에서 꼭 필요한 것만 포함하는 이미지를 만드는 것이다.
  • 소프트웨어를 설치하면 패키지 목록을 캐싱하거나 추천 패키지 등을 함께 설치하기 때문에 대부분의 경우 불필요한 요소나 설치 후 잔재가 발생한다.
  • 세부적인 내용은 운영체제나 소프트웨어에 따라 다르지만, 기본적인 원칙은 크게 다르지 않다.

실습 데비안 리눅스는 소프트웨어를 설치할 때 패키지 매니저인 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
  1. 004: 최초 버전과 v2 버전의 Dockerfile을 사용해 이미지를 빌드했다. v2 버전에는 압축 해제와 관련한 최적화가 적용됐다.
  2. 018~019: 최적화된 v2 버전의 이미지가 용량이 무려 2.46GB나 적다.

  3. 디버깅 편의를 위해 인스트럭션을 분할해 두고 개발 작업을 진행하는 경우는 흔하다.

  4. 인스트럭션을 분할해 두면 중간 단계의 레이어로도 컨테이너를 실행할 수 있기 때문에 내려받은 파일을 캐시에 저장한 상태로 이후 인스트럭션을 작성할 수 있다.
  5. 하지만 인스트럭션이 하나로 합쳐져 있었다면 매번 파일을 다시 내려받아야 했을 것이다.
  6. 그래도 작업이 끝난 후에는 다시 최적화를 해 두어야 한다.

예제 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 의 디스크 용량이 여기에 쓰였다) 불필요한 파일을 삭제했다.

links

social