[Docker] 이미지 캐시, 레이어 (image layer)
이미지 캐시 ( image cache )
이미지를 빌드할 때마다 도커는 모든 명령 결과를 캐시
레이어 아키텍쳐 : 이전에 build 했던 Dockerfile을 rebuild할 때 이전 실행과 대비하여 새파일 및 수정 내역이 없으면 이전 빌드때 실행했던 캐시를 그대로 사용
Layer
Dockerfile에서 모든 명령 FROM .. WORKDIR ... COPY
등은 각각 하나의 레이어로, FROM 레이어를 맨 밑으로 위로 층층이 레이어를 쌓는다. 그리고 이런 레이어들을 층층마다 캐시한다.
FROM <base_image> => Layer 1
WORKDIR /app => Layer 2
COPY . /app => Layer 3
RUN npm install => Layer 4
EXPOSE 80 => Layer 5
CMD ["node", "server.js"] => Layer 6
단, 쌓인 레이어의 모습은 아래와 같다.
Layer 6 | CMD |
Layer 5 | EXPOSE |
Layer 4 | RUN |
Layer 3 | COPY |
Layer 2 | WORKDIR |
Layer 1 | FROM |
그런 다음 이미지를 기반으로 컨테이너를 실행하면, 컨테이너는 Dockerfile의 명령을 실행한 결과의 애플리케이션 이미지 위에 "새로운 레이어를 추가" 하여 이미지를 레이어로 실행할 때만 활성화되는 최종 레이어를 추가한다.
최종 명령 이전의 모든 명령은 이미지의 일부이며 별도의 레이어로 아무 것도 변경되지 않으면 이런 레이어를 캐시에서 사용할 수 있다.
만약 변경 사항이 있을 경우 캐시의 일부 결과만을 사용해서 rebuild할 때 약간 느려진다. 이는 레이어 변경 후의 모든 레이어가 rebuild 되기 때문인데, 만약 소스 코드를 수정하고 위의 Dockerfile을 사용해서 rebuild한다고 가정하면, FROM과 WORKDIR 레이어는 캐시를 사용하여 빠르지만, COPY 명령어부터는 파일이 수정되었기 때문에 캐시를 사용하지 않고 build한다. 그렇기 때문에 COPY 명령부터는 이미지를 처음 빌드할 때와 다름 없는 속도이기 때문에 속도적 측면에서 느릴 수 밖에 없다.
튜닝 후
그러나, package 파일은 변경하지 않았는데, 억울하게도( 코드가 달라졌기 때문에 이후 날리는 명령이 어떤 다른 결과를 초래할지 모름) COPY 명령 다음에 위치한 관계로 이미지를 rebuild할때마다 npm install 명령을 캐시를 사용하지 않고 수행하는 것을 볼 수 있다. 그렇기 때문에, 변경된 사항 부분( COPY <code> ) 을 더 뒤로 빼고 npm install 부분을 더 위 층으로 올려 캐시를 사용하는 것이 훨씬 속도가 빨라진다.
FROM <base_image>
WORKDIR /app
COPY package.json /app # package 먼저 COPY
RUN npm install # package 설치
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]