본문 바로가기

devops/docker

도커 빌드 속도를 높히고, 도커 이미지 크기를 줄이는 방법

도커의 빌드 사이클 속도를 높이고 가벼운 도커 이미지를 만드는 방법을 알아보겠습니다.

Dockerfile 명령어

  • FROM : 부모 이미지를 지정
  • LABEL : 메타 정보, Maintainer 정보 등을 지정, 자유롭게 사용가능함
  • ENV : 환경변수 지정
  • RUN : 컨테이너에 패키지를 설치하는 등의 명령어를 실행하고 이미지 레이어를 생성
  • COPY : 파일과 디렉토리를 컨테이너에 복사
  • ADD : 파일과 디레토리를 컨테이너에 복사하는 것은 COPY 와 동일하지만 tar파일은 자동으로 언팩함
  • CMD : 실행 컨테이너의 대한 명령어나 인수를 전달함, CMD는 한개만 지정 가능
  • WORKDIR : 작업 디렉토리를 지정함(디렉토리가 없으면 생성함)
  • ARG : 도커 이미지를 빌드할때 Docker에 전달하는 변수를 정의함
  • ENTRYPOINT : 실행 컨테이너에 며령어나 인수를 전달함
  • EXPOSE : 포트를 노출시킴
  • VOLUME : 영구 데이터에 접근 및 저장하기위한 디록토리 마운트 지점을 생성

캐시

도커는 빠른 빌드를 위해 캐시를 제공합니다.

이미지를 만들때 Dockerfile에 따라 단계별로 빌드를 진행하고, 도커는 캐시에서 기존에 캐시에 중간 이미지가 존재하면 중간이미지를 생성하는 대신 재사용합니다.
혹시 Dockerfile을 수정한 경우 해당 중간이미지의 캐시는 무효화되어 다시 빌드됩니다.
즉, Dockerfile 위에서 순서대로 이미 캐시가 있으면 재사용하고 그렇지 않으면 캐시는 무효화됩니다.

다른 명령어와 다르게 ADDCOPY 명령어는 도커가 파일의 내용을 확인하고 캐시를 체크합니다.
참조된 파일의 체크섬은 기존 캐시의 중간 이미지의 체크섬과 비교됩니다.
파일 내용이나 메타 데이터가 변경된 경우에도 역시 캐시는 무효화됩니다.

캐시를 사용 팁

  • --no-cache=true 옵션을 사용하여 도커 빌드에서 캐시를 사용하지 않도록 할 수 있습니다.

  • Dockerfile을 일부를 변경하면 그 명령어의 다음부부은 모두 재빌드됩니다. 가능한한 자주 변경되는 부분을 Dockerfile 나중에 정의하세요.

  • 캐시가 누락되는 것을 방지하기위해 RUN apt-get updateapt-get install은 다음과 같이 체인으로 연결하세요.

    • RUN apt-get update && apt-get install <<packages>>
  • pip와 같은 패키지 인스톨러를 사용할 경우에는 아래와 같이 파일을 전달받아 오래된 패키지 리스트를 받지 않도록 하세요.

    COPY requirements.txt /tmp/
    RUN pip install -r /tmp/requirements.txt
    COPY . /tmp/

사이즈 줄이기

사이즈가 작은 베이스 이미지를 이용할 것!!!

Apline 베이스 이미지는 리눅스 배포판으로 5MB로 메우 작은 배포판입니다.
만약 컨테이너에 Python이 필요한 경우에는 Alpine은 매우 훌륭한 절충안일 것입니다.
print("Hello World")를 출력하는 컨테이너를 만드는데 불과 85MB면 충분합니다.

FROM python:3.7.2-alpine3.8
COPY . /app
ENTRYPOINT [“python”, “./app/my_script.py”, “my_var”]

멀티스테이지 빌드(Multistage Builds)

멀티스테이지 빌드는 여러 FROM 명령어를 사용합니다.
하나의 스테이지에서 다른 스테이지로 빌드 아티팩트를 복사해 넘겨줄 수 있습니다.
최종적으로 원하지 않는 것은 삭제되어 전체 이미지 크기는 줄어듭니다.

멀티스테이지 빌드 예제

FROM golang:1.7.3 AS build
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=build /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]

위 도커파일에서 COPY --from=을 이용하여 다른 스테이지의 아티팩트를 받아올 수 있습니다.

dockerignore

.dockerignore파일은 .gitignore파일과 비슷합니다.
도커 빌드시 빌드에 제외할 파일을 지정합니다.

도커 컨테이너 사이즈 체크

  • 실행중인 컨테이너의 대략적인 사이즈를 확인하려면 docker container ls -s 명령어를 사용하세요
  • docker image ls 명령어로 도커 이미지의 사이즈를 확인할 수 있습니다.
  • 이미지를 구성하는 중간 이미지의 사이즈를 확인하려면 docker image history my_image : my_tag 명령어를 사용하세요.
  • docker image inspect my_image:tag 명령어를 실행하면 각 레이어의 크기를 포함해서 이미지에 대한 많은 정보를 확인할 수 있습니다.
  • dive 패키지를 이용하면 좀 더 간편하게 레이러를 확인 할 수 있습니다.