LabHub

이미지 빌드 · 멀티스테이지와 경량화 · 실습

멀티스테이지로 깎아내기

LabHub 에서 이어서 보기

이 실습은 진짜 VM 에서 돕니다

이 상자는 파드가 아니라 KubeVirt 가 띄운 가상머신입니다. 리눅스 커널이
따로 돌고 systemd 가 실제로 서비스를 관리하며, docker 는 흉내가 아니라
진짜 도커 엔진입니다. docker run 으로 띄운 컨테이너는 실제로 프로세스가
되고 docker execdocker logs 도 그대로 동작합니다.

예전에는 이 실습이 파드 안에서 돌았습니다. 커널 권한을 전부 내려놓은 상자라
컨테이너를 띄우는 단계가 막혀 있었고, 그래서 이미지 아카이브를 직접 풀어
보는 우회로 배웠습니다. 이제 우회가 필요 없습니다.

알아 둘 것이 둘 있습니다.

목표

빌더 스테이지에서 만든 산출물만 최종 이미지로 옮겨, 같은 결과물을 훨씬
작은 이미지로 만드는 과정을 크기 숫자로 확인합니다.

왜 중요한가

이미지 크기는 미관의 문제가 아니라 배포 속도와 롤백 속도의 문제입니다.
노드가 스케일아웃될 때마다, 롤백할 때마다 그 크기를 다시 받습니다. 그리고
크기를 줄이는 가장 큰 지렛대는 압축이나 정리가 아니라 "**최종 이미지에
들어가면 안 되는 것을 애초에 그 스테이지에서 만들지 않는 것**"입니다.
레이어는 되감기지 않기 때문에, 이 원칙을 어기면 나중에 아무리 지워도
크기가 돌아오지 않습니다.

단계

1. /root/build3 을 만들고 /root/build3/Dockerfile 에 스테이지를 둘 만듭니다. 첫 스테이지는 python:3.12-alpine 을 쓰고 이름은 builder 이며, /out/app.txtbuilt-in-builder 를 써 넣습니다. 두 번째 스테이지는 alpine:3.20 입니다. labhub/ms:v1 로 빌드합니다.
2. 최종 스테이지에서 빌더의 /out/app.txt/app/app.txt 로 복사하도록 고치고 labhub/ms:v2 로 빌드합니다. 실행해서 파일을 읽으면 built-in-builder 가 나와야 합니다.
3. /root/build3/fat.Dockerfile단일 스테이지로 같은 결과물을 만드는 버전(베이스는 python:3.12-alpine)을 작성하고 labhub/ms:fat 으로 빌드합니다.
4. 첫 스테이지만 빌드해 labhub/ms:builder 이미지를 만듭니다. 그 안에는 /out/app.txt 가 있어야 합니다.
5. Dockerfile 최종 스테이지에 busybox:1.36 이미지에서 /bin/busybox/app/busybox 로 직접 복사하는 줄을 추가하고 labhub/ms:v3 로 빌드합니다.
6. labhub/ms:v3 를 실행해 python3 가 없는지 확인합니다. 이미지 크기는 60MB 미만이어야 합니다.
7. /root/build3/scratch.Dockerfile 을 만들어 FROM scratch 위에 busybox:1.36/bin/busybox 만 올리고, 인자로 받은 문자열을 그대로 출력하도록 ENTRYPOINT배열 형식으로 지정합니다. labhub/ms:scratch 로 빌드하고, scratch-works 를 인자로 주면 그 문자열이 출력되어야 합니다.
8. /root/build3/size.md 에 아래 네 줄을 실제 값으로 적습니다.

fat_mb=<labhub/ms:fat 크기(MB)>slim_mb=<labhub/ms:v3 크기(MB)>scratch_mb=<labhub/ms:scratch 크기(MB)>reduction_pct=<(fat_mb - scratch_mb) / fat_mb * 100 의 정수부>

참고

단계 8개

  1. 스테이지 두 개 만들기
  2. 산출물만 가져오기
  3. 단일 스테이지와 크기 비교
  4. 중간 스테이지만 빌드하기
  5. 다른 이미지에서 직접 복사하기
  6. 빌드 도구 남기지 않기
  7. 빈 베이스 위에 올리기
  8. 크기 보고서