Docker 레이어 캐시를 사용하여 빠른 빌드

9053 단어 devopsdocker
나는 Docker가 내 업무에서 가장 두렵고 곤혹스러운 일 중의 하나라는 것을 발견했다.이해하기 쉽고 무섭지 않은 방식으로 내가 배운 것들을 나눌 수 있기를 바란다.

Docker란?
Docker는 an(almost) virtual machine의 컨테이너 운송 소프트웨어의 응용 프로그램이다.Docker 컨테이너를 사용하여 다음을 수행할 수 있습니다.
  • 응용 프로그램 코드를 컴퓨터의 다른 부분과 분리한다.
  • 애플리케이션에서 액세스할 수 있는 자원(예: 네트워크)을 제어할 수 있습니다.
  • 가상 운영체제에서 코드를 실행하면 서로 다른 컴퓨터에서 코드를 실행할 수 있고 코드의 행위에 대해 더욱 큰 자신감을 가지게 된다(예를 들어 개발과 생산 과정에서).

  • 작업 원리
    다음은 Docker 컨테이너를 만드는 방법입니다.
  • Dockerfile을 작성하여 소스 코드에 추가합니다.
  • Docker 파일을 Docker build 명령에 전달합니다.
  • Docker는 Dockerfile의 설명을 실행하여 컨테이너의 이미지를 만듭니다.
  • 이미지를 Docker create 명령에 전달합니다.
  • Docker는 이미지에 따라 컨테이너를 만듭니다.
  • 먼저 Docker는 Docker 파일의 설명에 따라 이미지를 구성합니다.
    가능한 경우는 다음과 같습니다.
    FROM node:12.14.1-slim
    USER node
    COPY package.json /home/node/
    WORKDIR /home/node
    RUN npm install
    RUN npm run build
    
    Docker 파일의 모든 줄은 Docker가 이미지를 어떻게 구축해야 하는지instruction입니다.
    예를 들어, copy 명령은 Docker 컨텍스트(예: 소스 코드)에서 컨테이너로 파일을 복사합니다.(컨테이너에는 자체 파일 시스템이 있습니다!)
    Docker가 명령을 하나씩 수행한 다음 결과의 스냅샷을 만들어 이미지로 저장합니다.
    그런 다음 이미지에서 컨테이너를 만들고 컨테이너를 시작하며 명령을 실행할 수 있습니다.
    다음은 내가 나의 노드를 어떻게 구축하고 운행할 것인가이다.위의 Dockerfile을 사용하는 js 응용 프로그램:
    docker build --tag my_app .
    docker run my_app npm start
    
    Docker run은 단일 명령에서 작성, 시작 및 실행의 조합과 비슷합니다.
    하지만 잠깐만, 이게 아직 일의 전모가 아니야.우리 차원에 대해 이야기합시다.

    도면층의 작업 원리
    Docker는 구문 이미지의 끝에만 스냅샷을 만드는 것이 아닙니다.실제로 Docker는 작성 프로세스의 각 명령에 따라 스냅샷을 생성합니다.
    이 스냅숏을 층이라고 하는데, 각 층마다 명령 집행으로 인해 발생한 변화를 기록하였다.
    한 레이어에는 마지막 명령을 실행한 이후 변경된 내용만 저장되므로 각 레이어는 상위 레이어(즉 상위 레이어)에 종속됩니다.부모 레이어가 없는 레이어는 해당 부모 레이어의 컨텍스트에서만 의미가 있으므로 유효하지 않습니다.
    따라서 레이어는 다음과 같습니다.
  • 명령
  • 지령 기간에 변화가 발생한 기록
  • 고유 ID
  • 상위 ID
  • (방주: Docker층은 Git 제출처럼 보입니다!)
    Docker는 구문 중인 모든 레이어를 내보낸 이미지에 저장합니다.
    Docker가 이미지에서 컨테이너를 만들도록 요청하면 Docker는 각 레이어의 변경 내용을 다른 레이어에서 재생성합니다(이것이 레이어라고 하는 이유).

    레이어 캐시의 작동 방식
    docker build을 실행할 때 --cache-from 명령줄 파라미터를 추가하여 docker에 층 캐시로 사용할 그림을 제공할 수 있습니다.
    모든 명령을 실행하기 전에 Docker는 캐시에 실행할 명령과 일치하는 층이 있는지 확인하고, 하나를 찾으면 새 층을 구축하는 것이 아니라 이 층을 사용합니다.좋아, Docker!
    중요한 것은 Docker가 이전 레이어의 ID가 캐시 레이어의 상위 ID와 일치하는지 확인하는 것입니다. 이전 레이어가 일치하지 않으면 캐시 레이어를 사용할 수 없습니다.
    이렇게 하면 Docker가 레이어 캐시에서 명령과 일치하는 항목을 찾을 수 없게 되면 해당 명령의 레이어와 모든 하위 레이어를 재구성해야 합니다. 즉, 캐시 레이어를 비활성화하면 사실상 모든 하위 레이어가 비활성화됩니다.
    이 작업이 실제로 어떻게 수행되는지 보여주기 위해 다음과 같은 예제 Dockerfile로 돌아가겠습니다.
    FROM node:12.14.1-slim
    USER node
    COPY package.json /home/node/
    WORKDIR /home/node
    RUN npm install
    RUN npm run build
    
    docker build을 실행하고 --cache-from 인자를 추가합니다. 아래와 같습니다.
    docker build --tag “my_app” --cache-from=”my_app” .
    
    다음은 로그 출력입니다.
    Step 1/6 : FROM node:12.14.1-slim
        ---> 918c7b4d1cc5
    Step 2/6 : USER node
        ---> Using cache
        ---> d897eea3d14a
    Step 3/6 : COPY package.json /home/node/
        ---> Using cache
        ---> 6211fc2535b1
    Step 4/6 : WORKDIR /home/node
        ---> Using cache
        ---> 8b7fbfbc367f
    Step 5/6 : RUN npm install
        ---> Using cache
        ---> 530d5f1f8e6d
    Step 6/6 : RUN npm run build
        ---> Using cache
        ---> ae5267476d3d
    Successfully built ae5267476d3d
    Successfully tagged my_app
    
    각 명령 이후 Docker는 캐시 레코드 로그를 사용하고 그 다음은 캐시가 있는 레이어의 ID입니다.
    이제 Dockerfile을 RUN npm install --only=prod 대신 RUN npm install로 변경한 다음 빌드를 다시 실행하면 다음과 같은 결과를 얻을 수 있습니다.
    Step 1/6 : FROM node:12.14.1-slim
        ---> 918c7b4d1cc5
    Step 2/6 : USER node
        ---> Using cache
        ---> d897eea3d14a
    Step 3/6 : COPY package.json /home/node/
        ---> Using cache
        ---> 6211fc2535b1
    Step 4/6 : WORKDIR /home/node
        ---> Using cache
        ---> 8b7fbfbc367f
    Step 5/6 : RUN npm install --only=prod
        ---> Running in a168555b7db9
    Removing intermediate container a168555b7db9
        ---> 44ab41899c52
    Step 6/6 : RUN npm run build
        ---> Running in 1230a3e778aa
    Removing intermediate container 1230a3e778aa
        ---> 8d3dca829a17
    Successfully built 8d3dca829a17
    Successfully tagged my_app
    
    로그 출력에서는 알 수 없지만, 이 버전은 이전 버전보다 훨씬 느리게 실행됩니다.원인을 찾아봅시다.
    앞의 행은 이전 행과 동일하지만 이제 명령에 들어가면 다음이 아니라 변경됩니다.
    Step 5/6 : RUN npm install
        ---> Using cache
        ---> 530d5f1f8e6d
    
    이제 우리는 다음과 같은 것을 얻었다.
    Step 5/6 : RUN npm install --only=prod
        ---> Running in a168555b7db9
    Removing intermediate container a168555b7db9
        ---> 44ab41899c52
    
    아하, 그래서 이 단계는 캐시를 사용하지 않고 명령을 실행했습니다. 명령이 바뀌었기 때문입니다!물론 좋은 일이다. 우리가 지령을 바꿨기 때문에, 우리는 Docker가 다른 일을 하기를 바란다.Docker가 캐시 레이어를 사용하는 경우 오류가 발생합니다.
    그러나 여기서 관건은 층의 ID도 변화530d5f1f8e6d부터44ab41899c52까지.즉, Docker가 레이어 캐시에서 찾을 때 레이어 ID가 이전과 다르기 때문에 일치하는 레이어를 찾을 수 없습니다. 즉, 부모 레이어의 ID와 명령에 따라 캐시 레이어를 찾을 수 있습니다.
    모든 층은 우리가 변경한 설명에 따라 재구성해야 한다.로그 출력에서 볼 수 있습니다. 이것이 바로 발생한 일입니다.일단 캐시가 효력을 상실하면 캐시 라인을 더 이상 사용하지 않습니다.
    그래서 우리가 구축하는 데 더 많은 시간이 필요한 이유는 우리가 npm installnpm run build 절차를 완전히 다시 운행해야 하기 때문이다.
    주의해야 할 것은 이것은 Docker의 문제가 아니라 중요한 기능이다!npm run build의 결과에 변화가 생길 수 있는데 이것은 우리가 먼저 뛸지npm install냐, 아니면 먼저 뛸지npm install --only=prod에 달려 있다.Dockerfile의 npm install 줄을 변경하는 것은 Docker가 우리의 npm run build 줄을 다시 실행하기를 거의 원할 것이라는 것을 의미한다.이것은 예상한 대로 캐시가 효력을 상실한 것이다.
    물론, 만약 우리가 아무런 변경도 하지 않은 상태에서 이 명령을 다시 실행한다면, 우리는 매번 같은 이미지 표시를 덮어쓰기 때문에 완전히 캐시된 구축을 받을 수 있을 것이다.

    왜 그게 중요해
    Docker 파일을 작성할 때 Docker층 캐시의 작업 원리를 이해하는 것이 매우 중요하다.
    이 Dockerfile 세그먼트를 예로 들어 보겠습니다.
    COPY src /home/node/src
    COPY package.json /home/node/
    WORKDIR /home/node
    RUN npm install
    RUN npm run build
    
    여기서 우리는 COPY src 지령을 npm install 지령 앞에 놓을 것이다.이것은 npm install 디렉터리에 있는 파일을 변경할 때마다 src src 파일을 변경하면 COPY src 줄의 층 캐시가 효력을 상실하기 때문에 다시 실행해야 한다는 것을 의미한다.(참고: COPY 테스트 중에 Docker는 파일 변경을 명령이 변경된 것으로 간주하여 캐시를 무효화합니다.)
    내 노드로 말하자면js 응용 프로그램, 나는 npm install의 결과가 내 src 폴더의 내용에 영향을 받지 않을 것이라고 믿기 때문에 src를 변경할 수 있기를 희망한다. 매번 기다릴 필요가 없다 npm install.
    따라서 Dockerfile 순서를 변경하고 COPY srcnpm install 다음으로 이동합니다.
    COPY package.json /home/node/
    WORKDIR /home/node
    RUN npm install
    COPY src /home/node/src
    RUN npm run build
    
    현재, 만약 내가 src 의 내용을 바꾸었지만, 내가 닿지 않았다면 package.json, Docker는 캐시에서 앞의 몇 층을 직접 가져올 수 있고, 다시 실행하기만 하면 된다. npm run build이것이 바로 우리가 원하는 것이다. npm install 의 출력은 src 의 내용에 따라 바뀌지 않지만 npm run build 의 출력은 바뀌기 때문이다.
    이것은 Docker가 다시 실행되지 않는다는 것을 의미하기 때문에 내가 변경하지 않는 package.json 에서 구축 속도를 높일 것이다.🎉

    아무튼...
    중요한 것은 Docker 파일에서 명령 간의 의존 관계를 이해하고 Docker 층 캐시의 장점을 최대한 활용하는 것이다.관련 지령을 한데 묶어 보아라.
    당신이 자주 변화하는 것, 변하지 않는 것, 그리고 당신이 가장 자주 변화한다고 생각하는 것을 Dockerfile 밑에 놓아 보세요.

    좋은 웹페이지 즐겨찾기