안녕하세요 펭귄 교수입니다.
이번 강의의 주제는 도커 이미지 최적화 및 관리입니다,
도커 이미지는 컨테이너가 실행될 때 필요한 모든 파일과 설정을 포함한 "템플릿" 같은 역할을 합니다.
하지만 이미지를 최적화하지 않으면 이미지 크기가 커지고, 그에 따라 컨테이너 실행 속도가 느려질 수 있습니다.
이번 글에서는 도커 이미지를 어떻게 하면 더 빠르고 효율적으로 만들 수 있을지 알아보겠습니다.
1. 도커 이미지란?
먼저, 도커 이미지가 무엇인지 간단히 알아보겠습니다.
도커 이미지는 애플리케이션과 그 애플리케이션을 실행하는 데 필요한 환경을 담고 있는 일종의 "스냅샷"입니다.
이미지를 기반으로 컨테이너가 실행되며, 컨테이너가 실행되는 동안 애플리케이션이 동작하게 됩니다.
도커 이미지는 여러 레이어로 구성되어 있습니다. 레이어는 이미지에 포함된 파일이나 설정을 나타내며, 각각의 레이어는 이전 레이어에 덧붙여지는 방식으로 쌓입니다.
이런 구조 덕분에 이미지를 효율적으로 관리할 수 있지만, 잘못 관리하면 이미지 크기가 불필요하게 커지기도 합니다.
2. 이미지 최적화하기
이미지를 최적화하려면, 작은 이미지를 만들고, 불필요한 파일을 최대한 줄이는 것이 핵심입니다.
예를 들어, 여러분이 웹 애플리케이션을 실행하는 컨테이너를 만들 때, 그 애플리케이션에 꼭 필요한 파일만 이미지에 포함시키는 것이 좋습니다.
다음은 이미지를 최적화하는 몇 가지 방법입니다.
2-1. 작은 베이스 이미지 사용하기
이미지를 만들 때 사용하는 베이스 이미지는 이미지를 구성하는 중요한 부분입니다. 베이스 이미지를 작게 하면 전체 이미지 크기를 크게 줄일 수 있습니다.
예를 들어, 여러분이 Ubuntu 베이스 이미지를 사용하는 대신, 더 작은 Alpine 이미지를 사용할 수 있습니다. Alpine 이미지는 도커에서 많이 사용하는 작은 리눅스 배포판입니다.
# 큰 이미지 예시
FROM ubuntu:latest
# 최적화된 작은 이미지 예시
FROM alpine:latest
Alpine은 불필요한 파일이 없어서 Ubuntu에 비해 훨씬 가벼운 이미지를 만들 수 있습니다.
대부분의 경우 Alpine만으로도 필요한 작업을 수행할 수 있기 때문에, 용량을 많이 절약할 수 있죠.
2-2. 여러 개의 RUN 명령어 합치기
도커에서 이미지를 빌드할 때, RUN 명령어는 새 레이어를 추가합니다. 따라서 여러 개의 RUN 명령어가 있으면, 이미지의 레이어 수가 많아지고 그에 따라 용량도 커집니다.
여러 개의 RUN 명령어를 하나로 합쳐서 실행하면 레이어 수를 줄여 이미지 크기를 최적화할 수 있습니다. 예를 들어, 아래처럼 여러 명령어를 하나로 합칠 수 있습니다.
# 비효율적인 방법
RUN apt-get update RUN apt-get install -y nginx
# 효율적인 방법
RUN apt-get update && apt-get install -y nginx
이렇게 하면 이미지를 더 가볍게 만들 수 있습니다.
2-3. 불필요한 파일 삭제
이미지 안에 캐시 파일이나 임시 파일 같은 불필요한 파일이 쌓이면 이미지가 커집니다. 이미지를 빌드한 후에 이런 파일을 꼭 삭제해 주세요.
예를 들어, 패키지를 설치한 후에는 패키지 관리자 캐시를 삭제하는 것이 좋습니다.
RUN apt-get update && apt-get install -y nginx \
&& rm -rf /var/lib/apt/lists/*
이렇게 하면 패키지를 설치할 때 생기는 불필요한 파일들을 제거하여 이미지 크기를 줄일 수 있습니다.
3. 멀티스테이지 빌드 사용하기
멀티스테이지 빌드는 도커에서 이미지를 최적화할 수 있는 또 다른 방법입니다.
애플리케이션을 빌드하는 과정에서 필요한 도구들은 있지만, 실제로 애플리케이션을 실행할 때는 불필요한 도구들이 있습니다.
이럴 때 멀티스테이지 빌드를 사용하면 빌드 도구는 포함하지 않고 최종 애플리케이션만 포함하는 이미지를 만들 수 있습니다.
멀티스테이지 빌드 예시
아래는 멀티스테이지 빌드를 사용한 간단한 예시입니다.
# 1단계: 빌드 환경
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 2단계: 최종 실행 환경
FROM alpine
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
이렇게 하면 Go 언어로 작성된 애플리케이션을 빌드하는 데 필요한 모든 도구는 첫 번째 단계에서만 사용되고, 최종 실행 환경에서는 실제로 빌드된 애플리케이션만 포함됩니다.
결과적으로 최종 이미지는 매우 작아집니다.
4. 이미지 관리하기
도커 이미지는 쉽게 관리할 수 있지만, 시간이 지나면서 불필요한 이미지나 중복된 이미지가 쌓일 수 있습니다.
이런 이미지를 관리하는 몇 가지 명령어를 소개합니다.
4-1. 이미지 목록 확인
현재 시스템에 저장된 이미지를 확인하려면 docker images 명령어를 사용합니다.
docker images
이 명령어는 현재 로컬에 있는 모든 도커 이미지를 보여줍니다.
이미지를 자주 업데이트하다 보면 비슷한 이름의 이미지들이 쌓일 수 있는데, 이때 어떤 이미지가 필요한지 확인할 수 있습니다.
4-2. 이미지 삭제
더 이상 필요하지 않은 이미지를 삭제하려면 docker rmi 명령어를 사용합니다.
docker rmi [이미지 ID 또는 이름]
모든 이미지를 한 번에 삭제하고 싶다면 다음 명령어를 사용할 수 있습니다.
docker rmi $(docker images -q)
이 명령어는 docker images -q 명령어로 이미지 ID만 가져와서 그 이미지들을 모두 삭제하는 방식입니다.
5. 캐시를 효율적으로 사용하기
도커는 이미지를 빌드할 때 캐시를 사용합니다.
캐시는 이미 빌드한 레이어를 재사용할 수 있게 도와주는데요, 이렇게 하면 같은 작업을 반복하지 않아 빌드 속도를 크게 줄일 수 있습니다.
하지만, 캐시를 잘못 사용하면 빌드 시간이 오히려 길어질 수 있으니 주의해야 합니다.
예를 들어, 이미지 내에서 자주 변경되는 파일을 먼저 복사하면 캐시가 제대로 동작하지 않을 수 있습니다.
자주 변경되지 않는 파일은 먼저 복사하고, 자주 변경되는 파일은 나중에 복사하는 것이 좋습니다.
# 비효율적인 방법
COPY . /app RUN apt-get update && apt-get install -y nginx
# 효율적인 방법
COPY package.json /app RUN apt-get update && apt-get install -y nginx COPY . /app
위의 예시에서 package.json 파일만 먼저 복사하고, 이후에 전체 애플리케이션 파일을 복사하면 도커 캐시를 더욱 효율적으로 사용할 수 있습니다.
6. 리눅스 명령어와 결합하여 자동화하기
도커 이미지를 관리할 때 리눅스 명령어와 결합하면 자동화가 가능합니다. 예를 들어, 아래 명령어는 오래된 이미지들을 자동으로 삭제합니다.
docker images --filter "dangling=true" -q | xargs docker rmi
위 명령어는 더 이상 사용되지 않는 "떠도는(dangling)" 이미지를 찾아서 모두 삭제합니다.
xargs를 사용하여 이미지를 일괄적으로 삭제할 수 있죠.
7. 도커 이미지 최적화: 정리
이미지를 최적화하는 것은 도커에서 애플리케이션을 빠르고 효율적으로 실행하는 데 매우 중요합니다.
작은 베이스 이미지를 선택하고, 불필요한 파일을 삭제하고, 멀티스테이지 빌드를 사용하는 등 다양한 방법으로 이미지를 최적화할 수 있습니다.
공식 문서 참조
예시 코드
# 작은 베이스 이미지 사용 예시
FROM alpine:latest RUN apk add --no-cache nginx
# 이미지 목록 확인
docker images
# 이미지 삭제
docker rmi $(docker images -q)
과제
- Alpine 이미지를 사용하여 최소한의 리소스로 애플리케이션 이미지를 만들어보세요.
- 멀티스테이지 빌드를 사용하여 애플리케이션 빌드 도구는 포함하지 않고 최종 실행 파일만 포함된 이미지를 만들어보세요.
- docker images --filter "dangling=true" -q | xargs docker rmi 명령어를 사용해 오래된 이미지를 자동으로 삭제하는 스크립트를 작성해보세요.
이번 포스팅에서는 도커 이미지를 최적화하는 다양한 방법을 알아보았습니다.
다음 포스팅에서는 도커 파일을 작성하는 방법에 관해서 다뤄보겠습니다.
'Docker > Docker 강의' 카테고리의 다른 글
[Docker 강의 7편] 도커 이미지 빌드 (0) | 2024.09.23 |
---|---|
[Docker 강의 6편] 도커 파일 작성하기 (Dockerfile) (0) | 2024.09.19 |
[Docker 강의 4편] 도커 네트워크와 볼륨 관리 (0) | 2024.09.16 |
[Docker 강의 3편] 도커 기본 명령어 사용법 (0) | 2024.09.15 |
[Docker 강의 2편] 도커 설치 및 기본 설정 (0) | 2024.09.13 |