[CloudNeta] EKS 워크샵 스터디 (9) - EKS 위 AI/ML 워크로드 Part 1 - EKSworkshop AI/ML로 Neuron 기반 다지기

이번 게시글에서는 EKS 워크샵 스터디 제 9주차 내용을 작성합니다.

이 글은 3부로 나누어집니다.

  1. 9주차 - EKS 위 AI/ML 워크로드 Part 1 - EKSworkshop AI/ML로 Neuron 기반 다지기 (현재 보고 계신 글)
  2. 9주차 - EKS 위 AI/ML 워크로드 Part 2 - GenAI on EKS로 추론 서빙 운영하기
  3. 9주차 - EKS 위 AI/ML 워크로드 Part 3 - Agentic AI Platform으로 멀티 에이전트 플랫폼 구축하기

들어가며

이번 편에서 다루는 워크샵은 다음과 같습니다.

Amazon Q Developer CLI는 Kiro CLI로 이관 중입니다

AWS는 2026-05-15부로 Amazon Q Developer 신규 가입을 중단하고, 후속으로 spec-driven agentic IDE/CLI인 Kiro로 이관 중입니다. 기존 Q Developer IDE 플러그인·유료 구독은 2027-04-30 end-of-support 예정입니다.

Kiro CLI는 Q Developer CLI와 backward compatible이라 본문 LAB 3에 나오는 q login, $HOME/.aws/amazonq/mcp.json MCP 설정, awslabs.eks-mcp-server 호출 흐름이 그대로 동작합니다. 워크샵 명령은 그대로 따라가도 되며, 마이그레이션 상세는 Upgrading from Amazon Q Developer CLIAmazon Q Developer end-of-support announcement를 참고하세요.

9주차는 EKS 위 AI/ML 워크로드를 다루는 3개 워크샵을 차례로 따라가는 구성입니다. 이번 Part 1에서는 그 첫 번째인 EKSworkshop AI/ML 트랙 을 정리합니다.

이 트랙을 처음 열어 보고 흥미로웠던 점은, 이번 트랙 전체가 NVIDIA GPU가 아닌 AWS 자체 가속기(Neuron 계열의 Trainium·Inferentia) 활용방안 으로 짜여 있다는 것이었습니다. GPU 기반 LLM 추론은 Part 2: GenAI on EKS에서 본격적으로 다루므로, Part 1은 자연스럽게 "GPU 외의 가속기를 EKS에서 어떻게 다루는가"와 "Amazon Q CLI(이하 Kiro) 로 운영을 어떻게 위임하는가"라는 부분으로 정리할 수 있었습니다.

EKSworkshop AI/ML 트랙 개요

EKSworkshop AI/ML 트랙은 다음 네 챕터로 구성되어 있습니다.

챕터 한 줄 요약
Large Language Models with vLLM Trainium(trn1) 위에서 Mistral 7B를 vLLM으로 서빙
Inference with AWS Inferentia Trainium에서 ResNet-50 컴파일 → Inferentia에서 추론
Operating EKS with Amazon Q CLI Kiro와 EKS MCP server로 클러스터 진단·트러블슈팅·배포
AI on EKS (EXPLORE) aws-samples의 별도 사이트로 안내되는 외부 트랙

네 번째 EXPLORE 항목은 외부 사이트로 연결되는 안내성 챕터라 이 글에서는 다루지 않고, 앞의 세 LAB을 중심으로 정리합니다.

사전 준비

워크샵 내의 prepare-environment 명령이란?

세 LAB 모두 prepare-environment <모듈경로> 한 줄로 클러스터 베이스라인을 잡고 시작합니다. 이 명령은 별도로 설치하는 CLI가 아니라, 워크샵 IDE 환경에 사전 정의된 쉘 함수 래퍼입니다. 구현은 aws-samples/eks-workshop-v2lab/scripts/setup.sh에서 확인할 수 있고, 내부적으로는 bin/reset-environment <모듈경로>를 호출해 해당 모듈이 필요한 리소스를 idempotent하게 재구성합니다.

따라서 이 명령은 다음 환경에서만 의미가 있습니다.

두 경우 모두 IDE 컨테이너 안의 /usr/local/binreset-environment 같은 헬퍼와 kubectl·helm·eksctl·aws·terraform·yq 등이 사전 설치되어 있어, 본문에 나오는 명령들은 거기서 그대로 실행하면 됩니다. 로컬 머신에서 곧장 호출되는 명령이 아니라는 점만 챙기면 됩니다.

