Single-platform 이미지 vs Multi-platform 이미지
Docker 이미지에는 크게 두 가지 유형이 있다
- Single-platform 이미지: 오직 하나의 플랫폼(x86_64, arm64 등) 에서만 동작하도록 만들어진 이미지
- Multi-platform 이미지: 여러 플랫폼용으로 빌드된 이미지들을 하나로 묶은 통합 이미지로 사용 환경에 따라 자동으로 알맞은 플랫폼 버전을 선택해 실행
다중 플랫폼 이미지는 동일한 애플리케이션을 여러 아키텍처용으로 따로 빌드한 뒤, 이들을 하나의 이미지처럼 포장한 것이다. 내부에는 각 아키텍처마다 별도의 설정(config)과 실행 파일 집합(layer)이 존재하며, 그 위에 목차 역할을 하는 manifest list가 하나 더 있다. 이 구조 덕분에 사용자는 단일 이미지 이름만 기억하면 되고, Docker가 알아서 현재 사용자의 시스템에 맞는 아키텍처 버전을 선택해 준다.

- Manifest: 하나의 이미지에 대한 정보를 담고 있는 메타데이터 블록으로, 어떤 레이어로 구성되어 있고, 어떤 설정(config)을 사용하는지를 정의
- Layers: 실제 파일 시스템 구조를 이루는 이미지 레이어들 ex) base image, 설치된 패키지 등
- Config: 이미지 실행 환경에 대한 설정 정보 ex) 엔트리포인트, 환경변수 등
멀티 플랫폼으로 빌드한 이미지의 경우 그림처럼 Manifest 가 플랫폼 마다 각각 따로 존재하며, 그 아래에는 해당 플랫폼에 맞는 Layers 와 Config 가 연결되어 있으므로, Docker 가 사용자의 시스템 아키텍처를 기준으로 자동으로 해당하는 manifest 를 pull 할 수 있는 것이다.
Docker Buildx 개념
[Docker Buildx 는 무엇인가?]
Docker Buildx는 여러 플랫폼용 이미지를 동시에 빌드할 수 있도록 지원하는 Docker CLI의 확장 기능이다. 내부적으로 BuildKit을 사용한다.
참고) 플랫폼 기본 아키텍처 구분은 다음과 같다.
- x86_64(linux/amd64): 대부분의 데스크탑/서버 CPU
- ARM64(linux/arm64): M1/M2/M3 Mac, AWS Graviton 등
- ARMv7(linux/arm/v7): 구형 ARM 기반 보드 (라즈베리 파이 등)
[플랫폼별 호환되는 이미지를 왜 만들어야 하는가?]
컨테이너는 가상 머신처럼 커널을 포함하지 않고 호스트 OS 커널을 그대로 사용한다. 그렇기 때문에 컨테이너의 바이너리 코드가 호스트의 CPU 아키텍처와 호환되어야 실행할 수 있다.
- ex) amd64용으로 빌드된 이미지를 arm64 Mac에서 실행하려고 할 경우 호환되지 않기 때문에 실행할 수 없다.
이때 buildx 멀티 플랫폼 빌드(Multi-platform build) 를 이용하면 애플리케이션을 여러 아키텍처용으로 각각 빌드하고, 이를 하나의 통합 이미지로 구성할 수 있다. 사용자는 단일 이미지만 배포하면 되고, 플랫폼에 따라 자동으로 적절한 아키텍처의 이미지가 선택되어 실행된다. 따라서 ARM 기반 개발용 머신이나 x86_64 기반 AWS EC2 인스턴스 등 서로 다른 하드웨어에서도 별도 에뮬레이션 없이 동일한 이미지를 실행할 수 있다.
참고) 에뮬레이터와 에뮬레이션 (Wikipedia)
- 에뮬레이터: 게스트 시스템과 동일한 방식으로 동작하도록 설계된 컴퓨터 시스템이다. 즉, 두 번째 시스템(호스트)이 첫 번째 시스템(게스트)을 모방하고 복사(imitate & replicate)하는 것이다.
- 에뮬레이션: 소프트웨어적으로 만든 장치가 정말로 다른 장치라고 믿도록 "속이는 것이다". 예를 들어, ARM64 머신이 x86_64처럼 "가짜로" 동작하게 만들어, 해당 이미지를 실행할 수 있게 해주는 과정이 에뮬레이션에 속한다.
예시로 MAC 에서 Docker 이미지 빌드 환경은 ARM64 기반이다. 하지만 우리가 실제로 배포하는 서버는 대부분 AWS EC2와 같은 x86_64 기반 환경이므로 이로 인해 로컬(Mac)에서 만든 이미지를 AWS에 배포했을 때 아래와 같이 호환성 문제가 발생한다.

