2022. 2. 25. 16:36ㆍDevOps/Docker & kubernetes
도커 빌드를 통해 생성되는 이미지의 용량을 줄이는 개념이다. 도커 이미지의 크기가 작아질 수록 이미지를 푸쉬하는 속도도 빨라지고, 외부 이미지를 가져오는 속도도 빨라지고, 컨테이너를 더 빨리 만들 수 있게되며, 해당 호스트에서 동일 용량대비 보유 도커 이미지의 수가 늘어나게 될 것이다. 즉 도커 컨테이너 서비스를 운용함에 있어서 중요한 개념중 하나라고 할 수 있다. 방법론은 굉장히 다양하지만, 가장 많이 사용되는 방법들에 대해 알아보도록 하자.
1. 필수 페키지, 파일만 추가하기
서버에 필요한 모든 페키지를 설치하는 경우가 종종 있다.(git, AWS CLI...등등등) 이런 다양한 도구들은 어쩌다 사용하거나 거희 사용하지 않는 등의 경우일 수 가 있다. 이런 페키지를 굳이 이미지에 설치하게 된다면 이미지 자체가 무거워지며 용량이 늘어나게 된다. "컨테이너"라는 개념 자체는 하나의 프로세스를 실행하는것에 맞게 설계된 프로그렘이기 때문에 굳이 잡다한 툴들을 설치할 필요가 없다는 점이다.
2. 컨테이너 레이어의 수 자체를 줄이기
도커파일의 지시어 숫자와(run명령어) 같다. 도커 파일 안의 지시어수를 줄이면 줄일 수록 레이어의 수 가 줄어들게 된다. RUN지시어가 하나의 도커 컨테이너 레이어를 이루게 되는데, 이 명령어들을 하나의 run으로 통합함으로써 하나의 레이어로 다루어 용량을 줄일 수 있다.
# Install needed packages
# &&이라는 명령어를 통해 여러줄의 run 명령어를 하나로 통합하였다.
# 또한 cache값을 필요로 하지 않기때문에 no-cache를 사용하였음을 알 수 있으며 불필요한 파일을 삭제함을 확인할 수 있다.
RUN \
apk add --no-cache bash curl git && \
git clone https://github.com/course-hero/slacktee /slacktee && \
apk del --no-cache git
RUN chmod 755 /slacktee/slacktee.sh
3. 베이스 이미지 자체를 경량 으로 만들기
베이스 이미지를 선택할때 애초에 가벼운 베이스를 선택하는 것 이다. 대표적으로는 debian의 slim, alpine의 linux Distribution(배포판), stretch와 같은 것들이 있다.
#
# nodejs-server
#
# build:
# docker build --force-rm -t nodejs-server .
# run:
# docker run --rm -it --name nodejs-server nodejs-server
#
# FROM 부분만 바뀐것을 확인하면 된다.
# FROM node:16-alpine, 16-slim 과 같은 명령어를 입력하면 된다.
FROM node:16-alpine
LABEL maintainer="Dockertest Park <test@test.com>"
LABEL description="Simple server with Node.js"
# Create app directory
WORKDIR /app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
이러한 명령어를 통해 이미지를 만들게 되면 기존의 이미지보다(906mb) 훨씬 더 작은 용량(slim-175, apline-110mb, multi의 경우 빌드때 사용하는 의존성이 적기 때문에 3mb밖에 줄지 않았다.)로 만들 수 있음을 확인할 수 있다.
4. 멀티 스테이지 빌드기능을 사용하기
빌드 스테이지와 릴리즈 스테이지를 각각 나누어서 빌드에 필요한 의존성은 빌드에서 처리하고 릴리즈에서는 결과값만 복사해서 경량화 시킬 수 있다.
실제로 운영 환경에서 빌드를 하게 될 경우 멀티 스테이지를 사용할때 경랑화를 굉장히 잘 할 수 있다.
#
# nodejs-server
#
# build:
# docker build --force-rm -t nodejs-server .
# run:
# docker run --rm -it --name nodejs-server nodejs-server
#
#from지시어에 as라는 새로운 명령어가 있음을 확인할 수 있다.
from을 통해서 정의되는 도커의 내용을 하나의 블록으로 형성하여
base라는 임시 이미지 이름을 부여한다. 이러한 from블록을 여러가지로 정할 수 있다.
하단의 build, release를 통해 확인할 수 있다.
이 둘은 base를 기반으로 하고있으며 base의 레이어를 사용하겠다 라는 의미이다.
FROM node:16-alpine AS base
LABEL maintainer="dockerTest Park <test@test.com>"
LABEL description="Simple server with Node.js"
# Create app directory
WORKDIR /app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
# npm install을 통해 package json파일을 기반으로 하여 nodejs를 실행하게 된다.
FROM base AS build
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# package json파일을 추가한 시점에서 copy의 from빌드를 통해 build에서 파일을 복사해온다.
FROM base AS release
COPY --from=build /app/node_modules ./node_modules
# Bundle app source
COPY . .
#포트는 8080이다.
EXPOSE 8080
CMD [ "node", "server.js" ]
'DevOps > Docker & kubernetes' 카테고리의 다른 글
Docker compose 사용하기(다양한 컨테이너 관리하기) (0) | 2022.02.26 |
---|---|
docker system 명령어와 데몬 디버깅 (0) | 2022.02.25 |
Docker Hub 저장소 활용하기 (0) | 2022.01.28 |
Docker images 압축과 불러오기 (0) | 2022.01.28 |
Dockerfile 문법정리 (0) | 2022.01.28 |