각 LAB이 적용하는 Terraform

prepare-environment <모듈경로>를 IDE 터미널에서 실행하면, 해당 모듈의 manifests/modules/aiml/<모듈>/.workshop/terraform/ 코드가 terraform apply되어 LAB이 시작될 준비를 마칩니다. 세 LAB의 관심사는 둘로 나뉩니다. 앞의 두 LAB은 Neuron 가속기 노드와 모델 실행 경로를 만들고, Kiro LAB은 가속기보다 운영 자동화와 MCP 통합에 초점을 둡니다.

LAB prepare 명령 배포되는 것 (Terraform 기준) 코드
vLLM prepare-environment aiml/chatbot AWS Load Balancer Controller, EKS Pod Identity Agent, Karpenter (controller + Helm release), 챗봇 UI Ingress aiml/chatbot/.workshop/terraform
Inferentia prepare-environment aiml/inferentia EKS Pod Identity Agent, Karpenter, 추론 산출물용 S3 버킷, 추론 Pod용 IRSA IAM Role/정책, Neuron Device Plugin DaemonSet + RBAC aiml/inferentia/.workshop/terraform
Kiro prepare-environment aiml/q-cli EKS Blueprints Add-ons, Pod Identity Agent, 트러블슈팅 실습용 DynamoDB 테이블(carts, GSI + Stream), 테이블 암호화용 KMS 키, carts 서비스 Pod Identity Association, IAM 정책/Role aiml/q-cli/.workshop/terraform

Terraform이 한 번 적용되어 베이스라인이 잡힌 다음, 본문에서 다루는 LAB별 흐름은 그 위에 추가 매니페스트를 kubectl/helm으로 얹는 식입니다. 예를 들어 LAB 1은 manifests/modules/aiml/chatbot/ 디렉터리의 nodepool.yaml, vllm.yaml, neuron-values.yaml을 차례로 적용해 Karpenter NodePool과 vLLM Deployment를 만듭니다.

앞의 두 LAB에서는 Karpenter가 가속기 노드 프로비저닝의 입구입니다. 노드 그룹을 수동으로 다루지 않고 NodePool/EC2NodeClass 선언으로 Neuron 인스턴스를 띄우는 흐름을 반복합니다. 반면 Kiro LAB은 노드 프로비저닝보다 "자연어 요청을 MCP 도구 호출로 바꾸어 EKS를 조회·진단한다"는 운영 인터페이스의 변화를 보여줍니다.

LAB 1. Large Language Models with vLLM

첫 번째 LAB은 vLLM으로 Mistral 7B를 서빙하지만, 가속기로 NVIDIA GPU가 아닌 AWS Neuron(Trainium / Inferentia 2세대) 을 사용한다는 점이 특이합니다.

챕터 구성

스텝 URL 핵심
Install the Neuron plugin /docs/aiml/chatbot/setup Neuron 디바이스를 K8s 확장 리소스로 노출
Provisioning compute /docs/aiml/chatbot/nodepool Karpenter NodePool로 Neuron 인스턴스 프로비저닝
Serving the model /docs/aiml/chatbot/mistral Mistral 7B를 vLLM으로 서빙
Configuring the chat bot /docs/aiml/chatbot/using 챗봇 인터페이스 구성
Testing the model /docs/aiml/chatbot/testing 엔드포인트 호출 검증

워크샵이 실제로 구성하는 것

  1. Neuron Device Plugin 설치: Helm chart 한 줄로 끝남
helm upgrade --install neuron-helm-chart oci://public.ecr.aws/neuron/neuron-helm-chart \
  --namespace kube-system --version 1.5.0 \
  --values ~/environment/eks-workshop/modules/aiml/chatbot/neuron-values.yaml \
  --wait

결과로 kube-system 네임스페이스에 neuron-device-plugin DaemonSet이 떠 노드의 Neuron 디바이스를 aws.amazon.com/neuron 확장 리소스로 노출합니다. GPU 환경에서 nvidia.com/gpu를 다루던 패턴과 정확히 동일한 모델입니다.

  1. Karpenter NodePool: neuron 단일 NodePool

