Docker 이미지 레이어
Docker 이미지
- Docker 이미지는 논리적으로는 하나의 대상이다.
- Docker를 구성하는 각각의 파일을
이미지 레이어
라고 부른다. 도커 이미지는 물리적으로는 여러 개의 작은 파일로 구성돼 있다. - 하나의 이미지는 위와 같이 여러 이미지가 계층적으로 쌓인 형태로 저장된다. 정리하면 하나의 도커 이미지는 여러개의 이미지 레이어로 구성된다.
- Docker를 구성하는 각각의 파일을
- 도커가 이들 파일을 조립하여 컨테이너 내부 파일 시스템을 만들며 , 전체 이미지를 사용할 수 있게 된다.
Docker 이미지와 이미지 레이어
- 도커 이미지란 이미지 레이어가 모인 논리적 대상이다.
- 도커 이미지 레이어란 무엇일까? 아래의 명령어를 입력하면 이미지 레이어에 대한 정보가 출력된다.
1 | docker image history web-ping |
CREATED BY 칼럼은 해당 이미지 레이어를 구성하는 Dockerfile 스크립트의 명령어이다. 즉 , Dokcerfile의 명령어와 이미지 레이어는 1:1로 매핑된다.
- 구체적으로 도커 이미지 레이어란
도커 엔진의 캐시에 물리적으로 저장된 파일
이다.- 이미지 레이어는 여러 이미지와 컨테이너에서 공유된다.
- 만약 Nodejs 런타임 이미지 레이어를 가진 컨테이너를 여러개 실행하면 이 컨테이너들은 모두 동일한 Nodejs 런타임이 들어 있는 이미지 레이어를 공유한다.
- 앞서 이미지 레이어는 여러 이미지에서 공유된다고 하였다.상기의 명령어를 입력하면 이미지의 “논리적” 크기를 확인할 수 있는데 , 마치 각각의 이미지가 75.3 MB을 잡아먹는것처럼보인다.
1
docker image ls
하지만 실제 이미지가 디스크에서 얼마나 차지하는지는 아래의 명령어로 확인이 가능하다.
실제로는 이미지 레이어는 이미지와 컨테이너에서 재사용되기 때문에 150.6MB가 아닌 75.3MB만 디스크에서 공간을 차지하고 있는것을 확인할 수 있다.
1 | docker system df |
공유 자원 : 이미지 레이어
- 이미지 레이어는 앞서 정리한대로 여러 이미지에서 공유되는 자원이다. 따라서 공유 자원을 수정하면 이를 사용하고 있는 모든 이미지에게 영향이 갈것이다.
- 도커는 이미지를 읽기 전용으로 만들어 이런 문제를 방지한다. 즉 이미지 레이어는 수정할 수 없다.
Dockerfile 스크립트 최적화
- 도커는 캐시에 일치하는 레이어가 있는지 확인하기 위해 해시값을 사용하는데,
- Dockerfile의 명령어
- Dockerfile의 명령어에 의해 복사되는 파일의 내용
위 2개로부터 계산된다. 즉 명령어가 일치하고 , 파일의 내용 역시 일치한다면 동일한 이미지 레이어 캐시를 사용한다는 말이다.만약 캐시 미스라면 실제로 Dockerfile의 명령어가 실행되고 , 해당 Dockerfile 스크립트 아래부터는 수정된것이 없다라도 모두 실행된다.
따라서 Dockerfile 스크립트의 명령어는 잘 수정하지 않는 명령어가 앞으로 오고 자주수정되는 명령어는 뒤로 오도록 배치해야지만 캐시된 이미지 레이어를 많이 재사용할 수 있다.
이는 빌드 시간을 줄이고 , 차지하는 디스크 용량 , 또 이미지를 네트워크를 통해 받는다면 네트워크 대역폭까지 줄일 수 있다.
예시
- 아래의 Dockerfile은 명령어 위치만 변경하더라도 개선할 수 있다. app.js가 자주 수정되는 앱이라고 가정하였을때
1
2
3
4
5
6
7
8
9
10FROM diamol/node
ENV TARGET="blog.sixeyed.com"
ENV METHOD="HEAD"
ENV INTERVAL="3000"
WORKDIR /web-ping
COPY app.js .
CMD ["node", "/web-ping/app.js"]
위 코드는 app.js 수정시마다 , CMD ["node", "/web-ping/app.js"]
이미지 레이어 역시 다시 빌드한다.
아래와 같이 스크립트를 개선하면 app.js 수정이 발생했을때 마지막 레이어를 제외하고는 모두 캐시된 이미지 레이어를 사용한다.
1 | FROM diamol/node |