Community

Docker 이미지 크기 최적화하기

3주 전에 대학생 분들 대상으로 '도커와 컨테이너'를 주제로 얘기하다가, Dockerfile을 최적화하는 방법에 대한 문의를 받았습니다. 관련해서 답변이 될 만한 기사 요약 및 공유 합니다. ❗️프롤로그 - Docker 이미지 형식은 image-spec이라는 사양에서 OCI(Open Container Initiative)에 의해 표준화되었습니다. - Docker 또는 기타 도구(예: buildah 또는 kaniko)를 사용하여 이미지를 빌드할 수 있으며 결과 이미지는 호환되는 모든 컨테이너 런타임에서 로드할 수 있습니다. - Docker 이미지 == OCI 호환 이미지 - 비용절감(디스크 및 네트워크 리소스 절감)을 위해 Docker 이미지의 크기를 작게 유지하는 것은 중요합니다. 1️⃣ 적합한 기본 이미지 선택 적합한 기본 이미지 선택 - 기본 이미지는 Dockerfile 시작 부분의 FROM 문에서 참조되는 이미지의 이름입니다. - 기본 이미지를 선택할 때 사용 가능한 이미지(예: Docker 허브)와 이러한 이미지에 사용 가능한 "slim" 이미지 태그를 주의 깊게 살펴보아야 합니다. - alpine과 같은 일부 distribution는 기본적으로 크기가 매우 최적화되어 있습니다(~3MB). 그러나 alpine은 훨씬 더 일반적인 glibc C-라이브러리 대신 musl을 사용한다는 주의 사항이 있습니다. 이로 인해 종종 호환성 문제가 발생합니다. - 우분투나 데비안과 같은 많은 Linux 배포 이미지도 기본적으로 다소 작습니다(40MB 미만). - 데비안과 같은 일부 배포판에는 이미지 크기를 줄이는 "slim" 태그가 있습니다 - 파이썬, 노드와 같은 프로그래밍 언어별 이미지의 경우 종종 기본 이미지가 다소 큽니다(수백 MB). 그러나 선택적 패키지(예: 컴파일러)가 제거되어 훨씬 더 작은(종종 10배 더 작은) 슬림한 변형(variant)이 있습니다. 2️⃣ 멀티-스테이지(Multi-Stage) 빌드 - App에서 사용하는 종속성을 다운로드하고 컴파일해야 하기 때문에 Docker 이미지가 커지는 경우가 많습니다. App을 실행하지 않고 빌드/설치만 하면 되는 불필요한 파일 및 폴더로 인해 이미지 크기가 증가합니다. 예를 들면 다음과 같습니다. - 다단계 빌드를 사용하면 빌드 프로세스를 두 개(또는 그 이상)의 개별 이미지로 분할할 수 있습니다. >> 모든 패키지와 컴파일러를 설치하고 컴파일을 수행하는 "빌드 이미지"(여기서 디스크 공간은 문제가 되지 않음) >> 빌드 이미지에서 실행 이미지로 복사하는 다른 (컴파일된) 라이브러리뿐만 아니라 애플리케이션 코드만 복사하는 "실행 이미지" 3️⃣ RUN 명령 통합(Consolidate) - 일시적으로 특정 파일만 필요할 때마다(즉, 파일을 다운로드/설치하고 사용한 다음 다시 삭제) 여러 RUN 명령을 사용하는 대신 이러한 모든 단계를 수행하는 단일 RUN 명령을 빌드해야 합니다. >> 좋은 사례와 나쁜 사례는 아래 링크를 참고하세요! 🤟🏻 https://www.augmentedmind.de/2022/02/06/optimize-docker-image-size/ - 소프트웨어를 다운로드하거나 컴파일합니다. 단일 RUN 문에서 패키지 관리자를 사용하여 패키지를 설치한 다음 사용한 다음 다시 제거하십시오. 4️⃣ 스쿼시(Squash) 이미지 레이어 - docker-squash는 이미지의 마지막 N개 레이어를 단일 레이어로 스쿼시하는 Python 기반 도구(pip를 통해 설치됨)입니다. - 스쿼싱은 많은 (대형) 파일 또는 폴더를 만든 다음 새 레이어에서 삭제한 레이어가 있는 경우 Docker 이미지 크기를 줄이는 데 유용합니다. 5️⃣ 종속성(디펜던시) 설치 시 공간 절약 - 패키지 관리자를 사용하여 앱이 의존하는 타사 소프트웨어 구성 요소를 설치하는 것이 일반적입니다. 패키지 관리자의 예로는 apt 또는 yum(Linux 패키지의 경우) 또는 Python용 pip와 같은 프로그래밍 언어별 관리자가 있습니다. - 개발언어별로 패키지 관리자를 사용해서 공간을 절약하는 방법은 아래 링크를 참고하세요! 🤟🏻 https://www.augmentedmind.de/2022/02/06/optimize-docker-image-size/ 6️⃣ 불필요한 chown 피하기 - Dockerfile의 일부 문이 빌드 컨테이너의 파일을 어떤 식으로든 수정할 때마다(메타 데이터 변경 포함) 해당 파일의 완전히 새로운 사본이 새 계층에 저장됩니다. 이는 파일 소유권 또는 권한의 변경에도 해당됩니다. 따라서 Docker가 영향을 받는 모든 파일을 복제하기 때문에 재귀 chown은 매우 큰 이미지를 생성할 수 있습니다. 7️⃣ .dockerignore 파일 사용 - .dockerignore 파일을 사용하면 Docker 빌드 프로세스가 호스트에서 빌드 컨텍스트로 복사하면 안 되는 파일 및 폴더를 지정할 수 있습니다. 이것은 Docker 이미지 빌드 속도를 높일 뿐만 아니라(빌드 컨텍스트가 더 빨리 채워지기 때문에) 이미지를 더 작게 만들 수도 있습니다. - 데이터 파일(예: 자동화된 테스트에만 필요한 원시 데이터가 있는 큰 CSV 파일)은 누군가가 "src" 폴더에 잘못 배치하여 전체 내용이 Dockerfile의 COPY 문을 통해 이미지에 복사될 수 있습니다. 8️⃣ docker-slim 도구 사용 - docker-slim은 이미지의 임시 컨테이너를 시작하고 (정적 + 동적 분석을 통해) 해당 컨테이너에서 애플리케이션이 실제로 사용하는 파일을 파악하여 이미지 크기를 줄이는 도구입니다. 그런 다음 docker-slim은 실제로 사용된 파일과 폴더만 포함하는 새로운 단일 계층 이미지를 빌드합니다. 이로 인해 docker-slim은 여기에 나열된 모든 접근 방식 중 가장 효과적인 접근 방식입니다. 단 주의사항이 있는데, 해당 내용은 링크를 참고하세요! 이상입니다. 상세 내용은 아래 링크를 참고하세요. 감사합니다. 👏

알림

알림이 없습니다