가속기 인스턴스는 단가가 높으므로 NodePool limit가 비용 가드레일 역할을 합니다. limit를 풀어두면 워크로드 한 번 잘못 띄우는 것만으로 청구서가 튀기 쉽습니다.

  1. vLLM 배포

여기서 짚고 갈 점은 모델 이름이 그냥 "Mistral 7B"가 아니라 -cores-2로 끝난다는 것입니다. Neuron은 모델을 그대로 올릴 수 없고 SDK로 컴파일해야 하는데, 워크샵은 이 컴파일 과정을 LAB 1에서는 건너뛰고 이미 컴파일된 모델을 Hugging Face에서 받아 쓰는 방식으로 진행합니다. 컴파일 자체는 LAB 2에서 직접 수행해 봅니다.

vLLM의 PagedAttention·KV cache·tensor parallel 같은 서빙 디테일은 Part 2: GenAI on EKS에서 GPU 환경으로 다시 다루므로, 여기서는 "vLLM 인터페이스 자체는 가속기 종류와 무관하다"는 점을 챙기고 넘어가는 게 효율적입니다.

LAB 2. Inference with AWS Inferentia

LAB 1이 "이미 컴파일된 모델을 받아 서빙"이었다면, LAB 2는 컴파일부터 추론까지 직접 해보는 챕터입니다.

챕터 구성

스텝 URL 핵심
Provisioning compute /docs/aiml/inferentia/karpenter Neuron 단일 NodePool 생성
Compile a pre-trained model /docs/aiml/inferentia/compile Trainium 노드에서 ResNet-50 컴파일
Run inference on AWS Inferentia /docs/aiml/inferentia/inference 컴파일된 모델로 Inferentia에서 추론
Real world implementation /docs/aiml/inferentia/wrapup 실무 적용 회고

워크샵이 실제로 구성하는 것

  1. NodePool: 컴파일·추론을 한 NodePool에 묶음

LAB 1이 NodePool을 neuron 한 개로 다루는 것과 결이 같습니다. 컴파일용 인스턴스(trn1)와 추론용 인스턴스(inf2)를 같은 NodePool에 두고, Pod의 nodeSelector/스펙으로 적절한 인스턴스에 떨어지게 합니다. 운영 환경에서 비용·격리가 중요해지면 두 NodePool로 쪼개는 게 자연스럽지만, 워크샵 수준에서는 한 NodePool로 충분하다는 게 흥미로운 설계 결정입니다.

  1. 컴파일: Trainium 노드에서 ResNet-50을 torch_neuronx로 변환
kubectl -n aiml exec compiler -- python /trace.py
kubectl -n aiml exec compiler -- aws s3 cp ./resnet50_neuron.pt s3://$AIML_NEURON_BUCKET_NAME/
  1. 추론: kubectl exec로 Python 스크립트 직접 실행
kubectl -n aiml cp ~/path/inference.py inference:/
kubectl -n aiml exec inference -- python /inference.py

이 워크샵은 의도적으로 추론 서버를 띄우지 않습니다. 모델 로딩과 추론 호출만 보여 주고, 서빙·오토스케일·라우팅 같은 운영 디테일은 Part 2의 GenAI on EKS와 KServe 쪽에서 다시 만나게 됩니다. LAB 2의 학습 목표는 어디까지나 "Neuron 컴파일 → Inferentia 추론"이라는 흐름의 가능성 자체를 확인하는 것입니다.

운영 관점에서 짚을 포인트

실 운영 사례: Nota AI의 Transformer 12개 모델 포팅

워크샵이 보여주는 ResNet-50 컴파일은 한 번에 깔끔하게 떨어지지만, 실제 LLM/Transformer를 Neuron으로 옮길 때는 op·출력 구조 호환성 이슈가 자주 등장합니다. AWS 한국 기술 블로그에 공개된 Nota AI 사례 (Tips for using Transformer models on AWS Inf/Trn)가 그 마찰을 잘 보여줍니다.

Nota는 Hugging Face 기반 Transformer 12개 모델(IBM Granite 3.1-8B, BERT-base, Llama-3.2-1B, Falcon-7B, Phi-3-mini, GPT-Neo, OPT, BLOOM 등)을 Inferentia/Trainium에 포팅하며 다음 패턴을 정리했습니다.