이때 Docker Buildx를 통해 멀티 아키텍처(Multi-platform) 지원 이미지를 빌드함으로써 해결할 수 있다.
Buildx 로 Multi-platform
[Driver 와 Builder]
Buildx 를 사용하려면, Driver 를 기반으로 Builder 를 만든 후 Builder 를 이용해서 멀티 플랫폼 이미지를 빌드할 수 있다.
Builder 는 Buildx가 사용하는 빌드 실행 환경이다. 각 빌더는 드라이버(driver) 를 기반으로 동작한다. 여러 빌더를 만들 수 있고, 그중 하나를 기본 빌더로 선택할 수 있다.
Driver 는 빌더가 어디서, 어떻게 빌드를 실행할지를 정하는 방식이다.
- docker 드라이버는 기존 docker build으로 로컬 Docker 데몬이 빌드를 수행하는 방식이다.
- docker-container 드라이버는 Buildx가 내부적으로 BuildKit 전용 컨테이너를 생성해 빌드를 진행하는 방식으로, 로컬 데몬과 분리되어 독립적으로 실행된다.
멀티플랫폼 지원 이미지를 빌드하려면 docker-container 드라이버를 사용해야 한다.
docker buildx ls 로 빌더를 확인할 수 있다.

default와 desktop-linux는 Docker Desktop 설치 시 자동으로 생성되는 기본 빌더들이며, *이 붙은 것은 현재 활성화된 빌더라는 의미다. (사진에서 desktop-linux)
[빌더 생성 및 관리 방법]
docker buildx create 로 빌더를 만든다. 기본적으로 --driver 옵션을 붙이지 않으면 docker-container 빌더가 자동 선택된다.

- --name: 생성할 빌더의 이름
- --use: 해당 빌더를 현재 기본 빌더로 설정
- --driver docker-container: 멀티 플랫폼 지원을 위한 BuildKit 컨테이너 기반 드라이버 사용
- --bootstrap: 빌더 생성 후 즉시 초기화
buildx use 를 이용해 기본 생성 빌더로 지정한다.

docker buildx inspect --bootstrap 으로 기본 생성 빌더를 초기화한다.

초기화하면 buildkit 이미지를 사용한 컨테이너가 실행된다.

빌더 삭제시 buildx rm 을 이용한다.

생성과 동시 기본값 지정, 초기화를 동시에 수행하면 편리하다.

[빌드 후 이미지 push 방법]
docker buildx build 를 사용해 buildx를 사용해 BuildKit 기반으로 이미지를 빌드할 것을 지정한다.
--platform 은 어떤 아키텍처용으로 이미지를 만들 것인지 지정하는 것으로 여러 플랫폼을 ,로 나열하면 멀티 플랫폼 이미지를 빌드할 수 있다.
일반적으로 로컬에서만 돌릴 이미지라면 buildx 를 사용할 이유가 없을 것 같다. 간단하게 MAC 에서 linux/amd64 이미지를 빌드 후 Docker Hub 나 ECR 에 Push 하려면 아래처럼 할 수 있다.
# ECR
docker buildx build \
--platform linux/amd64 \
-t ECR주소/이미지명:태그 \
--push .
# Docker Hub
docker buildx build \
--platform linux/amd64 \
-t dockerhub_username/image_name:tag \
--push .
References
'Infra' 카테고리의 다른 글
| yaml 파일을 읽고 수정할때 유용한 yq 알아보기 (0) | 2025.06.19 |
|---|---|
| [Linux] 환경변수 (Environment Variable) 개념과 활용 (0) | 2025.05.24 |
| [Docker] docker prune 으로 사용하지 않는 오브젝트 정리 (0) | 2024.11.29 |