스타트업에서 어떤 서버를 구축할지 결정하는 일은 매우 중요합니다. 제한된 비용으로 더 많은 유저를 수용하기 위해 온갖 노력이 들어가곤 하는데, 애초에 같은 돈으로 더 좋은 컴퓨터를 대여할 수 있다면 얼마나 좋을까요?
지난 2월, 서울 리전에 t4g 인스턴스가 추가됐습니다. EC2의 Arm 기반 t4g 인스턴스는 서버 컴퓨터로 흔히 사용되는 동급 t3 모델보다 40%나 나은 성능을 자랑한다고 합니다. 아래 글에 따르면, 동등한 조건에서 t3 모델보다 3배 이상 나은 CPU 성능을 보였지만 오히려 20% 더 저렴했습니다.
AWS EC2 Instance Comparison: T3 vs T3a vs T4g(영문)
하지만 관심이 생겨 검색을 해봐도 아직 참고할 만한 사례를 찾기 어려웠습니다. 가성비와 편의성 사이에서 고민한 끝에, 일단 도입해 써보기로 결심했습니다.
t4g 인스턴스의 가장 큰 특징은, 로컬 컴퓨터에서 일반적으로 쓰이는 Amd64(x86-64) 아키텍처가 아닌 arm64 기반 프로세서를 사용한다는 사실입니다. 그 덕에 동일 비용으로 훨씬 뛰어난 성능을 발휘할 수 있지만, 여러 호환성 문제를 겪을 수도 있습니다.
사실 겉으로 보기엔 기존에 쓰던 인스턴스들과 큰 차이를 느낄 수는 없었는데요. 문제는 도커를 설치하려 할때부터 시작됐습니다.
리눅스 컴퓨터에 도커를 설치하실 때 보통 다음의 도커 설치 공식문서를 참조하실 텐데요. 도커 설치를 위한 셋업 단계 마지막에, amd64용 커맨드를 입력하지 않도록 주의하셔야 합니다.
저장소 세팅 시에 위의 arm64용 커맨드를 입력하셔야 합니다. 혹시라도 착각해 x86_64용 커맨드를 입력하신 경우 빠르게 인스턴스를 초기화하거나 재대여하시길 추천드립니다. 해당 커맨드를 되돌리기는 까다롭고, 그렇다고 다시 arm64 커맨드를 입력하면 에러가 발생하기 때문입니다.
특정 버전의 우분투에서 도커 컴포즈를 설치하는 경우 설치가 안되는 문제가 발생할 수 있습니다. 해당 문제를 겪으신다면 다음 이슈에서 해결법을 찾을 수 있습니다.
Release docker/compose image for armv7 / arm64v8 #6831
도커 컴포즈 이미지를 활용하라는 답변도 있지만 오버헤드가 있으므로 추천드리진 않습니다. nemchik
님의 답변이 큰 도움이 됐고, 이 방식으로 해결했을때 테스트 단계에서 도커 컴포즈를 이용하는데 어떠한 문제도 발생하지 않았습니다.
설치를 무사히 마치셨다면, 기존에 사용하던 이미지를 레지스트리에서 풀받아 실행하는 순간 아래와 같은 에러를 마주하게 됩니다.
exec user process caused: exec format error
보통의 개발 컴퓨터는 amd64 아키텍처를 사용하므로, 기본 세팅으로 도커 이미지를 빌드하면 amd64에서만 동작하는 이미지가 빌드됩니다. 이를 arm 기반 t4g 인스턴스에서 실행하려하면 위와 같은 에러가 발생합니다. 따라서 이미지 빌드시에 arm64용으로 빌드해줄 필요가 있습니다.
다행히도 도커에서는 이와 같은 다중 플랫폼에 대응하고자 docker buildx
를 제공합니다. 최신 버전의 경우 도커에 이미 내장돼있는 기능으로, 다양한 아키텍처에서 작동하는 도커 이미지를 빌드해줍니다. 사용법에 대해선 아래 링크들을 참조하시면 좋습니다.
Docker Buildx로 Multi-Archtecture Image 빌드하기
Docker buildx를 활용하여 Multi-Architecture 이미지 빌드
Docker Buildx 공식문서
제 경우, 인텔 프로세서 맥북에서 도커 이미지를 빌드해 arm64 t4g 인스턴스에서 이미지를 실행하고 있습니다. 이 경우 제가 사용하는 커맨드는 다음과 같습니다(위 링크대로 기본 세팅을 하셔야 합니다).
docker buildx build --platform linux/arm64 -t [image name]:$VER -f [Dockerfile 경로] --load .
docker push [image name]:$VER
보이듯이 멀티 아키텍처 빌드를 도커에서 아주 잘 지원해주고 있어서 사용하는 입장에서는 거의 차이가 없고, 빌드 커맨드만 다릅니다. 다만 같은 이유로 이 이미지를 로컬 컴퓨터에서 실행할 수는 없습니다. 또한 docker buildx
에서 --load
를 --push
로 바꾸면 빌드한 이미지를 바로 레지스트리로 푸시합니다.
이제 직접 빌드하신 이미지를 서버 상에 돌리는데에는 거의 문제가 없습니다. 다만 겪으실 수 있는 마지막 관문은 공개 이미지를 직접 사용할때 일어납니다. 대부분의 'Awesome'으로 지정된 서비스와 라이브러리들은 Arm 아키텍처도 지원합니다.
위와 같이 redis는 ARM 64를 지원합니다. 사용에 문제가 없습니다.
하지만 도커허브 상의 널리 사용되지 않는 일부 이미지들은 x86-64만 지원하는 경우도 있습니다.
Arm을 지원하지 않는 celery 모니터링 서비스 flower
이 경우 해당 이미지의 멀티 아키텍처 베이스 이미지와, 공개된 도커파일을 가져와 docker buildx
로 직접 멀티 아키텍처 빌드해 사용하실 필요가 있습니다. 다만 커스텀 이미지만을 사용하는 경우가 많고, 이런 문제가 흔한 일은 아니어서 크게 걱정하진 않아도 괜찮다고 생각합니다. Arm64를 지원하는 이미지만을 찾고 싶으신 경우, 도커 허브의 Architectures
필터에서 Arm64를 체크해 검색하면 됩니다.
앞서 t4g 인스턴스에서 도커를 사용할때 겪을 만한 어려움과 해결책을 다뤘습니다. 다만, 한번 세팅하고 나면 큰 문제가 될만한 내용은 아니라고 생각합니다.
실제로 저희는 초기 세팅과 안정성 테스트 후에는 t4g 인스턴스에 만족해 잘 사용하고 있습니다. 현재도 여러 대의 t4g 인스턴스 위에 도커 스웜을 올려 프로덕션 서버를 운용하고 있습니다. 다만 대규모 유저를 대상으로 하진 않아 저희가 겪지 못한 문제가 발생할 수 있으니 참고만 해주시면 감사하겠습니다.
모든 종류의 지적에 대해 미리 감사드립니다.
좋은 포스트 잘봤습니다. 궁금한게 하나 있는데요 arm64가 모바일 아키텍쳐로 알고 있는데요
속도 측면에서 x86-64보다 많이 부족하지 않을까 궁금해서 여쭤봅니다. 감사합니다.