비용 측면에서도 같은 글에 별도 사례(NVIDIA V100 → T4 전환)가 함께 공개되어 있습니다. 월 운영비 $2,203 → $391로 약 85% 절감, 추론 속도 14% 향상, 정확도 97.14% → 97.03%로 0.1% 이내 손실이라는 수치를 제시하며 가속기 전환의 손익을 정량으로 보여 줍니다.

워크샵의 ResNet-50 코스에서는 만나기 어려운 시나리오지만, 자체 모델을 Inferentia로 옮길 계획이 있다면 사전 호환성 점검(torch_neuronx.trace() 더미 실행)을 CI에 포함시키고, 위의 return_dict=False 같은 패턴을 미리 카탈로그화해 두는 것이 도입 초기의 마찰을 크게 줄여 줍니다.

GPU 추론과 비교

구분 NVIDIA GPU AWS Inferentia / Trainium
모델 준비 학습된 모델을 그대로 로드 Neuron SDK로 사전 컴파일 필요
단가 동일 추론 성능 대비 높음 추론 워크로드에서 가격 효율 우수
생태계 CUDA/cuDNN, 사실상 모든 프레임워크 Neuron SDK 지원 범위로 제한
K8s 통합 NVIDIA Device Plugin / GPU Operator Neuron Device Plugin (aws.amazon.com/neuron)
운영 관성 가장 표준적인 경로 컴파일·op 호환성 등 별도 학습곡선

요약하면 Inferentia는 "컴파일 가능한 모델 + 안정적인 추론 트래픽"이라는 조건이 맞을 때 강력한 선택지가 됩니다. 모델을 빠르게 갈아끼우거나 다양한 op를 쓰는 경우라면 GPU의 유연성이 우위입니다.

LAB 3. Operating EKS with Amazon Q CLI

세 번째 LAB은 가속기 워크로드와는 결이 다른, 운영 자동화 관점의 챕터입니다. 워크샵 페이지 자체가 Preview 상태임을 명시하므로, 운영 환경 도입을 전제하기보다는 에이전트 기반 운영의 가능성을 체감하는 용도로 보는 게 적절합니다.

챕터 구성

스텝 URL 핵심
Setup /docs/aiml/q-cli/q-cli-setup Kiro 설치, EKS MCP server 등록, q login
Retrieve cluster details /docs/aiml/q-cli/retrieve-cluster-details 자연어로 클러스터 인벤토리·상태 조회
Basic troubleshooting /docs/aiml/q-cli/basic-troubleshooting Pending Pod 시나리오 진단
Advanced troubleshooting /docs/aiml/q-cli/advance-troubleshooting 복합 시나리오 진단

워크샵이 실제로 구성하는 것

  1. Kiro 설치와 MCP 설정
curl --proto '=https' --tlsv1.2 -sSf \
  https://desktop-release.q.us-east-1.amazonaws.com/1.12.4/q-${ARCH}-linux.zip -o /tmp/q.zip
unzip /tmp/q.zip -d /tmp
sudo Q_INSTALL_GLOBAL=true /tmp/q/install.sh --no-confirm

설치 후 $HOME/.aws/amazonq/mcp.json에 EKS MCP server 엔트리를 등록하는데, 워크샵이 제공하는 eks-mcp.json을 그대로 복사해서 씁니다. 핵심은 uvx를 통해 awslabs.eks-mcp-server@0.1.13을 실행한다는 점입니다. Kiro는 자체적으로 EKS를 모르고, MCP server가 자연어 요청을 K8s/EKS API 호출로 번역해 주는 구조입니다.

이어서 q login으로 AWS Builder ID 또는 Pro 라이선스 인증을 거치면 세션이 열립니다.

  1. 클러스터 조회: 자연어를 MCP 도구 호출로 번역

워크샵이 제시하는 프롬프트 예시는 다음과 같습니다.

"Summarize the configuration of the eks-workshop EKS cluster"
"List all pods in the carts namespace with their IP addresses along with the host names they are running on"
"Deploy a test pod in my cluster and check if it can access internet"

Kiro는 이 요청을 받고 EKS MCP server의 도구들(describe-cluster, list_k8s_resources, manage_k8s_resource, get_k8s_events 등)을 호출해 응답을 마크다운 표·체크리스트 형태로 돌려줍니다.

  1. Basic 트러블슈팅: 일부러 만든 Pending Pod

