Kiro와 Arm MCP Server를 활용한 자동 클라우드 마이그레이션
Source: Dev.to – Automated Cloud Migrations with Kiro and the Arm MCP Server
번역을 진행하려면 번역하고자 하는 전체 텍스트(본문)를 제공해 주시겠어요?
본문을 주시면 원본 형식과 마크다운을 그대로 유지하면서 한국어로 번역해 드리겠습니다.
소개
AWS Graviton은 AWS의 모든 EC2 인스턴스 중 최고의 가격‑성능을 제공하며, 최근 Graviton 5 발표로 그 가치 제안이 더욱 강력해졌습니다. Graviton으로 마이그레이션하는 것은 재정적으로도 합리적이며 애플리케이션에 큰 성능 향상을 제공합니다.
대부분의 애플리케이션은 문제 없이 옮겨지지만, 코드에 x86‑특화 최적화가 포함되어 있다면 어떻게 할까요?
좋은 소식: 이제 마이그레이션을 직접 수동으로 할 필요가 없습니다.
이 글에서는 Kiro(AWS의 에이전트형 IDE)와 Arm MCP Server를 함께 사용하여 Docker 이미지, SIMD 인트린식, 컴파일러 플래그 등 전체 마이그레이션 과정을 자동화하는 방법을 보여드리겠습니다.
Arm MCP 서버가 제공하는 것
- ✅ Docker 이미지를 확인하여
arm64지원 여부를 매니페스트를 파고들지 않고 확인합니다. - 🔍 코드베이스를 스캔하여 x86‑전용 코드(인트린식, 빌드 플래그 등)를 찾습니다.
- 📚 Arm 지식베이스를 검색하여 마이그레이션 가이드와 인트린식 대응 항목을 찾습니다.
- 🧪 어셈블리를 분석하여 성능 특성을 파악합니다.
예시: 레거시 벤치마킹 앱 마이그레이션
Imagine you’ve inherited a legacy benchmarking application that’s tightly coupled to x86. Below is the original Dockerfile.
FROM centos:6
# CentOS 6 reached EOL – use vault mirrors
RUN sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-Base.repo && \
sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Base.repo
# Install EPEL repository (required for some development tools)
RUN yum install -y epel-release && \
sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/epel.repo && \
sed -i 's|^#baseurl=http://download.fedoraproject.org/pub/epel|baseurl=http://archives.fedoraproject.org/pub/archive/epel|g' /etc/yum.repos.d/epel.repo
# Install Developer Toolset 2 for better C++11 support (GCC 4.8)
RUN yum install -y centos-release-scl && \
sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo && \
sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo && \
sed -i 's|^# baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo && \
sed -i 's|^# baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
# Install build tools
RUN yum install -y \
devtoolset-2-gcc \
devtoolset-2-gcc-c++ \
devtoolset-2-binutils \
make \
&& yum clean all
WORKDIR /app
COPY *.h *.cpp ./
# AVX2 intrinsics are used in the code
RUN scl enable devtoolset-2 "g++ -O2 -mavx2 -o benchmark \
main.cpp \
matrix_operations.cpp \
-std=c++11"
CMD ["./benchmark"]
왜 이 Dockerfile이 Graviton에서 작동하지 않을까
| 문제 | 설명 |
|---|---|
centos:6 | arm64 변형이 없음 – 기본 이미지가 x86 전용입니다. |
-mavx2 | x86 전용 컴파일러 플래그이며, Arm CPU는 AVX2를 이해하지 못합니다. |
AVX2 인트린식 (__m256 등) | Arm에서 컴파일되지 않습니다; Arm에 해당하는 SIMD 인트린식이 필요합니다. |
If you didn’t spot these problems yourself, that’s fine—Kiro + Arm MCP Server will.
문제 있는 행렬 곱셈 코드
아래는 matrix_operations.cpp 파일로, AVX2 인트린식을 사용한 double‑precision 행렬 곱셈을 구현하고 있습니다. (코드 조각은 의도적으로 최소화했으며, 실제 곱셈 커널은 전체 구현에 포함되어 있습니다.)
// matrix_operations.cpp
#include "matrix_operations.h"
#include <vector>
#include <random>
#include <iostream>
#include <immintrin.h> // AVX2 intrinsics
// ---------------------------------------------------------------------------
// Matrix constructor
// ---------------------------------------------------------------------------
Matrix::Matrix(size_t r, size_t c) : rows(r), cols(c) {
// Allocate a rows × cols matrix filled with zeros
data.resize(rows, std::vector<double>(cols, 0.0));
}
// ---------------------------------------------------------------------------
// Fill the matrix with random values in the range [0.0, 10.0)
// ---------------------------------------------------------------------------
void Matrix::randomize() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0.0, 10.0);
for (size_t i = 0; i < rows; ++i) {
for (size_t j = 0; j < cols; ++j) {
data[i][j] = dis(gen);
}
}
}
// ---------------------------------------------------------------------------
// (The multiplication routine that uses AVX2 intrinsics is omitted here)
// ---------------------------------------------------------------------------
이 코드가 ARM v8 AArch64에서 실패하는 이유
| Issue | Explanation |
|---|---|
AVX2 인트린식 (_mm256_*) | x86‑64 전용 인트린식이라 ARM v8에서는 사용할 수 없습니다. |
| 헤더 및 include guard 누락 | 원본 조각에 여러 표준 헤더가 빠져 있어 컴파일 오류가 발생합니다. |
std::vector 초기화 오류 | std::vector(cols, 0.0) 대신 std::vector<double>(cols, 0.0)이어야 합니다. |
| 루프 누락 / 구문 오류 | randomize 메서드의 일부가 불완전하게 작성되었습니다. |
제안된 마이그레이션 경로 (Kiro 어시스턴트 사용)
-
아키텍처 감지
- Kiro가 CI 설정 파일(
.github/workflows/*.yml)을 읽어 실행기가arm64임을 확인합니다.
- Kiro가 CI 설정 파일(
-
호환되지 않는 인트린식 식별
- 소스에서 AVX2 인트린식(
_mm256_*)을 스캔하고, 이를 비이식성으로 표시합니다.
- 소스에서 AVX2 인트린식(
-
휴대 가능한 대안 제시
- Kiro는 AVX2 코드를 ARM NEON 등가물(
float64x2_t,float64x4_t등)로 교체하거나, 성능 영향을 감수할 수 있다면 스칼라 구현으로 대체할 것을 제안합니다.
- Kiro는 AVX2 코드를 ARM NEON 등가물(
-
자동 리팩터링 (옵션 PR)
- Kiro는 풀 리퀘스트를 생성하여:
- Docker/CI 이미지를 ARM‑호환 베이스 이미지로 업데이트합니다.
- 빌드 명령에
-march=armv8-a+simd옵션을 추가합니다. - AVX2 인트린식을 NEON‑호환 코드 또는 휴대 가능한 스칼라 루프로 교체합니다.
- Kiro는 풀 리퀘스트를 생성하여:
-
검증
- 변경 후 Kiro가
arm64러너에서 벤치마크를 실행하고, 원래 x86 빌드와 성능을 비교하여 차이를 보고합니다.
- 변경 후 Kiro가
TL;DR
- 문제: x86‑전용 Docker 베이스, 컴파일러 플래그, 그리고 AVX2 인트린식이 Graviton(ARM) 인스턴스에서 코드를 실행하지 못하게 함.
- 해결책: Kiro + Arm MCP Server를 사용해 문제 요소(예: AVX2 인트린식, x86‑전용 전처리기 검사)를 자동으로 감지하고 교체.
- 결과: 최신 Graviton 5 인스턴스에서도 실행 가능한 깔끔한 ARM‑호환 Docker 이미지와 소스 코드를 얻어 비용 효율적인 성능 향상을 달성.
한 번 시도해 보세요—미래의 여러분(그리고 AWS 청구서)에게 감사할 겁니다!
헤더 파일 matrix_operations.h
#ifndef MATRIX_OPERATIONS_H
#define MATRIX_OPERATIONS_H
#include <cstddef> // size_t
#include <vector> // std::vector
#include <iostream> // std::cout (optional, for debugging)
class Matrix {
private:
std::vector<std::vector<double>> data; // 2‑D storage
size_t rows;
size_t cols;
public:
// ctor
Matrix(size_t r, size_t c);
// fill the matrix with random values (0‑1)
void randomize();
// matrix multiplication (returns a new matrix)
Matrix multiply(const Matrix& other) const;
// sum of all elements – handy for a quick sanity check
double sum() const;
// simple accessors
size_t getRows() const { return rows; }
size_t getCols() const { return cols; }
};
// Benchmark driver – defined in a separate .cpp file
void benchmark_matrix_ops();
#endif // MATRIX_OPERATIONS_H
무엇이 수정되었나요?
| 문제 | 원본 | 수정 사항 |
|---|---|---|
| 포함 가드 종료 누락 | #endif // MATRIX_OPERATIONS_H 가 클래스 정의 앞에 나타남 | 가드를 파일 전체를 감싸도록 이동함 |
#include 라인이 비어 있었음 | #include | 필요한 헤더 (<cstddef>, <vector>, <iostream>)를 추가함 |
| 벡터 선언 구문 | std::vector> data; | std::vector<std::vector<double>> data; 로 변경함 |
| 닫히지 않은 주석 / 불필요한 텍스트 | "Time: " | 제거함 – 헤더 파일에 포함되지 않음 |
| 함수 프로토타입에 세미콜론 누락 | none | 필요한 곳에 각 프로토타입 뒤에 ; 를 추가함 |
소스 파일 main.cpp
#include "matrix_operations.h"
#include <iostream>
int main() {
std::cout << "Matrix Operations Benchmark\n"
<< "============================\n";
#if defined(__x86_64__) || defined(_M_X64)
std::cout << "Running on x86‑64 architecture with AVX2 optimisations\n";
#else
std::cout << "Running on a non‑x86 architecture (e.g., ARM/Graviton)\n";
#endif
// Execute the benchmark – implementation lives in matrix_operations.cpp
benchmark_matrix_ops();
return 0;
}
수정된 내용
| 문제 | 원본 | 수정됨 |
|---|---|---|
<iostream> 포함 누락 | #include (empty) | #include <iostream> 추가 |
#error 지시문이 ARM에서 컴파일을 방지함 | #error "This code requires x86-64 architecture with AVX2 support" | 런타임 메시지로 교체했으며, 이제 코드는 모든 아키텍처에서 컴파일됩니다. |
| 일관성 없는 들여쓰기 / 불필요한 공백 | Mixed tabs/spaces | 4칸 공백 들여쓰기로 정규화 |
불필요한 using namespace std; (존재하지 않음) – 명확성을 위해 std::를 명시적으로 사용 | – | 변경 없음 |
프로젝트를 ARM‑Ready(ARM 준비)하는 방법
-
AVX2 인트린식 제거 – 이를 포터블 SIMD 라이브러리(예: xsimd 또는 컴파일러 자동 벡터화)로 교체합니다.
-
Dockerfile 업데이트
# ARM 호환 베이스 이미지 사용 FROM public.ecr.aws/ubuntu/ubuntu:22.04-arm64 # 빌드 도구 설치 RUN apt-get update && apt-get install -y \ build-essential cmake git \ && rm -rf /var/lib/apt/lists/* # 소스 복사 및 빌드 COPY . /app WORKDIR /app RUN cmake -B build && cmake --build build -j$(nproc) -
적절한 플래그로 컴파일
g++ -O3 -march=armv8.2-a+simd -std=c++20 -I. -o matrix_demo main.cpp matrix_operations.cpp -
Graviton에서 컨테이너 실행 – 이제 이미지가 x86‑전용 체크 없이 시작되며 ARM‑네이티브 SIMD 확장을 활용합니다.
빠른 테스트
# 로컬에서 빌드 (ARM 호스트 또는 Docker를 통한 에뮬레이션)
docker build -t matrix-bench:arm .
# 실행
docker run --rm matrix-bench:arm
예상 출력:
Matrix Operations Benchmark
============================
Running on a non‑x86 architecture (e.g., ARM/Graviton)
[benchmark output…]
이제 코드는 완전히 포터블하며, Graviton 5 인스턴스가 제공하는 비용 효율적인 성능을 활용할 수 있습니다. 즐거운 코딩 되세요!
Kiro + MCP로 ARM 마이그레이션
코드에 x86 전용 인트린식이 많이 포함되어 있지만, Kiro가 자동으로 변환을 처리할 수 있습니다.
1. Kiro를 설정해 ARM MCP 서버에 연결하기
프로젝트 루트에 .kiro/settings/mcp.json 파일을 생성합니다:
{
"mcpServers": {
"arm-mcp": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/path/to/your/code:/workspace",
"armlimited/arm-mcp:1.0.1"
]
}
}
}
Notes
- 이 명령은 Docker를 통해 ARM MCP 서버를 실행합니다.
/path/to/your/code를 프로젝트의 절대 경로로 바꾸세요.- Kiro가 새 서버를 자동으로 인식합니다. 채팅에
/mcp를 입력해 연결을 확인하면arm-mcp와 해당 도구들이 목록에 표시됩니다.
2. 채팅에서 빠른 확인
Kiro에게 즉석 검사를 요청할 수 있습니다. 예:
Check the base image in the Dockerfile for ARM compatibility
Kiro는 MCP 도구를 사용해 centos:6은 amd64만 지원한다는 결과를 보고합니다.
3. 스티어링 문서로 마이그레이션 자동화
.kiro/steering/arm-migration.md 파일을 생성합니다:
---
inclusion: manual
---
Your goal is to migrate a codebase from x86 to ARM. Use the MCP server tools to help you with this. Check for x86‑specific dependencies (build flags, intrinsics, libraries, etc.) and replace them with ARM‑equivalent ones, ensuring compatibility and optimizing performance. Examine Dockerfiles, version files