반응형
x86 환경에서 Docker Buildx를 사용하여 이미지를 ARM용으로 빌드해서 ECR에 푸시해 보자
이전에 분명 m1의 docker 빌드 후 배포 시 format 문제로 글을 올린 적이 있었다. 그때는 format 오류가 발생한 이유는 내 로컬 PC가 m1맥북이고 EC2가 x86을 사용하는 t3.small 인스턴스였기 때문이었는데 이런 경우에는 당연히 로컬에서 빌드하면 arm용 이미지로 빌드되었기 때문에 배포하면 아키텍처가 다르다고 나왔다. 지금은 반대의 상황일 때의 해결방법이다. 만약 내 pc가 x86 아키텍처이고 ECS의 인스턴스가 arm이라면 어떻게 해야 할까? 이것에 대해 설명하도록 하겠다. 이 내용은 다음 편에 작성될 CodeBuild에서 arm 이미지를 빌드하는 과정에서 배우게 된 내용이니 CI/CD에 대해서 궁금했다면 이번 편이 아닌 다음 편을 확인하도록 하자
exec format 관련 오류코드
exec /usr/bin/java: exec format error
1.Docker Buildx란?
Docker Buildx는 Docker의 고급 빌드 도구로, 다양한 플랫폼과 아키텍처에 대한 이미지 빌드를 가능하게 하는 확장 기능이다. 이 도구는 BuildKit에 기반을 두고 있으며, Docker 이미지의 빌드 및 배포 과정을 효율적이고 유연하게 만들어준다.
1-1. 주요 특징 및 장점
- 멀티 플랫폼 빌드 지원
- Docker Buildx를 사용하면 하나의 커맨드로 여러 플랫폼(예: ARM, x86-64)을 대상으로 하는 이미지를 동시에 빌드할 수 있다. 이는 크로스 컴파일링을 간소화하고, 다양한 환경에서의 배포를 용이하게 만든다.
- Docker Buildx를 사용하면 하나의 커맨드로 여러 플랫폼(예: ARM, x86-64)을 대상으로 하는 이미지를 동시에 빌드할 수 있다. 이는 크로스 컴파일링을 간소화하고, 다양한 환경에서의 배포를 용이하게 만든다.
- 성능 최적화
- BuildKit의 기능을 활용하여, Docker 이미지 빌드 과정에서 캐싱 및 병렬화를 통해 빌드 시간을 단축할 수 있다. 또한, 불필요한 단계를 건너뛰어 리소스 사용을 최적화한다.
- BuildKit의 기능을 활용하여, Docker 이미지 빌드 과정에서 캐싱 및 병렬화를 통해 빌드 시간을 단축할 수 있다. 또한, 불필요한 단계를 건너뛰어 리소스 사용을 최적화한다.
- 더 나은 캐싱 메커니즘
- Buildx는 더 진보된 캐싱 메커니즘을 제공하여, 빌드 속도를 향상시키고 반복적인 빌드 작업에서 시간을 절약할 수 있게 해 준다.
- Buildx는 더 진보된 캐싱 메커니즘을 제공하여, 빌드 속도를 향상시키고 반복적인 빌드 작업에서 시간을 절약할 수 있게 해 준다.
- 컨테이너 레지스트리 통합
- Docker Buildx는 이미지를 직접 컨테이너 레지스트리로 푸시할 수 있는 기능을 제공한다. 이를 통해 빌드 과정을 더욱 간편하게 만들 수 있다.
- Docker Buildx는 이미지를 직접 컨테이너 레지스트리로 푸시할 수 있는 기능을 제공한다. 이를 통해 빌드 과정을 더욱 간편하게 만들 수 있다.
- 사용자 정의 네트워크 지원
- 빌드 과정에서 사용자 정의 네트워크를 설정할 수 있어서 프라이빗 레지스트리나 인터넷에 연결되지 않은 환경에서도 빌드가 가능하다.
- 빌드 과정에서 사용자 정의 네트워크를 설정할 수 있어서 프라이빗 레지스트리나 인터넷에 연결되지 않은 환경에서도 빌드가 가능하다.
1-2. 사용 예시
- 이 명령어는 linux/arm64 플랫폼을 대상으로 myimage:latest라는 태그의 이미지를 빌드한다.
docker buildx build --platform linux/arm64 -t myimage:latest .
2. 로컬 환경에서 Docker Buildx 설치
2-1. Docker 설치 (Docker Desktop)
- Docker가 로컬 시스템에 설치되어 있지 않다면, 먼저 Docker를 설치한다. (이 글에서는 Docker Desktop을 설치한다.)
- Download for Mac - Apple Chip을 제외(Apple Chip은 arm이다.)한 각자의 OS(X86)를 클릭해서 Docker Desktop을 설치하면 된다. (자동으로 buildx가 가능하게 된다.)
2-2. Buildx 설치 및 설정
- Docker Buildx는 최신 버전의 Docker에 기본적으로 포함되어 있다. 그러나 가끔 사용 중인 Docker 버전에 Buildx가 포함되어 있지 않은 경우가 있는데 그런 경우에는 새 빌더 인스턴스를 생성하고 사용 설정을 해줘야 한다. 이를 위해서 터미널에 아래의 명령을 입력하자.
- 아래의 명령은 'mybuilder'라는 이름의 새 Buildx 빌더 인스턴스를 생성하고, 현재 세션에서 이를 기본 빌더로 사용하도록 설정한다.
docker buildx create --name mybuilder --use
2-3. 빌더 시작 및 플랫폼 확인
- 빌더를 시작하고 사용 가능한 플랫폼 목록을 확인한다. 만약 위에서 새 빌더 인스턴스를 생성했다면 생성한 빌더가 올바르게 설정되었는지 확인하기 위해서도 아래의 명령어를 입력해봐야 한다.
- 이 명령은 현재 활성화된 Buildx 빌더의 상세 정보를 보여주며, 필요한 경우 빌더를 초기화한다. '--bootstrap' 옵션은 빌더를 시작하고 사용 가능한 플랫폼 목록을 표시한다.
docker buildx inspect --bootstrap
3. ARM 아키텍처용 이미지 빌드
3-1. 이미지 빌드 명령어 실행
- 다음과 같은 명령어로 ARM 아키텍처용 이미지를 빌드한다. (참고로 빌드할때는 dockerfile이 있는곳에 가서 하자)
docker buildx build --platform linux/arm64 -t [이미지 이름]:[태그] . --push
3-2. ECR에 로그인하기
- 빌드된 이미지를 AWS ECR에 푸시한다. 먼저 AWS CLI를 사용하여 ECR에 로그인하도록 하자.
- 여기서 [리전]에는 예시로 서울 리전인 ap-northeast-2를 넣어뒀는데 나머지 정보는 개인정보라 적지 않았다.
aws ecr get-login-password --region [리전] | docker login --username AWS --password-stdin [ECR 리포지토리 URL]
3-3. ECR에 이미지 푸시
- 그 후, 이미지를 ECR에 푸시한다.
docker push [ECR 리포지토리 URL]/[이미지 이름]:[태그]
4. 한 번의 명령어로 이미지 빌드하는 방법
4-1. 명령어 한 번으로 이미지 빌드 및 ECR에 푸시하기
- ARM 아키텍처용 이미지를 빌드하고, 동시에 ECR에 푸시하는 명령어다.
- 이 명령어는 --push 옵션을 포함하고 있어서, 빌드가 완료되면 바로 ECR에 이미지가 푸시된다.
docker buildx build --platform linux/arm64 -t [ECR 리포지토리 URL]/[이미지 이름]:[태그] . --push
4-2. 명령어 설명
- 플랫폼 지정
- --platform linux/arm64 옵션은 Docker가 ARM 아키텍처용으로 이미지를 빌드하도록 지시한다. 이는 AWS ECS에서 사용되는 ARM 기반의 EC2 인스턴스와 호환되는 이미지를 생성하기 위함이다.
- --platform linux/arm64 옵션은 Docker가 ARM 아키텍처용으로 이미지를 빌드하도록 지시한다. 이는 AWS ECS에서 사용되는 ARM 기반의 EC2 인스턴스와 호환되는 이미지를 생성하기 위함이다.
- 이미지 태그 및 레지스트리 지정
- -t [ECR 리포지토리 URL]/[이미지 이름]:[태그] 부분은 빌드된 이미지에 태그를 지정하고, 해당 이미지를 어느 ECR 리포지토리에 저장할지를 결정한다.
- 이 부분에서 [ECR 리포지토리 URL], [이미지 이름], [태그]는 각각 AWS ECR의 리포지토리의 URL, 사용자가 지정하고자 하는 이미지의 이름, 그리고 해당 이미지의 태그를 나타낸다. (태그는 내가 여기에 적어서 정하는 것이다.)
- 빌드 및 푸시
- 마지막으로 --push 옵션은 이미지가 빌드된 후에 바로 AWS ECR로 푸시되도록 한다. 이렇게 하면 별도의 docker push 명령을 실행할 필요 없이, 빌드와 푸시를 한 번에 처리할 수 있다.
이번 포스팅을 남기게 된 이유는 AWS의 EC2에 X86과 ARM 등 다양한 인스턴스의 종류가 있었기 때문이다.
ARM 인스턴스는 X86 인스턴스에 비해 가격이 저렴하지만 호환성이 좋지 못하다는 단점이 있다.
그것이 Docker에서 빌드를 하는 과정에서 드러나게 되었는데 서로 다른 아키텍처에서 빌드한 이미지를 기동 하려면 자바에서 타입캐스팅을 하듯이 Docker의 이미지도 아키텍처에 맞게 타입을 변환시켜줘야만 했다. 이에 이 글을 남긴다. 많은 분들이 오류를 해결했으면 좋겠다.
2023.11.09 - [AWS] - AWS CodeBuild와 Docker Buildx를 활용한 ARM 아키텍처 ECS의 이미지 빌드 전략
2023.10.28 - [DevOps] - ECR Docker 이미지 Push 오류: M1 아키텍처와 exec format 문제
반응형
'AWS > ECS, ECR' 카테고리의 다른 글
[AWS ECR] Docker Buildx로 ARM 전용 Docker 이미지 빌드하기 (0) | 2023.11.09 |
---|---|
[AWS] ECS로 MSA인프라 구현하기 (0) | 2023.11.07 |
[AWS ECS] ECS로 MSA 구현하기 (0) | 2023.11.07 |
AWS Secrets & ECS SpringBoot 설정 (3-2): 성공적인 배포 완료 (1) | 2023.11.03 |
AWS Secrets & ECS SpringBoot 설정 (3-1): ECS배포와 오류 분석 (0) | 2023.11.03 |