programing

도커 파일에서 다중 RUN과 단일 체인 RUN 중 어느 것이 더 좋습니까?

subpage 2023. 8. 22. 22:09
반응형

도커 파일에서 다중 RUN과 단일 체인 RUN 중 어느 것이 더 좋습니까?

Dockerfile.1 다실중을 합니다.RUN:

FROM busybox
RUN echo This is the A > a
RUN echo This is the B > b
RUN echo This is the C > c

Dockerfile.2가입:

FROM busybox
RUN echo This is the A > a &&\
    echo This is the B > b &&\
    echo This is the C > c

RUN 더 생각했고, 레이어가 적을수록 생각했습니다.Dockerfile.2더 낫습니다.

이것은 분명히 사실입니다.RUN 이항목추항에서 합니다.RUN (계속,yum install nano && yum clean all), 하지만 모든 경우에RUN다음과 같은 몇 가지 사항을 고려해야 합니다.

  1. 계층은 이전 계층보다 차이를 더하기 때문에 나중 계층이 이전 계층에 추가된 항목을 제거하지 않는 경우 두 방법 사이에 Disk 공간 절약 이점이 크지 않아야 합니다.

  2. 허브에서 때문에 도커 허브는 도커 허브입니다.Dockerfile.1아마 조금 더 클 수도 있지만 이론적으로 다운로드 속도가 더 빠를 것입니다.

  3. 문장 4번째 문장)을 하면,echo This is the D > d및 ) 및역지재건,건재,Dockerfile.1에 더 수 , 캐시덕더빠구수축있만지할게르분에,만▁would,Dockerfile.24개의 명령을 모두 다시 실행해야 합니다.

자, 질문은 다음과 같습니다.도커 파일을 하는 더 나은 방법은 무엇입니까?

가능한 경우 파일을 만드는 명령과 동일한 파일을 삭제하는 명령을 항상 하나로 병합합니다.RUN 각각의 인이 있기 입니다. 이것은 각각의RUN합니다. 말 파일 으로 볼 수. 출력은 문자 그대로 파일 시스템 변경 사항을 볼 수 있습니다.docker diff생성되는 임시 컨테이너에 있습니다.다른 계층에서 생성된 파일을 삭제하는 경우 유니온 파일 시스템은 파일 시스템 변경 사항을 새 계층에 등록하는 것뿐이며 파일은 여전히 이전 계층에 있으며 네트워크를 통해 전송되어 디스크에 저장됩니다.따라서 소스 코드를 다운로드하여 추출하고 이진 파일로 컴파일한 다음 마지막에 tgz와 소스 파일을 삭제하면 이미지 크기를 줄일 수 있습니다.

다음으로, 저는 다른 이미지에서 재사용 가능성과 예상되는 캐싱 사용량에 따라 계층을 개별적으로 분할했습니다.4개의 이미지가 모두 동일한 기본 이미지(예: 데비안)인 경우, 대부분의 이미지에 대한 공통 유틸리티 모음을 첫 번째 실행 명령으로 가져와서 다른 이미지가 캐싱의 이점을 얻을 수 있습니다.

이미지 캐시 재사용을 검토할 때 도커 파일의 순서가 중요합니다.기본 이미지가 업데이트되고 Docker 파일에 높은 위치에 있는 경우에만 매우 드물게 업데이트되는 구성 요소를 봅니다.Docker 파일이 끝날 무렵에는 호스트별 UID를 가진 사용자를 추가하거나 폴더를 만들고 권한을 변경하는 등 빠르게 실행되고 자주 변경될 수 있는 모든 명령을 포함합니다.컨테이너에 현재 개발 중인 해석 코드(예: JavaScript)가 포함된 경우, 가능한 한 늦게 추가되어 재구성이 해당 단일 변경사항만 실행됩니다.

이러한 각 변경 그룹에서 계층을 최소화하기 위해 최대한 통합합니다.따라서 4개의 서로 다른 소스 코드 폴더가 있는 경우 단일 폴더 안에 이러한 폴더가 배치되어 단일 명령으로 추가할 수 있습니다.apt-get과 같은 패키지 설치는 가능한 경우 단일 RUN으로 병합되어 패키지 관리자 오버헤드(업데이트 및 정리)를 최소화합니다.


다단계 빌드에 대한 업데이트:

다단계 빌드의 최종 단계가 아닌 단계에서 이미지 크기를 줄이는 것에 대해 훨씬 덜 걱정합니다.노드로 각의 "" "" "" "" "" "" "" "" "" "" "" "" "" ""로 분할하여 캐시 재사용 할 수 .RUN선을

그러나 이것은 계층 스퀴징에 대한 완벽한 해결책은 아닙니다. 왜냐하면 단계 간에 복사하는 것은 환경 변수 설정, 진입점 및 명령과 같은 나머지 이미지 메타데이터가 아니라 파일이기 때문입니다.또한 Linux 배포판에 패키지를 설치하면 라이브러리 및 기타 종속성이 파일 시스템 전체에 분산되어 모든 종속성을 복사하기 어려울 수 있습니다.