워크샵은 존재하지 않는 PVC(my-pvc)를 참조하는 Pod를 띄워 Pending 상태를 만들고, 다음과 같이 묻습니다.

"I have a pod stuck in a pending state in my eks-workshop cluster. Find the cause of the failure and provide me with a summary of the approach to solve it."

Kiro는 list_k8s_resourcesmanage_k8s_resource(Pod describe) → get_k8s_eventssearch_eks_troubleshoot_guide 순서로 도구를 엮어 호출하고, "PVC 생성 / 볼륨 마운트 제거 / Pod 삭제" 세 가지 해법을 제안합니다.

  1. Advanced 트러블슈팅: ConfigMap 조작으로 만든 CrashLoopBackOff

Advanced 시나리오는 carts 서비스의 ConfigMap에서 로컬 DynamoDB 엔드포인트(http://carts-dynamodb:8000)를 빼서, Pod가 실제 AWS DynamoDB로 연결을 시도하게 만듭니다. 사전 준비 단계에서 prepare-environment aiml/q-cli가 미리 깔아둔 DynamoDB 테이블·IAM 정책·Pod Identity Association이 정확히 이 시나리오의 무대입니다. Pod는 곧 CrashLoopBackOff 상태로 떨어집니다.

사용자가 던지는 프롬프트는 다음 한 줄입니다.

"I have a pod in my eks-workshop cluster that is with status CrashLoopBackOff. Troubleshoot the issue and resolve it for me."

Kiro는 Pod 상태 조회에 이어 get_policies_for_role로 Pod의 IAM Role에 묶인 정책을 가져오고, use_aws 도구로 AWS 측 상태까지 확인해 다음 에러를 근본 원인으로 식별합니다.

User: arn:aws:sts::1234567890:assumed-role/eks-workshop-carts-dynamo/...
  is not authorized to perform: dynamodb:Query

Basic이 "해법 제안"으로 끝났다면 Advanced는 IAM 역할에 dynamodb:GetItem·Query 등의 inline policy를 직접 추가하고 Pod를 재시작하는 데까지 갑니다. Kiro가 진단 보조에서 수정 실행자로 넘어가는 지점이며, 회고 섹션에서 짚는 "MCP server에 위임된 권한이 곧 Kiro 한 줄의 폭발 반경"이 추상적 경고가 아니라 실제로 IAM 정책 변경으로 일어난다는 의미를 보여줍니다.

권한이 강할 수록 검토해보자

문제를 쉽게 찾고 진행할 수는 있지만, 이게 옳은 판단인지는 제대로 된 트러블슈팅 방안인지 검토 후 처리하는 것이 좋습니다.

운영 관점에서 짚을 포인트

Part 3로 이어지는 다리

LAB 3에서 본 "MCP server를 매개로 한 EKS 운영 자동화"는 Part 3: Agentic AI Platform에서 다룰 멀티 에이전트 플랫폼의 한 축과 직접 닿아 있습니다. 여기서는 Kiro가 MCP 도구를 호출하는 단일 운영 인터페이스였지만, Part 3에서는 같은 MCP 패턴이 에이전트 애플리케이션 내부의 tool calling, 멀티 에이전트 협업, 메모리, 게이트웨이 구조로 확장됩니다.

워크샵을 따라가며 느낀 포인트

마치며

이번 편에서는 EKSworkshop AI/ML 트랙을 따라가며 EKS 위 AI/ML 워크로드의 기반을 정리했습니다. 특히 NVIDIA GPU가 아닌 AWS Neuron 가속기와 Kiro 기반 운영 자동화의 관점에 초점을 맞췄습니다.

Part 2: GenAI on EKS로 추론 서빙 운영하기에서는 이번 편에서 가볍게 통과시킨 vLLM을 NVIDIA GPU 위에서 본격적으로 다루며, GPU Operator·DCGM 관측·KServe 배포까지 추론 서빙의 운영 디테일을 정리합니다. 이어서 Part 3: Agentic AI Platform으로 멀티 에이전트 플랫폼 구축하기에서는 Kiro LAB에서 본 MCP 패턴이 실제 에이전트 플랫폼의 tool calling, 에이전트 간 협업, 세션/메모리, 게이트웨이 구조로 어떻게 이어지는지 살펴봅니다.