본문 바로가기
DevOps

Docker Image와 Dockerfile로 알아보는 Image Layer

by NEMNE 2022. 4. 3.

들어가기 전에

이전까지는 도커의 존재만 알고 있을 뿐 도커가 정확하게 무엇을 하는지 왜 사용하는지에 대해 하나도 알지 못했다. 그러나 칼고리 스터디를 통해 도커를 접할 기회가 생겼고 까다로울 거 같다는 예상과 달리 막상 도커을 접하고 나니 새로운 지식을 배우게 되어 재밌었고 왜 그렇게 도커를 많이 사용하는지에 대해 알게되는 계기가 되었다.

 

도커의 다양한 개념 중 이번 글에서는 이미지 레이어에 대해 다뤄보려고 한다.


“Docker 이미지는 일련의 레이어로 구성되어 있고 각 계층은 Dockerfile에 있는 명령어를 나타낸다.”
- docker docs -

 

실제 공식 문서에 이미지에 대한 정의처럼 위 예제를 보면 다음과 같다.

 

4개의 Command로 구성되었으며, 여기서 File System을 수정하는 Command는 Layer를 생성한다.

  • FROM : ubuntu:18.04 이미지를 생성한다.
  • COPY : 내 로컬 환경에 있는 일부 파일을 추가한다. (Image Layer 생성)
  • RUN : 빌드 과정에서 실행할 명령 지정(make를 통해 앱을 빌드 / 캐시 디렉토리 삭제) (Image Layer 생성)
  • CMD : 컨테이너에서 실행할 명령 지정 (app.py 실행)

 

실제로 ubuntu:14.04는 3개의 레이어가 생성되는데 ubuntu의 dockerfile을 보면 RUN 명령어가 3번 실행됐기 때문이다.

ubuntu 이미지로 RUN 명령이 3개 존재한다.

 

즉, Layer는 이전 Layer와의 차이점 집합이며 파일을 추가 & 제거하면 새로 생성된다. (RUN, ADD, COPY 등)

 

Container Layer

Layer는 서로 위에 쌓이고 새 컨테이너를 만들 때 쓰기 가능한 Layer가 추가되는데 이를 Container Layer라고 한다.

(Image Layer는 read only)

 

 

즉, 우리가 새 컨테이너를 만들고 내부에서 발생하는 파일 생성, 수정, 삭제 등의 작업은 모두 Container Layer에 기록된다.

 

Storage Driver

“스토리지 드라이버를 효과적으로 사용하려면 Docker가 이미지를 빌드하고 저장하는 방법과 이러한 이미지가 컨테이너에서 사용되는 방법을 아는 것이 중요합니다.” - docker docs -

Image Layer와 Container Layer를 이해하는 것이 중요한 이유는 Storage Driver 사용을 위해서 필요하다.

 

또한 “나뉘어진 레이어들을 어떻게 하나로 통합하지?”라는 의문이 생길 수 있는데 나눠진 레이어를 합치기 위해서 Union Mount 이용한다. Union Mount는 하나의 디렉토리에 여러 파일 시스템을 마운트하면 여러 파일 시스템 내용이 합쳐지는 것을 의미한다.

 

위 사진에서 UnionFS는 linux, freeBSD 등의 File System로 다른 FS에 대한 Union Mount의 구현체이다.

 

다른 구현체로는 AUFS, btfs, zvfs, overlay 등이 있다. 여기서 Union Mount의 구현체가 Docker의 Storage Driver가 된다.(Docker에서는 overlay가 디폴트)

 

 

Storage Driver가 다양한만큼 성능도 상황에 따라 다르기 때문에 올바른 상황에 맞게 Storage Driver를 사용하는 것이 중요하다.

 

실습으로 확인하기

이제 실습으로 직접 확인할 차례이다.

ubuntu:14.04 이미지가 존재한다는 가정하에 진행했다.

 

docker run --name commit_test ubuntu:14.04

앞에서 우분투 이미지가 3개의 레이어로 구성되었으니 이미지를 컨테이너화 시킬 때도 3개의 레이어가 Pull이 된다.

 

 

docker image inspect ubuntu:14.04

inspect 명령어를 통해 실제 이미지 레이어 정보를 확인 할 수 있다.

 

Layers는 이미지 레이어 정보

 

 

docker start commit_test
docker exec -it commit_test /bin/bash
cd home
vi text.txt //아무 글자 입력 후 저장
exit

docker commit commit_test commit_test1
docker images // 이미지 리스트 확인

이후 위 코드를 입력하여 text.txt가 추가된 새로운 이미지를 생성한다.

 

 

docker run -it --name commit_test2 commit_test1
cd home
ls

 

다시 확인하고자 commit_test1 이미지 기반으로 한 새로운 컨테이너를 생성한다.

commit_test1으로 생성된 컨테이너를 확인해보면 기존 ubuntu:14.04 이미지에 없었던 test.txt가 생성됐다.

 

 

추가로 commit_test1 이미지의 구성 레이어를 확인해보면

docker image inspect commit_test1

 

 

기존과 다르게 1개의 레이어가 추가된 것을 확인 할 수 있다.

 

 

참고

https://opentutorials.org/course/4781/30609

https://docs.docker.com/storage/storagedriver/

https://jenakim47.tistory.com/40

https://devaom.tistory.com/5