이미지 레이어는 어떻게 관리해야 할까?
dockerfile과 이미지 레이어
--
이미지는 레이어로 구성되어 있으며
이미지를 빌드할 때 생성되는 레이어는
일반적으로 dockerfile에 작성된 지시어 하나당 레이어 한 개가 추가된다.
(레이어를 추가하지 않는 지시어도 존재한다.)
위 그림에서는
레이어가 5개 추가된 것을 볼 수 있지만
베이스 이미지인 node:14 이미지는 이미 레이어가 14개로 구성된 이미지기 때문에
결과적으로 총 18개의 레이어로 구성된 이미지가 빌드될 것이다.
레이어의 개수가 늘어나는 것은 이미지의 크기를 증가시키는 것이고
이미지의 크기가 증가된다면 빌드의 속도가 느려지고 이미지 관리도 복잡해지는 단점이 생긴다.
그래서 레이어는 꼭 필요한 레이어만 추가하는 것이 좋다.
레이어의 개수를 관리하는 대표적인 케이스가 RUN 지시어를 사용하는 경우이다.
RUN 지시어는 컨테이너 레이어 안에서 특정 명령어를 실행하는 지시어이다.
그래서 이미지 빌드를 하다 보면 여러 번의 작업을 수행해야 하는 경우가 생기는데
각 명령어마다 RUN 지시어를 사용하게 되면 빌드되는 이미지에는
RUN 지시어를 사용한 개수만큼 레이어가 증가하게 된다.
하지만 리눅스에서는 "&&"를 사용하여 여러 개의 명령어를 한 번에 실행할 수 있도록 할 수 있다.
즉, RUN 지시어 하나 만으로 여러 개의 명령어를 동작시킬 수 있어
결과적으로 같은 상태의 이미지를 생성하지만 레이어의 개수를 줄일 수 있게 된다.
--
이미지 크기
--
이미지의 크기는 가능한 작은 것이 좋다.
보통 현업에서는 이미지를 빌드, 푸시, 배포하는 과정은 모두 각각 다른 기기에서 이루어진다.
- 새로운 버전으로 빌드한 이미지를 레지스트리에 푸시
- 각 환경에서 이미지를 레지스트리에서 다운로드하여 컨테이너를 업그레이드
이러한 과정에서 이미지는 네트워크를 통해서 업로드, 다운로드되기 때문에
이미지의 크기가 작은 것이 배포 속도와 네트워크 사용량에서 더 유리하다.
이미지의 크기를 줄이는 다양한 방법
1. 애플리케이션의 크기를 줄이기
애플리케이션 소스에 불필요한 기능들을 줄이고
하나의 큰 모듈을 여러 모듈로 분리하여 애플리케이션의 크기를 줄일 수 있다.
2. 베이스 이미지를 크기가 작은 이미지로 선택하기
보통 apline OS를 기반으로 제작된 이미지를 베이스 이미지로 많이 활용된다.
apline으로 된 이미지는 매우 작은 크기의 리눅스 배포판 이미지로
필요한 패키지만 포함하고 있어서 크기가 작다.
기본적인 리눅스 커널, 쉘, 패키지 관리자 등 필수적인 구성 요소만 포함되어 있다.
여기서 더 극단적으로 크기를 줄이려면
모든 이미지의 가장 뿌리가 되는 이미지인 scratch 이미지를 활용하면 된다.
scratch는 도커에서 제공하는 완전히 비어있는 베이스 이미지이며
해당 이미지를 사용하면 모든 필요 요소들을 직접 추가해줘야 한다.
(이미지를 빌드하기 위한 가장 최소한의 파일만 포함되어 있는 이미지)
특별한 경우가 아니면 가능한 apline 베이스 이미지를 사용하는 것이 좋다.
DockerHub에 업로드되어 있는 이미지들(nginx, jdk)을 잘 찾아보면 태그에 "alpine"이 붙어 있는 이미지들이 있다.
"alpine"태그가 붙은 이미지들은 빌드할 당시에 베이스 이미지를 "alpine"으로 사용했다는 것을 명시한다.
3. .dockerignore 파일을 사용해서 불필요한 파일이 이미지에 들어가지 않게 관리하기
git으로 소스코드를 관리할 때에도 .gitignore라는 파일에 git으로 관리하지 않을 파일을 등록하는 것처럼
도커에도 .dockerignore 파일을 이용하여 이미지 빌드 시 이미지에 들어가지 않을 파일들을 관리할 수 있다.
보통 COPY 지시어를 통해 단일 파일을 복사하는 것보다 디렉터리 전체를 복사하는 방식을 사용한다.
COPY 지시어를 여러 번 나누어서 복사하면 그만큼 레이어가 증가하기 때문이다.
이때 디렉터리 전체를 복사할 때 그 안에 있는 특정 파일 또는 디렉터리는 복사되지 않도록 하기 위해
.dockerignore 파일에 등록해 주면 된다.
--
참고 및 출처
'Docker' 카테고리의 다른 글
3Tier 아키텍처 구성 방법 (+Nginx 설정) (0) | 2024.07.01 |
---|---|
이미지 빌드시 캐싱 활용하기 (0) | 2024.06.30 |
도커 볼륨, 마운트, 바인드 마운트 (+명령어) (0) | 2024.06.28 |
Docker의 가상 네트워크 (+명령어) (0) | 2024.06.27 |
docker 가상 네트워크 포트포워딩과 도커 DNS (+명령어) (0) | 2024.06.26 |