HotFoxy
불여우의 전직 이야기
게임 서버 개발자가 되어 보죠!
전체 방문자
오늘
어제
  • 분류 전체보기 (135)
    • 연구한 이야기 (26)
      • 깊게 공부해보기 (7)
      • 문제 해결 이야기 (12)
      • 맡은 업무 이야기 (6)
    • 전직 이야기 (0)
      • 1년이라는 시간 (5)
      • 프로카데미 이야기 (5)
    • 공부한 이야기 (87)
      • 알고리즘 (7)
      • 리눅스 (11)
      • 클라우드 (24)
      • 윈도우 OS (17)
      • 윈도우 소켓 프로그래밍 (11)
      • 네트워크 (16)
      • Docker & K8S (0)
      • 기타 (1)
    • 자격증 이야기 (12)
  • MSB : Mad Square's Brawl
  • GITHUB

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
HotFoxy

불여우의 전직 이야기

연구한 이야기/문제 해결 이야기

dockerfile은 죄가 없다.

2024. 2. 24. 21:52

업무를 진행하며, 다양한 서버와 인프라를 도커 환경으로 묶어 봤다.
이 때, 어떨 때는 도커 빌드 속도가 빨랐다가 어느 때는 느리고, 이런저런 문제를 겪기도 했다.

dockerfile을 작성할 때 유의해야 할 세 가지를 뽑아 정리해 보았다.

1. 레이어 개수에 유의하기

Dockerfile의 각 명령어는, 대부분 새로운 레이어를 생성한다.
불필요하게 많은 레이어는 빌드 시간과 이미지 크기를 증가시켜, 효율성을 저하시킬 수 있다.

기존에는 가독성을 위해 다음과 같이 작성했었다.

FROM alpine:latest

RUN apk update
RUN apk add rust
RUN apk add cargo
...

하지만 위 dockerfile의 경우 벌써 네개의 레이어가 만들어진다.
따라서, 아래처럼 개선할 수 있다.

FROM alpine:latest

RUN apk update && apk add rust cargo

2. 레이어 캐싱 효율적으로 사용하기

docker는 빌드 과정에서 레이어를 캐싱하고 재사용함으로서 빌드 시간을 절약할 수 있다.

하지만, 아래처럼 생각 없이 dockerfile을 작성했다가는,
캐싱 없이 항상 모든 레이어를 재빌드하게 될 수도 있다.

FROM alpine:latest

COPY . /app
RUN apk update && RUN apk add python3 cargo
...

이 경우, COPY 명령어를 통해 복사되는 파일들이 변경되면,
이후의 모든 레이어는 캐시를 믿을 수 없게 된다.

위 경우, 종속성 및 빌드 도구 패키지의 설치가 끝난 다음,
실제 컨텐츠의 docker 복사가 이루어져도 되는 상황이기에,
다음과 같이 개선할 수 있다.

FROM alpine:latest

RUN apk update && apk add python3 cargo
COPY . /app
...

이 상황에서는, RUN 명령어 구문은 빌드 시에 항상 재사용되게 됨으로서,
쌓이게 되면 많은 자원을 아낄 수 있게 된다.

3. 레이어 크기 관리하기 : 멀티 스테이징

도커에 조금 익숙해졌을 무렵,
내가 만든 도커 이미지의 크기가 1GB가 넘어가는 것을 보고,
이대로는 안되겠다 싶어 개선해보려 다음과 같이 작성했었다.

FROM alpine:latest

RUN apk update && apk add rust cargo ...
COPY . /app
RUN cargo build ...
RUN apk del rust cargo && rm -rf /app/src ...
...

이렇게 작성하면, 빌드때에만 필요했던 패키지가 정리되기에,
도커 이미지 크기도 그만큼 줄어들어 도움이 될 줄만 알았다.

하지만, docker의 각 레이어는, 명령어에 따른 '변경 사항'을 기록한다.

따라서, 한번 생성된 레이어들의 크기는 변하지 않고,
저 RUN apk del은 패키지를 지운다는 데이터 레이어를,
오히려 추가만 할 뿐이었다.

멀티 스테이지 빌드

위 문제를 해결하기 위해 찾아보았고,
멀티 스테이지 빌드를 통해 깔끔히 해결할 수 있었다.

# 빌드 스테이지
FROM alpine as build-stage
RUN apk update && apk add rust cargo
COPY . /app
RUN cargo build ...

# 최종 이미지
FROM alpine
COPY --from=build-stage /app /app

위처럼 빌드 이미지를 통해 얻어진 '결과 패키지'만,
깨끗한 base 이미지로 가져오고,
필요 시 동작에 필요한 패키지만 추가함으로서,
이미지 크기를 획기적으로 줄일 수 있다.

또한, 빌드를 위해 복사된 소스 코드나 빌드 리소스들은,
빌드 이미지에만 남고 최종 이미지에는 빠지게 된다!

dockerfile을 작성할 때 얼마나 신경쓰냐에 따라,
이후 수많이 빌드를 할 때 누적되면 큰 차이가 된다!

저작자표시 (새창열림)

'연구한 이야기 > 문제 해결 이야기' 카테고리의 다른 글

mysql connect 시에 timezone 관련해서 에러가 나요!  (2) 2024.03.02
Android Studio NDK breakpoint가 잡히지 않아요!  (0) 2024.03.02
jenkins(image) 에서 docker buildx를 사용하고 싶어요!  (0) 2023.12.22
CMake 와 static library에서의 종속성 관리  (0) 2023.12.16
서버 스트레스테스트 시 일정 주기로 멈춰요!  (0) 2023.12.09
    '연구한 이야기/문제 해결 이야기' 카테고리의 다른 글
    • mysql connect 시에 timezone 관련해서 에러가 나요!
    • Android Studio NDK breakpoint가 잡히지 않아요!
    • jenkins(image) 에서 docker buildx를 사용하고 싶어요!
    • CMake 와 static library에서의 종속성 관리
    HotFoxy
    HotFoxy
    1년 동안의 고군분투 전직 이야기! ..가 완료되어, 게임개발자로 살아남는 이야기!

    티스토리툴바