ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Docker Image 경량화 방법 - 1부
    Programming/Docker 2023. 8. 8. 12:41
    반응형

    제가 사용하는 방식은 Develop Image의 용량이 너무 커서, 줄이는 방법을 고안하면서 터득했던 방법론을 공유하고자 합니다.

    실제 개발에 사용하고 있고, 많은 테스트를 진행한 결과입니다.

     

    3부작으로 나누었습니다.

    1부 일반적인 패키지 관리 방법

    2부 멀티스테이징 빌드

    3부 ENTRYPOINT를 활용한 마지막 경량화

     

    대부분 Deploy 이미지를 구축하는 방법에 대해서는 많은 레퍼런스가 있기 때문에 그런 부분부터 보고 오시면 조금 더 이해가 쉬울 수 있습니다.

     

    일단 Docker Image는 다수의 이미지 레이어의 결합체입니다.

    예를들어서, 이런 이미지와

    FROM ubuntu:20.04
    RUN apt-get update --yes
    RUN apt-get install --yes --no-install-recommends curl

    이런 이미지가 있다고 가정하겠습니다.

    FROM ubuntu:20.04
    RUN apt-get update --yes && \
        apt-get install --yes --no-install-recommends curl

     

    1번 이미지는 레이어가 2개이고, 2번 이미지는 레이어가 1개입니다.

    그러면 실제로 레이어가 Fix되는 부분은 apt-get install하고 나서가 레이어가 Fix가 됩니다.

    그러면 추후에 다른 레이어에서 기존에 만든 레이어에 있는 데이터를 삭제해도, 용량은 절대 줄어들지 않습니다.

    이게 중요 포인트입니다.

     

    그러면 실제로 deb 파일을 설치하는 과정에서 update를 하면 다운로드 가능한 패키지 목록을 가져오고,

    설치를 한다면 Dependency 패키지들이 Cache로 디스크에 남게 됩니다.

    설치까지 끝났으니, 대부분의 패키지들은 /usr/lib, /usr/bin 에 설치가 됩니다.

    실행할 바이너리 파일과 그 파일이 바라보는 패키지들이 설치가 되는거죠

     

    그럼 여기서 우리가 실제로 필요 없는 부분은 어떤 것일까요?

    바로 설치하고 나서 남아있는 설치 파일입니다.

    즉 대부분 apt로 설치하면 cache가 되는 위치는 /var/lib/apt/lists/* 입니다.

    이 부분은 있어봤자, 쓰이지도 않은 쓰레기가 되는거죠

     

    최종적으로는 패키지의 설치는 다음과 같이 작성하는 것이 레이어를 효율적으로 사용하는 방법입니다.

    FROM ubuntu:20.04
    RUN apt-get update --yes && \
        apt-get install --yes --no-install-recommends curl && \
        apt-get clean && rm -rf /var/lib/apt/lists/*

    실제로는 패키지 Cache 삭제 명령인 apt-get clean와 다운로드 된 패키지를 삭제하는 명령어를 같이 적어줘야 합니다.

     

    여기까지가 제일 기본적인 레이어를 경량화하는 방법입니다.

     

    비교적으로 보여드리면 다음과 같습니다. 여러 패키지를 비교 대상으로 하면 차이가 명확합니다.

     

    1번 이미지

    FROM ubuntu:20.04
    
    LABEL maintainer="joonyeonglim - datacook.tistory.com"
    
    # Fix: https://github.com/hadolint/hadolint/wiki/DL4006
    # Fix: https://github.com/koalaman/shellcheck/wiki/SC3014
    SHELL ["/bin/bash", "-o", "pipefail", "-c"]
    
    USER root
    
    # Install all OS dependencies for notebook server that starts but lacks all
    # features (e.g., download as all possible file formats)
    ENV DEBIAN_FRONTEND noninteractive
    
    RUN apt-get update --yes && \
        # - apt-get upgrade is run to patch known vulnerabilities in apt-get packages as
        #   the ubuntu base image is rebuilt too seldom sometimes (less than once a month)
        apt-get upgrade --yes && \
        apt-get install --yes --no-install-recommends \
        postgresql-client-12 \
        gnupg2 \
        ca-certificates \
        fonts-liberation \
        locales \
        # - pandoc is used to convert notebooks to html files
        #   it's not present in arm64 ubuntu image, so we install it here
        pandoc \
        # - run-one - a wrapper script that runs no more
        #   than one unique  instance  of  some  command with a unique set of arguments,
        #   we use `run-one-constantly` to support `RESTARTABLE` option
        run-one \
        sudo \
        # - tini is installed as a helpful container entrypoint that reaps zombie
        #   processes and such of the actual executable we want to start, see
        #   https://github.com/krallin/tini#why-tini for details.
        tini \
        wget  \
        vim

     

     

    2번 이미지

    FROM ubuntu:20.04
    
    LABEL maintainer="joonyeonglim - datacook.tistory.com"
    
    # Fix: https://github.com/hadolint/hadolint/wiki/DL4006
    # Fix: https://github.com/koalaman/shellcheck/wiki/SC3014
    SHELL ["/bin/bash", "-o", "pipefail", "-c"]
    
    USER root
    
    # Install all OS dependencies for notebook server that starts but lacks all
    # features (e.g., download as all possible file formats)
    ENV DEBIAN_FRONTEND noninteractive
    
    RUN apt-get update --yes && \
        # - apt-get upgrade is run to patch known vulnerabilities in apt-get packages as
        #   the ubuntu base image is rebuilt too seldom sometimes (less than once a month)
        apt-get upgrade --yes && \
        apt-get install --yes --no-install-recommends \
        postgresql-client-12 \
        gnupg2 \
        ca-certificates \
        fonts-liberation \
        locales \
        # - pandoc is used to convert notebooks to html files
        #   it's not present in arm64 ubuntu image, so we install it here
        pandoc \
        # - run-one - a wrapper script that runs no more
        #   than one unique  instance  of  some  command with a unique set of arguments,
        #   we use `run-one-constantly` to support `RESTARTABLE` option
        run-one \
        sudo \
        # - tini is installed as a helpful container entrypoint that reaps zombie
        #   processes and such of the actual executable we want to start, see
        #   https://github.com/krallin/tini#why-tini for details.
        tini \
        wget  \
        vim && \
        apt-get clean && rm -rf /var/lib/apt/lists/*

     

    마지막 레이어에 캐시 삭제 명령어와 불필요한 설치 파일을 삭제하는 명령어를 추가했습니다.

     

    결과는 다음과 같습니다.

     

    1번 이미지는 342MB, 2번 이미지는 297MB

    14% 가량 이미지가 줄어들었네요.

     

    많은 패키지가 들어간다면 더욱 더 용량이 줄어들겠죠?

    읽어주셔서 감사합니다.

     

    끝.

    반응형
Designed by Tistory.