따라서 CI/CD 서버에 바이너리를 구축하는 대신 다단계 빌드를 사용하므로 CI/CD 서버에 툴만 있으면 실행할 수 있습니다.docker buildjdk, 및가 설치되어 않습니다.jdk, nodejs, go 파일 형식입니다.

모범 사례에 나열된 공식 답변(공식 이미지는 이를 준수해야 함)

도면층 수 최소화

도커 파일의 가독성(따라서 장기적인 유지 관리 가능성)과 사용하는 계층 수를 최소화하는 것 사이의 균형을 찾아야 합니다.사용하는 계층 수에 대해 전략적이고 신중해야 합니다.

1 이후 버전 1.10 이후COPY,ADD그리고.RUN문은 이미지에 새 레이어를 추가합니다.이러한 문을 사용할 때는 주의해야 합니다.의 "을령명니봅다해합결하"로 조합해 .RUN위해 에만 가독성을 위해 필요한 경우에만 구분합니다.

많은 정보: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ #가장 인기 있는 사이트

업데이트: 도커의 다단계 > 17.05.

의 다계빌는서여개사수있다습을 사용할 수 .FROMDocker 파일에 있는 문.각각FROM문은 단계이며 자체 기본 이미지를 가질 수 있습니다.마지막 단계에서는 알파인과 같은 최소 기본 이미지를 사용하고, 이전 단계의 빌드 아티팩트를 복사하고, 런타임 요구 사항을 설치합니다.이 단계의 최종 결과는 사용자의 이미지입니다.이것이 앞에서 설명한 바와 같이 계층에 대해 걱정하는 부분입니다.

평소처럼 도커는 다단계 빌드에서 훌륭한 문서를 보유하고 있습니다.다음은 간단한 발췌문입니다.

다단계 빌드에서는 Docker 파일에 여러 FROM 문을 사용합니다.각 FROM 명령어는 다른 베이스를 사용할 수 있으며, 각 명령어는 빌드의 새로운 단계를 시작합니다.한 단계에서 다른 단계로 아티팩트를 선택적으로 복사하여 최종 이미지에 원하지 않는 모든 것을 남길 수 있습니다.

이에 대한 훌륭한 블로그 게시물은 https://blog.alexellis.io/mutli-stage-docker-builds/ 에서 찾을 수 있습니다.

귀하의 의견에 대한 답변:

  1. 네, 층은 일종의 차이입니다.절대적으로 변화가 없다면 레이어가 추가되지 않은 것 같습니다.문제는 #2 계층에서 무언가를 설치/다운로드하면 #3 계층에서 제거할 수 없다는 것입니다.그래서 일단 레이어에 무언가가 쓰여지면, 그것을 제거함으로써 이미지 크기를 더 이상 줄일 수 없습니다.

  2. 계층을 병렬로 풀링하여 속도를 높일 수 있지만 각 계층은 파일을 제거하더라도 이미지 크기를 의심할 여지 없이 늘립니다.

  3. 예, 캐싱은 도커 파일을 업데이트하는 경우 유용합니다.하지만 그것은 한 방향으로 작용합니다.10개의 계층이 있고 #6을 변경하더라도 #6-#10의 모든 계층을 재구축해야 합니다.따라서 빌드 프로세스 속도를 높이는 경우는 많지 않지만 이미지 크기를 불필요하게 늘릴 수 있습니다.


이 답변을 업데이트하라고 상기시켜준 @Mohan에게 감사드립니다.

위의 답변은 구식인 것 같습니다.이 문서는 다음과 같습니다.

Docker 17.05 이전 버전과 Docker 1.10 이전 버전에서는 이미지의 계층 수를 최소화하는 것이 중요했습니다.다음과 같은 개선 사항을 통해 이러한 필요성이 완화되었습니다.

[...]

Docker 17.05 이상에서는 필요한 아티팩트만 최종 이미지에 복사할 수 있는 다단계 빌드 지원이 추가되었습니다.이렇게 하면 최종 이미지의 크기를 늘리지 않고 중간 빌드 단계에 도구 및 디버그 정보를 포함할 수 있습니다.

그리고 이것은:

또한 이 예제에서는 이미지에 추가 레이어가 생성되지 않도록 Bash & & 연산자를 사용하여 두 개의 RUN 명령을 함께 인위적으로 압축합니다.이는 오류가 발생하기 쉽고 유지 관리가 어렵습니다.

모범 사례는 다단계 빌드를 사용하고 유지하는 것으로 변경된 것 같습니다.Dockerfile쉬운

이미지 계층에 포함된 내용에 따라 다릅니다.핵심은 가능한 한 많은 레이어를 공유하는 것입니다.

나쁜 예
  1. 도커 파일.1

    RUN yum install big-package && yum install package1
    
  2. 도커 파일.2

    RUN yum install big-package && yum install package2
    
좋은 예
  1. 도커 파일.1

    RUN yum install big-package
    RUN yum install package1
    
  2. 도커 파일.2

    RUN yum install big-package
    RUN yum install package2
    

다른 제안은 삭제가 추가/설치 작업과 동일한 계층에서 발생하는 경우에만 유용하지 않다는 것입니다.

언급URL : https://stackoverflow.com/questions/39223249/multiple-run-vs-single-chained-run-in-dockerfile-which-is-better

반응형