JUST WRITE

Docker 제품 만들기(3) - Image 빌드 개선 본문

MLOps/Docker

Docker 제품 만들기(3) - Image 빌드 개선

천재보단범재 2021. 10. 2. 16:16
2020년에 다니고 있는 회사 내부 프로젝트에서 기술적인 부분만 발췌해서 정리한 글입니다.

 

Image 빌드 개선

제품들의 Docker Image를 구성하기는 했지만 전혀 가볍지가 않았다.

기본 500MB가 되는 Docker Image를 고객사에 배포하는 것은 옳지 않았다.

그래서 효율적인 Image를 만들기 위해 빌드 개선 작업을 진행하였다.

기존에 작업하였던 Dockerfile를 수정하였다.

경량화

Docker Container는 Scale in/out을 통해 중지, 삭제, 재생성될 수 있다.

이러한 이유로 경량화된 Container를 구성하도록 해야 한다.

기본 Image 변경

경량화 첫 번째 작업은 기본 Image를 변경하였다.

기본 Image를 경량화된 Image를 사용해서 크기를 줄인다.

Container내 Process에 필요한 최소한의 패키지만 설치된 환경을 구성하는 것이다.

가볍고 간단하게 보안성을 목적으로 개발된 Alpine Linux Image로 변경하였다.

제품 Image 변경 전 기본 Image 변경 후 기본 Image
Web Application Image tomcat-8.5-jdk-openjdk-slim tomcat-8.5-alpine
Java Daemon Program Image openjdk-8-slim openjdk-8-jre-alpine

변경 전은 Debian이었으므로 설치가 필요한 Package를 수정하였다.

  • 유지 : procps, vim
  • 변경
    • libfontconfig1 -> fontconfig, ttf-dejavu
    • iputils-ping > iputils
  • 추가 : bash
# Web Applciation Image
# 변경 전
FROM tomcat:8.5-jdk8-openjdk-slim
RUN apt-get update && apt-get install -y procps
RUN apt-get install -y libfontconfig1 vim iputils-ping

# 변경 후
FROM tomcat:8.5-alpine
RUN apk update && apk add --no-cache procps fontconfig vim iputils

Caching으로 인한 순서 고려

Docker Engine은 1번 이상 Build한 Dockerfile의 Image를 Sciprt 라인 단위로 Caching 한다.

자주 변경될 수 있는 COPY와 같은 명령어는 뒤로 배치한다.

변경 후 다시 Build 하더라도 기존 Command는 수행되지 않고 변경된 COPY부분 포함 아랫부분만 수행하게 된다.

.dockerignore 사용

build시 Docker Engine은 Dockerfile이 있는 경로, 하위 경로를 Docker Context에 저장 후 작업을 수행한다.

직접적으로 사용하지 않는 파일들도 Context에 포함되어 Build 성능을 저하할 수 있다.

이 경우 .dockerignore 파일을 통해 제외대상을 설정하여 Build 성능을 높인다.

example/hello.txt
example/*.cpp
wo*
*.cpp
.git
.svn

Layer 최소화

Docker Image의 Layer 수는 Dockerfile의 예약어만큼 생성된다.

Layer 수가 증가할수록 Image 파일의 크기, Build 시간이 증가된다.

합칠 수 있는 Command는 합쳐서 Layer 수를 줄인다.

# 변경 전
RUN apk update
RUN apk add --no-cache procps fontconfig vim iputils

# 변경 후
RUN apk update && apk add --no-cache procps fontconfig vim iputils

Image 비교

위와 같은 작업들로 Image 빌드 개선 작업을 진행하였다.

아래와 같이 제품 Image Dockerfile 변경 전과 변경 후로 비교해보았다.

변경 전 Dockerfile

FROM tomcat:8.5-jdk8-openjdk-slim

ENV CATALINA_HOME /usr/local/tomcat
WORKDIR $CATALINA_HOME

ENV MANAGER_USER swjeong
ENV MANAGER_PASS 123456

RUN apt-get update && apt-get install -y procps
RUN apt-get install -y libfontconfig1

# war 파일 복사
COPY target/product.war /usr/local/tomcat/webapps/product.war

# java option 추가
ENV JAVA_OPTS="$JAVA_OPTS -Xms4096M -Xmx4096M"

# docker container의 timezone을 서울로 변경
ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

WORKDIR /usr/local/tomcat

# 8080포트
EXPOSE 8080

변경 후 Dockerfile

FROM tomcat:8.5-alpine

#ENV CATALINA_HOME=/usr/local/tomcat
ENV MANAGER_USER=swjeong
ENV MANAGER_PASS=123456
ENV JAVA_OPTS="$JAVA_OPTS -Xms4096M -Xmx4096M"
ENV TZ=Asia/Seoul

#WORKDIR $CATALINA_HOME

RUN apk update && apk add --no-cache procps fontconfig vim iputils

# war 파일 복사
COPY target/product.war /usr/local/tomcat/webapps/product.war

# docker container의 timezone을 서울로 변경
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

EXPOSE 8080

** 제품명, 정보가 드러나는 부분은 임의 명칭으로 대체

Image 스펙 비교

Layer 수는 많이 줄이지 못했지만 Image 크기를 50% 정도 줄일 수 있었다.

제품 Image
Layer 수 Image Size
변경 전 변경 후 변경 전 변경 후
Web Application Image 12 9 501MB  290MB
Java Daemon Program Image 10 9 480MB  261MB

 

다음 글에서는 고객사에 Docker 제품을 배포 방안에 대해 공유하겠습니다.

728x90
반응형
Comments