WellSpring

AEWS 11주차 - ML Infra(GPU) on EKS 본문

AEWS

AEWS 11주차 - ML Infra(GPU) on EKS

daniel00324 2025. 4. 18. 15:35

목차

     
    ※ 본 게재 글은 gasida님의 'AEWS' 스터디 중 최영락님의 강의내용과 실습예제 및 AWS 공식 Workshop 과정을 참고하여 작성하였습니다.


    [ AI 워크로드에 대한 컨테이너 사용 ]

    ☞ 최근 기업 간 경쟁력 측면의 한 축으로 'Machine Learning""Deep Learning" 2개의 화두가 대두되고 있다. 해당 기술을 기반으로한 서비스를 제공하기 위해 더 빠른 GPU 및 네트웍, 메모리 등의 종합적인 인프라와 S/W 측면의 모델의 중요성이 강조되고 있다. 모델들의 효율적인 학습과 워크로드를 제공하기 위해 GPU의 병렬처리 능력 및 컨테이너 기술에 대한 이해가 필요하다.
     
    [ More ... ]

    더보기

    1. 전통적 접근 방식의 한계

     - 베어메탈 기반의 서버에 GPU 드라이버와 라이브러리 사용 시, 다음과 같은 심각한 문제점에 봉착하게 된다.

     

    • 환경 구성의 복잡성: CUDA, cuDNN 등 복잡한 드라이버 스택 설치 및 관리가 필요. 특히 버전 호환성 문제로 인해 특정 프레임워크(TensorFlow, PyTorch)가 특정 CUDA/cuDNN 버전만 지원하는 경우가 많았음.
    • 재현성 부족: 동일한 실험 환경을 다른 시스템에서 재현하기 어려움. '내 컴퓨터에서는 잘 작동하는데요?.'와 같은 이야기를 많이 들을 수 있었음.
    • 리소스 비효율성: 고가의 GPU 리소스가 특정 사용자나 프로젝트에 고정되어 활용도가 저하. (베어메탈 GPU 서버의 활용률은 30% 미만인 경우가 많았음)
    • 확장성 제한: 대규모 분산 학습을 위한 인프라 확장이 어려웠음. 새로운 GPU 서버를 추가할 때마다 동일한 환경 구성 과정을 반복 필요.

     2. 컨테이너 기술 (2가지 축)

    • Cgroups (Control Groups): 프로세스 그룹의 리소스 사용(CPU, 메모리, 디스크 I/O, 네트워크 등)을 제한하고 격리하는 메커니즘
    • Namespaces: 프로세스가 시스템의 특정 리소스만 볼 수 있도록 격리하는 기능 Linux는 여러 유형의 네임스페이스(PID, 네트워크, 마운트, UTS, IPC, 사용자 등)를 제공

    [ 제약사항 ]

    ☞ 물리적으로 분할하기 어려운 GPU: CPU 코어나 메모리와 달리, 초기 GPU는 물리적으로 분할하여 여러 컨테이너에 할당하기 어려웠음 (최근에는 MIG 기술로 개선됨 - Nvidia GPU A100에서 새롭게 생긴 기능, 2020년 등장).

     

    ▶ 참고: https://brunch.co.kr/@f38b64b143b343c/19 / https://everenew.tistory.com/491

     

    3. MIG vs. vGPU  - ref. ChatGPT

    항목MIG (Multi-Instance GPU)vGPU (Virtual GPU)
    기술 방식 GPU의 하드웨어 자원을 논리적으로 분할 (엔비디아 A100 이후 지원) 소프트웨어 기반 가상화 (vGPU Manager가 VM에 GPU 리소스를 할당)
    리소스 격리성 ★★★ 완벽한 하드웨어 격리 (SM, memory, cache 등 분리) ★☆☆ 자원 공유 기반, 간섭 발생 가능
    지원 GPU 모델 A100, H100, 일부 L40 등 (Ampere, Hopper 아키텍처) 다양한 GPU (T4, A10, A16 등 포함)
    용도 HPC, AI 모델 학습, 딥러닝 추론 등 고성능 워크로드 VDI, 그래픽 작업, 경량 AI 추론 등
    성능 일관성 매우 높음 (다른 인스턴스 영향 無) 중간~낮음 (리소스 경쟁 발생 가능)
    설정 난이도 중간~높음 (nvidia-smi CLI 활용, 리소스 설계 필요) 쉬움~중간 (vGPU 매니저 및 VM 설정)
    VM 통합 여부 주로 컨테이너 환경 (VM도 가능하긴 함) VM 중심 (Citrix, VMware 등과 통합 용이)
    관리 툴 nvidia-smi, Kubernetes + GPU Operator 등 NVIDIA vGPU Manager, vSphere, Citrix 등

     

    4. 컨테이너 환경에서의 GPU 리소스 사용 진화 (단일 GPU)

    • 초기 단계 (2016-2018)
      • 초기에는 GPU 장치 파일을 컨테이너에 직접 마운트하고 필요한 라이브러리를 볼륨으로 공유해야 했음.
      • 아래는 Tensorflow에서 CUDA를 통해 NVIDIA GPU 장치에 액세스하도록 Docker 명령어를 수동으로 실행하는 예시임
    docker run --device=/dev/nvidia0:/dev/nvidia0 \
               --device=/dev/nvidiactl:/dev/nvidiactl \
               -v /usr/local/cuda:/usr/local/cuda \
               tensorflow/tensorflow:latest-gpu

     

    • 이 방식 문제점
      • 모든 장치 파일을 수동으로 지정해야 함
      • 호스트와 컨테이너 간 라이브러리 버전 충돌 가능성
      • 여러 컨테이너 간 GPU 공유 메커니즘 부재
      • 오케스트레이션 환경에서 자동화하기 어려움

    • NVIDIA Container Runtime 활용 (2018-2020)
      • NVIDIA는 이러한 문제를 해결하기 위해 NVIDIA Container Runtime을 개발하였음. NVIDIA Container Runtime: Docker, CRI-O 등 컨테이너 기술에서 사용하는 Open Containers Initiative (OCI) 스펙과 호환되는 GPU 인식 컨테이너 런타임임.
      • 이 런타임은 다음과 같은 기능을 자동화함:
        • GPU 장치 파일 마운트
        • NVIDIA 드라이버 라이브러리 주입
        • CUDA 호환성 검사
        • GPU 기능 감지 및 노출
    # Docker 19.03 이전 버전 사용
    docker run --runtime=nvidia nvidia/cuda:11.0-base nvidia-smi
    
    # Docker 19.03 이후부터는 더 간단하게 --gpus 플래그를 사용
    docker run --gpus '"device=0,1"' nvidia/cuda:11.0-base nvidia-smi
    • 이 방식을 통해 다음과 같은 개선점을 얻음
      • 자동화된 GPU 검출 및 설정
      • 호스트-컨테이너 간 드라이버 호환성 자동 관리
      • 컨테이너 이미지 이식성 향상

    apiVersion: v1
    kind: Pod
    metadata:
    name: gpu-pod
    spec:
    containers:
      - name: gpu-container
        image: nvidia/cuda:11.0-base
        command: ["nvidia-smi"]
        resources:
        limits:
          nvidia.com/gpu: 2 # 2개의 GPU 요청
    • 이 방식을 통해 다음과 같은 장점 지원:
      • 선언적 리소스 관리
      • 클러스터 수준의 GPU 리소스 스케줄링
      • 자동화된 GPU 할당 및 격리
      • 다중 테넌트 환경에서의 리소스 공정성

     

    ☞ 이제 AWS 워크샵을 통해 GenAI & ML 에 대해 경험해 보자!!


    Workshop : Build GenAI & ML for Performance and Scale, using Amazon EKS, Amazon FSx and AWS Inferentia

    ☞ Introduction

    더보기

    이 워크숍에서는 다음을 수행하는 방법을 배웁니다.

    1. Amazon EKS 클러스터에 vLLM 및 WebUI Pod를 배포하여 Kubernetes에 제너레이티브 AI 챗봇 애플리케이션을 배포하고, Amazon FSx for Lustre 및 Amazon S3를 사용하여 Mistral-7B 모델을 저장 및 액세스하고, AWS Inferentia Accelerator를 사용하여 제너레이티브 AI 워크로드에 Accelerate Compute를 활용합니다.
    2. 추가 노드가 필요한 추가 Pod 요청이 있는 경우 Karpenter를 사용하여 EKS 노드 수를 확장하여 확장 및 운영 효율성을 높일 수 있습니다.
    3. Amazon EKS 클러스터에서 AWS Inferentia Accelerated Compute를 새로운 노드 풀로 사용하여 제너레이티브 AI 애플리케이션을 강화할 수 있습니다.
    4. Amazon FSx for Lustre 및 Amazon S3를 모델 및 데이터를 호스팅할 성능 및 확장 가능한 데이터 계층으로 구성합니다.
    5. 데이터 계층에서 운영 효율성 달성: 여러 복사본을 저장하지 않고 컨테이너 Pod 전체에서 동일한 모델 데이터에 액세스하고, 분산 액세스 및 DR 공유와 같은 시나리오를 위해 지역 간에 데이터를 원활하게 공유합니다.

    대상: DevOps 엔지니어, 머신 러닝 과학자/엔지니어, 컨테이너 및 스토리지 엔지니어, 클라우드 아키텍트

    사전 요구 사항: AWS 컨테이너 및 AWS 클라우드에 대한 기본적인 이해가 필요한 것이 좋습니다.

    소요 시간 : 약 2 시간이 소요됩니다.

     

     

    [ 개념 이해하기 ]

    더보기

    ▶ 생성형 AI 및 머신 러닝

    생성형 AI와 머신 러닝(ML)은 기업이 운영 및 혁신 방식을 혁신할 수 있도록 지원합니다. 생성형 AI는 텍스트, 이미지, 오디오 및 소프트웨어 코드와 같은 프롬프트에서 새로운 콘텐츠를 생성하기 위해 대규모 언어 모델(LLM)을 활용하는 인공 지능 클래스를 말합니다.

      

      대규모 언어 모델(LLM)이란 ?

    대규모 언어 모델(LLM)은 자연어의 패턴과 구조를 학습하기 위해 방대한 양의 텍스트 데이터에 대해 훈련된 기계 학습 모델의 한 유형입니다. 그런 다음 이러한 모델을 텍스트 생성, 질문 답변 및 언어 번역과 같은 광범위한 자연어 처리 작업에 사용할 수 있습니다. 이 랩에서는 70억 개의 매개변수가 있는 특정 LLM 모델인 오픈 소스 Mistral-7B-Instruct 모델을 사용할 것입니다. 이름의 "Instruct"는 이 모델이 지침을 따르고 단순히 텍스트를 생성하는 것을 넘어 다양한 작업을 수행하도록 훈련되었다는 사실, 즉 채팅 응용 프로그램에 적합하다는 사실을 나타냅니다. 이 워크숍에서는 이 오픈 소스 LLM 모델을 사용하게 됩니다.

     

      vLLM이란?

    vLLM(가상 대규모 언어 모델)  는 LLM 추론 및 제공을 위한 사용하기 쉬운 오픈 소스 라이브러리입니다. Mistral-7B-Instruct와 같은 LLM 모델을 배포하여 텍스트 생성 추론을 제공할 수 있는 프레임워크를 제공합니다. vLLM은 OpenAI API와 호환되는 API를 제공하여 LLM 애플리케이션을 쉽게 통합할 수 있습니다.

     

    vLLM은 다음과 같은 기능을 통해 빠릅니다.

    • 최첨단 서빙 처리량
    • PagedAttention을 통한 어텐션 키 및 가치 메모리의 효율적인 관리
    • 들어오는 요청의 지속적인 일괄 처리
    • CUDA/HIP 그래프를 사용한 빠른 모델 실행

    vLLM은 다음과 같은 기능을 통해 유연하고 사용하기 쉽습니다.

    • 인기 있는 HuggingFace 모델과의 원활한 통합
    • OpenAI 호환 API 서버
    • 접두사 캐싱 지원
    • AWS Neuron, NVIDIA GPU 등과 같은 칩셋 지원

     Amazon EKS에서 vLLM을 사용하여 Mistral-7B-Instruct 배포

    OpenAI 호환 엔드포인트로 텍스트 생성 추론 기능을 제공하기 위해 Amazon Elastic Kubernetes Service(EKS)에서 vLLM 프레임워크를 사용하여 Mistral-7B-Instruct 모델을 배포할 예정입니다. Karpenter를 사용하여 AWS inferentia2 EC2 노드(Generative AI용으로 설계된 가속 컴퓨팅)를 가동하고 컨테이너 이미지에서 vLLM Pod를 시작합니다.

     

     Amazon EKS(Elastic Kubernetes Service)란 무엇입니까?

    아마존 EKS 는 자체 Kubernetes 제어 플레인 또는 작업자 노드를 설치 및 운영하지 않고도 AWS에서 Kubernetes를 사용하여 컨테이너 기반 앱을 쉽게 배포, 실행, 관리 및 확장할 수 있는 관리형 서비스입니다. Amazon EKS 클러스터는 수천 개의 컨테이너를 지원하도록 확장할 수 있으므로 Amazon EKS에서 LLM을 조정하고 배포할 수 있는 제너레이티브 AI 및 ML 워크로드에 적합합니다. Amazon EKS는 제너레이티브 AI 및 기계 학습 워크로드에 필요한 신속한 확장 및 축소를 달성하고 최적의 비용 효율성을 달성하는 데 도움이 되는 효과적인 오케스트레이터 역할을 합니다.


     [ 추론 서비스를 사용하는 방법 ]

    워크숍에서 배포할 vLLM 호스팅 Mistral-7B-Instruct 모델에서 제공하는 OpenAI 호환 엔드포인트를 사용하도록 설계된 "Open WebUI" 애플리케이션을 사용하여 추론 서비스에 연결할 수 있습니다. Open WebUI 애플리케이션을 사용하면 채팅 기반 인터페이스를 통해 LLM 모델과 상호 작용할 수 있습니다. Open WebUI 애플리케이션을 사용하려면 애플리케이션 컨테이너를 배포하고 제공된 WebUI URL에 연결한 다음 LLM 모델과 채팅을 시작하기만 하면 됩니다. WebUI 애플리케이션은 VLLM 호스팅 Mistral-7B-Instruct 모델과의 통신을 처리하여 원활한 사용자 경험을 제공합니다

     

     [ 모델 및 학습 데이터 저장 및 엑세스 ]

    이 워크숍에서는 Mistral-7B-Instruct 모델이 Amazon S3 버킷에 저장됩니다 아마존 S3 에 연결되어 있습니다. Amazon FSx for Lustre 파일 시스템 S3 . vLLM 컨테이너는 Generative AI Chat 애플리케이션에 대해 마운트된 Amazon FSx for Lustre 인스턴스를 통해 Mistral 모델 데이터를 사용합니다. Amazon FSx for Lustre는 속도가 중요한 워크로드를 위해 확장 가능한 고성능 파일 시스템을 제공하고, 밀리초 미만의 지연 시간을 제공하며, TB/s의 처리량과 수백만 IOPS로 확장할 수 있는 완전관리형 서비스입니다. 또한, Amazon FSx는 Amazon S3(내구성, 가용성 및 확장성이 뛰어난 객체 저장소)와 통합되므로 Lustre 고성능 파일 시스템으로 방대한 양의 클라우드 데이터를 쉽게 저장, 액세스 및 처리할 수 있습니다.

     

     [ 추론 서비스를 사용하는 방법 ]

    AWS Inferentia 액셀러레이터  딥 러닝(DL) 및 생성형 AI 추론 애플리케이션을 위해 Amazon EC2에서 가장 저렴한 비용으로 높은 성능을 제공하도록 AWS에서 설계했으며, Inferentia2 기반 Amazon EC2 Inf2 인스턴스는 대규모 언어 모델(LLM)과 같이 점점 더 복잡해지는 모델을 배포하는 데 최적화되어 있습니다. AWS 뉴런 SDK  는 컴파일러, 런타임 및 프로파일링 도구가 포함된 SDK로, 고성능 및 비용 효율적인 딥 러닝(DL) 가속을 제공합니다. AWS Neuron SDK는 개발자가 PyTorch 및 TensorFlow와 같은 인기 있는 프레임워크와 기본적으로 통합되는 AWS Inferentia 액셀러레이터에 모델을 배포하는 데 도움이 되므로 기존 코드 및 워크플로를 계속 사용하고 Inferentia 액셀러레이터에서 실행할 수 있습니다.

     


    1. 환경설정

    1.1 cloud9 

    더보기

    Step1. IAM 역할 검증

     

    Step2. EKS 클러스터 변수 세팅

     

    Step3. Kubeconfig 파일 업데이트

     

     

    1.2 작업장 환경 살펴보기

    더보기

    Step1. karpenter 설치 살펴보기

    Karpenter 컨트롤러 파드의 출력을 검사하면 다음과 같은 환경 변수가 설정된 것을 볼 수 있다.

    • CLUSTER_ENDPOINT - 연결할 새 노드에 대한 외부 Kubernetes 클러스터 엔드포인트입니다. 엔드포인트가 지정되지 않은 경우 노드는 DescribeCluster API를 사용하여 클러스터 엔드포인트를 검색합니다.
    • INTERRUPTION_QUEUE - EKS Terraform 블루프린트의 일부로 생성된 SQS 대기열에 대한 엔드포인트입니다. 이 SQS 대기열은 스팟 중단 알림 및 AWS Health 이벤트를 보관하는 데 사용됩니다.

    Step2. karpenter node 확인 ( 2개 이상 기동 - 정상 )

    Step3. Karpenter 로그 표시 (alias 설정 : kl )

    alias kl='kubectl -n karpenter logs -l app.kubernetes.io/name=karpenter --all-containers=true -f --tail=20'

     


    2. Configure storage - Host model data on Amazon FSx for Lustre

    ☞ Module overview

    더보기

    In this workshop the Mistral-7B-Instruct model is stored in an Amazon S3 bucket, which is liked to an Amazon FSx for Lustre File system, which the vLLM container will use for the Generative AI ChatBot application.

    In this module you will deploy and integrate an FSx for Lustre instance (which will serve your model data) with your Amazon EKS cluster (which will host your Generative AI application), and learn about Kubernetes storage concepts, such as the CSI driver, Persistent Volumes, StorageClass,and Static vs Dynamic storage provisioning. The infrastructure for this module, comprises of an Amazon EKS cluster with two EC2 worker nodes, Amazon FSx for Lustre file system, and Amazon S3 Bucket.

     

    1) Amazon FSx for Lustre

    Amazon FSx for Lustre  속도가 중요한 워크로드(예: 기계 학습, 분석, 고성능 컴퓨팅)에 고성능 병렬 파일 시스템을 제공하는 완전 관리형 서비스입니다. FSx for Lustre는 밀리초 미만의 지연 시간으로 데이터에 액세스할 수 있으며 TB/s의 처리량과 수백만 IOPS로 확장할 수 있는 기능을 제공합니다. FSx for Lustre는 다음과 통합됩니다. 아마존 S3 따라서 Lustre 고성능 파일 시스템을 통해 방대한 양의 클라우드 데이터를 쉽게 저장, 액세스 및 처리할 수 있습니다. S3 버킷에 연결되면 FSx for Lustre 파일 시스템은 S3 객체를 최종 사용자에게 파일로 투명하게 표시하며, Lustre 파일 시스템에서 파일이 추가, 수정 또는 삭제될 때 연결된 S3 버킷의 콘텐츠를 자동으로 업데이트할 수 있습니다.

    Amazon FSx for Lustre  is a fully managed service that provides a high-performance parallel file system for workloads where speed matters (i.e. Machine Learning, analytics, high performance compute). FSx for Lustre provides sub-millisecond latency access to data, and the ability to scale to TB/s of throughput and millions of IOPS. FSx for Lustre also integrates with Amazon S3 , making it easy for you to store, access and process vast amounts of cloud data with a Lustre high-performance file system. When linked to an S3 bucket, an FSx for Lustre file system transparently presents S3 objects as files to the end user, and can automatically update the contents of the linked S3 bucket, as files are added to, modified, or deleted from the Lustre file system.

     

    2) Kubernetes storage concepts, and intergration with FSx for Lustre

    CSI 드라이버 - 컨테이너 스토리지 인터페이스(CSI)는 블록 및 파일 스토리지 시스템을 쿠버네티스와 같은 컨테이너 오케스트레이션 시스템에 노출하기 위한 표준으로, 쿠버네티스가 컨테이너화된 애플리케이션의 영구 스토리지를 기본적으로 관리할 수 있도록 합니다.

    FSx for Lustre 컨테이너 스토리지 인터페이스(CSI) 드라이버는 Amazon EKS 클러스터가 FSx for Lustre 파일 시스템을 기반으로 하는 영구 볼륨의 수명 주기를 관리할 수 있도록 하는 CSI 인터페이스를 제공합니다. FSx for Lustre CSI 드라이버를 사용하면 컨테이너 워크로드를 위한 지연 시간이 짧은 고성능 영구 스토리지를 빠르고 쉽게 통합할 수 있습니다.

    StorageClass - StorageClass는 EKS 관리자가 제공하는 스토리지의 "클래스"를 설명할 수 있는 방법을 제공합니다. 서로 다른 스토리지 클래스는 서로 다른 스토리지 유형(즉, Amazon FSx, Amazon EBS 또는 Amazon EFS와 같은 서로 다른 AWS 스토리지 서비스 유형) 또는 백업 정책에 매핑될 수 있습니다. 쿠버네티스는 이러한 스토리지 클래스가 무엇을 나타내는지에 대해 의견이 분별합니다

    영구 볼륨(PV) - 관리자가 이미 프로비저닝한 EKS 클러스터에 매핑된 스토리지 볼륨입니다. 퍼시스턴트 볼륨의 라이프사이클은 파드의 수명을 넘어서므로, 스토리지 볼륨을 사용하는 파드의 수명 이후에도 유지되어야 하는 공유 데이터에 대한 액세스가 필요한 파드에 이상적인 선택이다.

    PVC(Persistent Volume Claim) - PVC(Persistent Volume Claim)는 사용자가 스토리지 볼륨에 대한 요청입니다. 클레임은 특정 크기 및 액세스 모드를 요청할 수 있습니다(예: ReadWriteOnce, ReadOnlyMany 또는 ReadWriteMany를 탑재할 수 있음)

     

    CSI driver - The Container Storage Interface (CSI) is a standard for exposing block and file storage systems to Container Orchestration Systems like Kubernetes, allowing Kubernetes to natively manage persistent storage for containerized applications.

    The FSx for Lustre Container Storage Interface (CSI) driver provides a CSI interface that allows Amazon EKS clusters to manage the lifecycle of persistent volumes which are based on FSx for Lustre file systems. The FSx for Lustre CSI driver allows for fast and easy integration of high-performance, low-latency persistent storage for container workloads.

    StorageClass - A StorageClass provides a way for EKS administrators to describe the "classes" of storage they offer. Different storage classes might map to different storage types (i.e. different AWS Storage Service types such as Amazon FSx, or Amazon EBS, or Amazon EFS), or to backup policies. Kubernetes is unopinionated about what these storage classes represent

    Persistent volume (PV) - is a storage volume mapped to an EKS cluster that has already been provisioned by an administrator. A Persistent Volume's lifecycle goes beyond the life of a Pod, hence it is an ideal choice for Pods that require access to shared data, which needs to be persisted beyond the life of the Pods that use the storage volume.

    Persistent volume claim (PVC) - Persistent Volume Claim (PVC) is the request for storage volume by a user. Claims can request specific size and access modes (e.g., they can be mounted ReadWriteOnce, ReadOnlyMany or ReadWriteMany)

     

    Static vs Dynamic provisioning of storage resources:

    • Static provisioning - This involves a two step process to create and use storage:
      • 1/An administrator creates the backend storage volume on the storage instance (i.e. a new FSx for Lustre instance), and then creates a corresponding Persistent Volume (PV) definition for the FSx for Lustre Instance on the Kubernetes cluster.
      • 2/The application developer then submits a PVC request to use the Persistent Volume in their Pod.
    • Dynamic provisioning - Dynamic provisioning eliminates the need for administrators to pre-provision storage to the EKS cluster. Instead, users can create and use persistent storage on-demand, where it automatically provisions a Persistent Volume (and its associated FSx for Lustre instance) when a user makes a Persistent Volume Claim (PVC) request.
    • 정적 프로비저닝 - 여기에는 스토리지를 만들고 사용하는 두 단계 프로세스가 포함됩니다.
      • 1/관리자가 스토리지 인스턴스(즉, 새 FSx for Lustre 인스턴스)에 백엔드 스토리지 볼륨을 생성한 다음 Kubernetes 클러스터의 FSx for Lustre 인스턴스에 대한 해당 PV(영구 볼륨) 정의를 생성합니다.
      • 2. 그런 다음 애플리케이션 개발자는 파드에서 퍼시스턴트 볼륨을 사용하기 위한 PVC 요청을 제출한다.
    • 동적 프로비저닝 - 동적 프로비저닝을 사용하면 관리자가 EKS 클러스터에 스토리지를 미리 프로비저닝할 필요가 없습니다. 대신, 사용자는 온디맨드 방식으로 퍼시스턴트 스토리지를 생성하고 사용할 수 있으며, 사용자가 퍼시스턴트 볼륨 클레임(PVC) 요청을 할 때 퍼시스턴트 볼륨(및 관련 FSx for Lustre 인스턴스)을 자동으로 프로비저닝할 수 있습니다.

     

    2.1 CSI 드라이버 배포

    Step1. 전제조건 - account-id  환경 변수 설정

    더보기
    ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)

    Step2. CSI 드라이버가 사용자를 대신하여 AWS API를 호출 할 수 있도록 허용하는 IAM 정책 및 서비스 계정 생성

    더보기

    아래 명령을 복사하고 실행하여 fsx-csi-driver.json 파일을 만듭니다.

    cat << EOF >  fsx-csi-driver.json
    {
        "Version":"2012-10-17",
        "Statement":[
            {
                "Effect":"Allow",
                "Action":[
                    "iam:CreateServiceLinkedRole",
                    "iam:AttachRolePolicy",
                    "iam:PutRolePolicy"
                ],
                "Resource":"arn:aws:iam::*:role/aws-service-role/s3.data-source.lustre.fsx.amazonaws.com/*"
            },
            {
                "Action":"iam:CreateServiceLinkedRole",
                "Effect":"Allow",
                "Resource":"*",
                "Condition":{
                    "StringLike":{
                        "iam:AWSServiceName":[
                            "fsx.amazonaws.com"
                        ]
                    }
                }
            },
            {
                "Effect":"Allow",
                "Action":[
                    "s3:ListBucket",
                    "fsx:CreateFileSystem",
                    "fsx:DeleteFileSystem",
                    "fsx:DescribeFileSystems",
                    "fsx:TagResource"
                ],
                "Resource":[
                    "*"
                ]
            }
        ]
    }
    EOF

     

    Step3. IAM 정책 생성

    더보기

     

    aws iam create-policy \
            --policy-name Amazon_FSx_Lustre_CSI_Driver \
            --policy-document file://fsx-csi-driver.json

    Step4. 드라이버에 대한 K8s 서비스 계정 생성하고, 서비스 계정에 정책 연결

    더보기

    아래 명령어를 복사하고 실행하여 서비스 계정을 생성하고, 3단계에서 생성한 IAM 정책을 연결합니다.

    eksctl create iamserviceaccount \
        --region $AWS_REGION \
        --name fsx-csi-controller-sa \
        --namespace kube-system \
        --cluster $CLUSTER_NAME \
        --attach-policy-arn arn:aws:iam::$ACCOUNT_ID:policy/Amazon_FSx_Lustre_CSI_Driver \
        --approve

    ☞ 30~60초 정도 소요예정

    Step5. 생성된 역할 ARN 을 변수에 저장

    더보기
    export ROLE_ARN=$(aws cloudformation describe-stacks --stack-name "eksctl-${CLUSTER_NAME}-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa" --query "Stacks[0].Outputs[0].OutputValue"  --region $AWS_REGION --output text)

     

    생성 된 변수를 메모장에 복사합니다. 

    WSParticipantRole:~/environment $ echo $ROLE_ARN
    arn:aws:iam::236431523810:role/eksctl-eksworkshop-addon-iamserviceaccount-ku-Role1-Gvw3DDg2qp2x

     

    Step6. FSx for Lustre 의 CSI 드라이버 배포

    더보기

    다음 명령을 복사하고 실행하여 FSx for Lustre용 CSI 드라이버를 배포합니다.

    kubectl apply -k "github.com/kubernetes-sigs/aws-fsx-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.2"

     

    다음 명령을 사용하여 CSI 드라이버가 성공적으로 설치되었는지 확인합니다.

    kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-fsx-csi-driver

    Step7. 위 4단계에서 만든 서비스 계정에 주석 달기

    더보기

    복사하고 다음 명령을 실행하여 서비스 계정에 IAM 역할을 추가합니다.

    kubectl annotate serviceaccount -n kube-system fsx-csi-controller-sa \
     eks.amazonaws.com/role-arn=$ROLE_ARN --overwrite=true

    서비스 계정 내용을 확인하여 성공했는지 확인할 수 있습니다.

    kubectl get sa/fsx-csi-controller-sa -n kube-system -o yaml

     

    [ Summary ]

    더보기

    이 섹션에서는 환경 변수를 생성하고, 올바른 IAM 정책 및 역할 ARN을 사용하여 서비스 계정을 생성하고, FSx for Lustre의 CSI 드라이버를 배포하는 사전 필수 작업을 완료했습니다. 다음 섹션에서는 FSx for Lustre에 대한 PV(Persistent Volume), PVC(Persistent Volume Claim) 및 StorageClass를 생성합니다.


    2.2 EKS 클러스터에서 Persistent Volume 생성

    [ 퍼시스턴트 볼륨 생성하는 두 가지 방법 ]

    더보기
    • 정적 프로비저닝 - 관리자는 백엔드 스토리지 엔티티를 생성하고, PV를 생성하고, 사용자는 이 PV가 자신의 파드에서 사용될 수 있도록 클레임(PVC)을 생성한다.
    • 동적 프로비저닝 - 사용자가 PVC를 요청하고 PV(및 지원되는 스토리지 엔티티)는 사용자 요구 사항에 따라 CSI 드라이버에 의해 자동으로 생성됩니다. 이 방법은 관리자가 미리 생성하기 위해 별도의 프로세스가 필요하지 않습니다

     

    이 실습 섹션에서는 이미 프로비저닝한 Persistent Volumes(PV)에 대한 정적 프로비저닝 방법과 Mistral-7B 모델을 저장하는 Amazon S3 버킷에 연결된 FSx for Lustre Instance를 사용합니다. 퍼시스턴트 볼륨 정의를 생성하고 퍼시스턴트 볼륨 클레임을 생성하여 vLLM Pod에서 이 스토리지 볼륨을 사용하여 Mistral-7B 모델 데이터에 액세스할 수 있습니다.

    아래 명령을 실행하여 올바른 작업으로 직접 변경하면 이 연습에 대한 명령을 실행할 수 있습니다

    cd /home/ec2-user/environment/eks/FSxL

    Cloud9 터미널에서 아래 명령을 실행하여 FSx Lustre 인스턴스 세부 정보(미리 생성됨)로 변수를 채웁니다.

    FSXL_VOLUME_ID=$(aws fsx describe-file-systems --query 'FileSystems[].FileSystemId' --output text)
    DNS_NAME=$(aws fsx describe-file-systems --query 'FileSystems[].DNSName' --output text)
    MOUNT_NAME=$(aws fsx describe-file-systems --query 'FileSystems[].LustreConfiguration.MountName' --output text)

     

    Step1. 퍼시스턴트 볼륨 생성

    더보기

    플레이스홀더 변수가 포함된 PV(퍼시스턴트 볼륨) yaml 파일 정의(fsxL-persistent-volume.yaml)를 살펴보겠습니다. 이 워크숍을 위해 이미 1200GiB FSx for Lustre 인스턴스를 생성했습니다. 따라서 이 퍼시스턴트 볼륨 정의에서는 'fsx-pv'라는 이름을 사용하여 EKS 클러스터 리소스로 등록하도록 1200GiB FSx for Lustre 인스턴스를 구성하기만 하면 됩니다.

    # fsxL-persistent-volume.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: fsx-pv
    spec:
      persistentVolumeReclaimPolicy: Retain
      capacity:
        storage: 1200Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteMany
      mountOptions:
        - flock
      csi:
        driver: fsx.csi.aws.com
        volumeHandle: FSXL_VOLUME_ID
        volumeAttributes:
          dnsname: DNS_NAME
          mountname: MOUNT_NAME

     

    ☞ 아래 명령을 실행하여 , 및 FSx Lustre 인스턴스의 실제 값으로 바꿉니다. FSXL_VOLUME_IDDNS_NAMEMOUNT_NAME

    sed -i'' -e "s/FSXL_VOLUME_ID/$FSXL_VOLUME_ID/g" fsxL-persistent-volume.yaml
    sed -i'' -e "s/DNS_NAME/$DNS_NAME/g" fsxL-persistent-volume.yaml
    sed -i'' -e "s/MOUNT_NAME/$MOUNT_NAME/g" fsxL-persistent-volume.yaml

     

    FSx 인스턴스 세부 정보를 사용하여 Persistent Volume 정의의 출력을 볼 수 있습니다. 1200GiB FSx for Lustre 파일 시스템과 해당 인스턴스 ID 및 DNS 이름을 생성한 것을 볼 수 있습니다.

    cat fsxL-persistent-volume.yaml

    이 퍼시스턴트볼륨(PV)을 EKS 클러스터에 배포해 보겠습니다.

    kubectl apply -f fsxL-persistent-volume.yaml

     

    "fsx-pv"라는 PV가 생성되었는지 확인합니다.

    kubectl get pv

     

     

     
    Step2. Persistent VolumeClaim 생성

    이제 이전 단계에서 정의한 퍼시스턴트볼륨(PersistentVolume)과 바인딩할 퍼시스턴트볼륨클레임(PVC)을 생성한다. fsx-pv 의 volumeName 값을 사용하여 사전 프로비저닝된 퍼시스턴트볼륨을 직접 참조하고 있습니다.

    더보기
    # fsxL-claim.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: fsx-lustre-claim
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: ""
      resources:
        requests:
          storage: 1200Gi
      volumeName: fsx-pv

     

    이 PersistentVolumeClaim을 EKS 클러스터에 배포한다.

    kubectl apply -f fsxL-claim.yaml

     

    퍼시스턴트볼륨클레임(PersistentVolumeClaim)이 퍼시스턴트볼륨(PersistentVolume)에 바인딩되어 있는지 확인한다. persistentvolumeclaim/fsx-lustre-claim 이 fsx-pv 의 볼륨에 바인딩된 것으로 표시되는 것을 볼 수 있습니다.

     

    kubectl get pv,pvc

    [ Summary ]

    더보기

    이 섹션에서는 퍼시스턴트볼륨을 성공적으로 구성하고, vLLM이 Mistral-7B 애플리케이션에 액세스하는 데 사용할 퍼시스턴트볼륨클레임을 생성했다.


    2.3 Amazon FSx 콘솔에서 옵션 및 성능 세부 정보 보기

    더보기

    이전 단계에서는 이 실습에서 사전 프로비저닝한 FSx for Lustre를 사용하여 영구 볼륨(PV)을 구성했습니다. 잠시 시간을 내어 FSx for Lustre 인스턴스에 대한 설정 및 옵션을 살펴보겠습니다. 참고: 이 워크숍의 후속 섹션에서 EKS 클러스터와 함께 자체 FSx for Lustre 인스턴스를 배포하고 구성할 수 있습니다.

    1. Amazon FSx 콘솔 . 로 이동합니다. 

    2. 계속하기 전에 오른쪽 상단에서 이 실습에 제공된 AWS 리전을 선택합니다

     

    3. FSx 콘솔에는 랩의 일부로 사전 프로비저닝된 FSx for Lustre 인스턴스의 세부 정보(그런 다음 EKS 클러스터에서 영구 볼륨으로 구성)의 세부 정보가 포함된 FSx 인스턴스 목록이 표시됩니다.

    4. 오른쪽 상단 모서리에 있는 파일 시스템 생성을 클릭하여 새 FSx for Lustre 인스턴스를 프로비저닝하기 위한 배포 옵션을 간단히 살펴보겠습니다.

    5. Amazon FSx for Lustre를 선택하고 다음을 클릭합니다.

    6. 다음 화면에서 FSx for Lustre에 대한 배포 옵션이 있음을 확인할 수 있습니다. 퍼시스턴트-SSD 또는 스크래치 스토리지에서 스토리지당 원하는 처리량 단위를 구성할 수 있는 기능과 메타데이터 IOPS 성능에 이르기까지. 압축과 같은 다른 옵션을 설정하고 Data Repository Import/Export 섹션에서 자동 데이터 가져오기/내보내기 옵션을 사용하도록 S3 연결 버킷을 구성할 수도 있습니다.

     

    7. 취소 버튼을 클릭하여 이 화면을 종료하고 FSx 콘솔로 돌아갑니다.

    8. FSx 콘솔에서 FSx 인스턴스 목록을 볼 수 있으며, 스토리지용 퍼시스턴트-SSD를 사용하여 1200GiB FSx for Lustre 인스턴스와 스토리지 단위당 250MB/s의 처리량 용량을 이미 프로비저닝했습니다.

     

    9. FSx for Lustre 인스턴스의 파일 시스템 ID를 클릭하여 구성에 대한 자세한 내용을 확인합니다.

    10. FSx 인스턴스와 관련된 세부 정보와 온라인으로 업데이트할 수 있는 항목도 표시됩니다. Update storage Capacity(스토리지 용량) 및 Update Throughput per unit of storage(스토리지 단위당 처리량 업데이트) 옵션이 있습니다.

     

    메모

    FSx for Lustre 인스턴스의 스토리지 용량을 늘리면 스토리지 단위당 처리 용량 성능도 증가합니다. 또한 스토리지 용량을 늘리지 않고 Throughput capacity(처리량 용량)를 독립적으로 늘릴 수도 있습니다(즉, 추가 스토리지 용량이 아닌 더 많은 처리량 성능이 필요함).

     

    11. 화면 하단으로 스크롤하여 Monitoring and performance(모니터링 및 성능) 탭을 클릭합니다. 여기에서 요약 메트릭(용량, 처리량, IOPS)에서 자세한 성능 메트릭(메타데이터, 성능, 네트워크 등)에 이르기까지 다양한 차원의 성능 메트릭을 볼 수 있습니다.

     

     

     

    [ summary ]

    더보기

    이제 이 모듈을 완료했습니다. 이 모듈을 통해 사용 가능한 다양한 FSx for Lustre 배포 옵션에 대해 알아보았으며, 기존 FSx 인스턴스의 스토리지, 처리량 용량 및 메타데이터 IOPS 성능 기능을 온라인으로 늘릴 수 있다는 것을 배웠습니다.


    3. Generative AI Chat 애플리케이션 배포

    [ 모듈 개요 ]

    더보기

    이 모듈에서는 Amazon EKS 클러스터에 vLLM Pod 및 WebUI Pod를 배포하여 Kubernetes에서 Generative AI 챗봇 애플리케이션을 구성 및 배포하고, Amazon FSx for Lustre 및 Amazon S3를 사용하여 Mistral-7B 모델을 저장 및 액세스하고, AWS Inferentia Accelerator를 Generative AI 워크로드의 가속 컴퓨팅으로 활용합니다.


    1.  생성형 AI 및 머신 러닝

    생성형 AI와 머신 러닝(ML)은 기업이 운영 및 혁신 방식을 혁신할 수 있도록 지원합니다. 생성형 AI는 텍스트, 이미지, 오디오 및 소프트웨어 코드와 같은 프롬프트에서 새로운 콘텐츠를 생성하기 위해 대규모 언어 모델(LLM)을 활용하는 인공 지능 클래스를 말합니다.

     

    2. 대규모 언어모델(LLM) 이란?

    대규모 언어 모델(LLM)은 자연어의 패턴과 구조를 학습하기 위해 방대한 양의 텍스트 데이터에 대해 훈련된 기계 학습 모델의 한 유형입니다. 그런 다음 이러한 모델을 텍스트 생성, 질문 답변 및 언어 번역과 같은 광범위한 자연어 처리 작업에 사용할 수 있습니다. 이 랩에서는 70억 개의 매개변수가 있는 특정 LLM 모델인 오픈 소스 Mistral-7B-Instruct 모델을 사용할 것입니다. 이름의 "Instruct"는 이 모델이 지침을 따르고 단순히 텍스트를 생성하는 것을 넘어 다양한 작업을 수행하도록 훈련되었다는 사실, 즉 채팅 응용 프로그램에 적합하다는 사실을 나타냅니다. 이 워크숍에서는 이 오픈 소스 LLM 모델을 사용하게 됩니다.

     

    3. vLLM 이란 ?

    vLLM(가상 대규모 언어 모델)  는 LLM 추론 및 제공을 위한 사용하기 쉬운 오픈 소스 라이브러리입니다. Mistral-7B-Instruct와 같은 LLM 모델을 배포하여 텍스트 생성 추론을 제공할 수 있는 프레임워크를 제공합니다. vLLM은 OpenAI API와 호환되는 API를 제공하여 LLM 애플리케이션을 쉽게 통합할 수 있습니다.

    vLLM은 다음과 같은 기능을 통해 빠릅니다.

    • 최첨단 서빙 처리량
    • PagedAttention을 통한 어텐션 키 및 가치 메모리의 효율적인 관리
    • 들어오는 요청의 지속적인 일괄 처리
    • CUDA/HIP 그래프를 사용한 빠른 모델 실행

    vLLM은 다음과 같은 기능을 통해 유연하고 사용하기 쉽습니다.

    • 인기 있는 HuggingFace 모델과의 원활한 통합
    • OpenAI 호환 API 서버
    • 접두사 캐싱 지원
    • AWS Neuron, NVIDIA GPU 등과 같은 칩셋 지원

    4. Amazon EKS에서 vLL을 사용하여 Mistral-7B-Instuct 배포

    OpenAI 호환 엔드포인트로 텍스트 생성 추론 기능을 제공하기 위해 Amazon Elastic Kubernetes Service(EKS)에서 vLLM 프레임워크를 사용하여 Mistral-7B-Instruct 모델을 배포할 예정입니다. Karpenter를 사용하여 AWS inferentia2 EC2 노드(Generative AI용으로 설계된 가속 컴퓨팅)를 가동하고 컨테이너 이미지에서 vLLM Pod를 시작합니다.

     

    4.1 AWS Inferentia 엑셀러레이터

    AWS 인퍼렌시아  는 딥 러닝 및 생성형 AI 추론 애플리케이션을 가속화하기 위해 Amazon Web Services(AWS)에서 설계한 사용자 지정 기계 학습 칩입니다. AWS Inferentia 액셀러레이터는 TensorFlow, PyTorch 및 MXNet과 같은 인기 있는 기계 학습 프레임워크를 지원하는 Amazon EC2에서 가장 저렴한 비용으로 높은 성능을 제공합니다. 기본 Inferentia2 가속기는 DL 모델을 대규모로 실행하도록 특별히 구축되었기 때문에 기계 학습 모델을 대규모로 배포하는 데 최적화되어 높은 성능과 비용 효율성을 제공합니다. AWS Inferentia2 기반 Amazon EC2 Inf2 인스턴스는 대규모 언어 모델(LLM) 및 잠재 확산 모델과 같이 점점 더 복잡해지는 모델을 배포하는 데 최적화되어 있습니다.

    AWS Inferentia는 기계 학습의 추론 단계를 가속화하는 데 사용됩니다. 추론에는 학습된 모델을 사용하여 새로운 데이터를 기반으로 예측 또는 결정을 내리는 것이 포함됩니다. 이 단계는 짧은 대기 시간과 높은 처리량이 필요한 실시간 애플리케이션 및 서비스에 매우 중요합니다. AWS Inferentia2는 다양한 추론 워크로드에 대해 높은 처리량과 짧은 지연 시간을 제공하도록 설계되었습니다. 각 Inferentia2 액셀러레이터에는 EC2 Inf2 인스턴스당 최대 12개의 Inferentia2 액셀러레이터가 있는 2개의 2세대 NeuronCore가 있습니다. 각 Inferentia2 가속기는 FP16 성능의 최대 190TFLOPS(초당 부동 작업)를 지원합니다. Inferentia2는 가속기당 32GB의 HBM을 제공하여 Inferentia1에 비해 총 메모리는 4배, 메모리 대역폭은 10배 증가합니다.

     

    4.2 AWS Neuron SDK - ML 프레임워크에 대한 기본 지원

    AWS 뉴런 SDK  는 컴파일러, 런타임 및 프로파일링 도구가 포함된 SDK로, 고성능 및 비용 효율적인 딥 러닝(DL) 가속을 제공합니다. AWS Neuron SDK는 PyTorch 및 TensorFlow와 같은 인기 있는 ML 프레임워크와 기본적으로 통합됩니다. AWS Neuron을 사용하면 이러한 프레임워크를 사용하여 두 AWS Inferentia 액셀러레이터 모두에 DL 모델을 최적으로 배포할 수 있으며, Neuron은 코드 변경을 최소화하고 공급업체별 솔루션과 연계하도록 설계되었습니다. Neuron은 Inferentia 액셀러레이터에서 자연어 처리(NLP)/이해, 언어 번역, 텍스트 요약, 비디오 및 이미지 생성, 음성 인식, 개인화, 사기 탐지 등을 위한 추론 애플리케이션을 실행할 수 있도록 지원합니다.  

    3.1 모델 추론을 위한 AWS Inferentia 노드에 vLLM 배포

    Step1. AWS Inferentia 엑셀러레이터용 Karpenter nodePool 및 EC2 NodeClass 생성

    더보기

    Karpenter 구성은 NodePool CR(사용자 정의 리소스)의 형태로 제공됩니다. NodePool은 Karpenter가 생성할 수 있는 노드와 해당 노드에서 실행할 수 있는 Pod에 대한 제약 조건을 설정합니다. NodePool은 노드 생성을 특정 컴퓨터 아키텍처로 제한하거나 여러 개를 사용하도록 유연하게 설정할 수 있습니다. 단일 Karpenter NodePool은 다양한 파드 모양을 처리할 수 있다. Karpenter는 레이블 및 선호도와 같은 Pod 속성을 기반으로 일정 및 프로비저닝 결정을 내립니다. 클러스터에는 둘 이상의 NodePool이 있을 수 있지만 지금은 추가 NodePool인 inferentia NodePool을 선언할 것입니다.

     

    1. Karpenter NodePool은 Karpenter가 생성할 수 있는 노드와 해당 노드에서 실행할 수 있는 파드에 대한 제약 조건을 설정한다. AWS 관련 설정은 NodeClasses를 사용하여 설정할 수 있습니다. 여러 노드 풀이 동일한 EC2NodeClass를 가리킬 수 있습니다.

    2. Cloud9 터미널에서 작업 디렉터리로 변경합니다.

    cd /home/ec2-user/environment/eks/genai

     

    3. 배포할 Karpenter NodePool 정의를 살펴보겠습니다. 생성 AI 애플리케이션(vLLM 포드)을 구동하는 데 사용할 AWS Inferentia INF2 가속 컴퓨팅 노드에 대한 새로운 노드 풀을 생성합니다

    cat inferentia_nodepool.yaml
    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: inferentia
      labels:
        intent: genai-apps
        NodeGroupType: inf2-neuron-karpenter
    spec:
      template:
        spec:
          taints:
            - key: aws.amazon.com/neuron
              value: "true"
              effect: "NoSchedule"
          requirements:
            - key: "karpenter.k8s.aws/instance-family"
              operator: In
              values: ["inf2"]
            - key: "karpenter.k8s.aws/instance-size"
              operator: In
              values: [ "xlarge", "2xlarge", "8xlarge", "24xlarge", "48xlarge"]
            - key: "kubernetes.io/arch"
              operator: In
              values: ["amd64"]
            - key: "karpenter.sh/capacity-type"
              operator: In
              values: ["spot", "on-demand"]
          nodeClassRef:
            group: karpenter.k8s.aws
            kind: EC2NodeClass
            name: inferentia
      limits:
        cpu: 1000
        memory: 1000Gi
      disruption:
        consolidationPolicy: WhenEmpty
        # expireAfter: 720h # 30 * 24h = 720h
        consolidateAfter: 180s
      weight: 100
    ---
    apiVersion: karpenter.k8s.aws/v1
    kind: EC2NodeClass
    metadata:
      name: inferentia
    spec:
      amiFamily: AL2
      amiSelectorTerms:
      - alias: al2@v20240917
      blockDeviceMappings:
        - deviceName: /dev/xvda
          ebs:
            deleteOnTermination: true
            volumeSize: 100Gi
            volumeType: gp3
      role: "Karpenter-eksworkshop" 
      subnetSelectorTerms:          
        - tags:
            karpenter.sh/discovery: "eksworkshop"
      securityGroupSelectorTerms:
        - tags:
            karpenter.sh/discovery: "eksworkshop"
      tags:
        intent: apps
        managed-by: karpenter

     

    4. AWS Inferentia INF2 가속 컴퓨팅 노드에 대한 Karpenter NodePool 정의를 배포해 보겠습니다.

    kubectl apply -f inferentia_nodepool.yaml

     

     5. NodePool 및 EC2 NodeClass 확인 :

    kubectl get nodepool,ec2nodeclass inferentia

     

     

    Step2. Neuron 장치 플러그인 및 그케쥴러 설치

    중요 : 실습 시간을 절약하기 위해 Mistral-7B 모델은 이미 AWS Neuron SDK를 사용하여 다운로드 및 컴파일되었으므로 이 워크숍의 AWS Inferentia Accelerated Computes 노드에 배포할 수 있습니다.

    더보기

    이제 EKS 클러스터에 Neuron Device Plugin 및 Neuron Scheduler를 설치해야 합니다.

     

    Step1. Neuron Device 플러그인 설치

    - Neuron 디바이스 플러그인은 Neuron 코어 및 디바이스를 쿠버네티스에 리소스로 노출합니다.

    - Neuron 디바이스 플러그인을 설치합니다(kubectl 경고 무시).

    kubectl apply -f https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/master/src/k8/k8s-neuron-device-plugin-rbac.yml
    kubectl apply -f https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/master/src/k8/k8s-neuron-device-plugin.yml

     

    Step2. Neuron Scheduler 설치

     - Neuron 스케줄러 확장은 둘 이상의 Neuron 코어 또는 디바이스 리소스가 필요한 Pod를 예약하는 데 필요합니다. Neuron 스케줄러 확장은 인접하지 않은 코어/디바이스 ID가 있는 노드를 필터링하고 이를 필요로 하는 POD에 대해 연속 코어/디바이스 ID를 할당합니다.

     - Neuron 스케줄러를 설치합니다.

    kubectl apply -f https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/master/src/k8/k8s-neuron-scheduler-eks.yml
    kubectl apply -f https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/master/src/k8/my-scheduler.yml

     

    Step3. vLLM 애플리케이션 Pod 배포

    - 이제 모델 제공 기능 및 추론 엔드포인트를 제공하는 vLLM Pod를 배포합니다. vLLM Pod가 온라인 상태가 되면 FSx for Lustre 기반 퍼시스턴트 볼륨에서 Mistral-7B 모델(29GB)을 메모리로 로드하면 사용할 준비가 됩니다.

     

    1. vLLM Pod를 배포합니다.

    kubectl apply -f mistral-fsxl.yaml

     

    2. vLLM 배포는 약 7-8분 정도 소요됩니다. (다음 단계를 계속할 수 있으며 이 단계가 완료될 때까지 기다릴 필요가 없습니다.)

    3. 아래 명령을 실행하여 vLLM의 mistral-fsxl.yaml 배포 파일을 검사합니다.

    메모

    AWS Inferentia Neuron 코어에 대한 요청, FSx for Lustre(fsx-lustre-claim)를 사용하여 이전에 생성한 PVC를 사용하는 영구 스토리지 및 일부 모델 파라미터에 대한 요청과 함께 단일 Pod 배포 요청을 확인할 수 있습니다.

     

    WSParticipantRole:~/environment/eks/genai $ cat mistral-fsxl.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-mistral-inf2-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: vllm-mistral-inf2-server
      template:
        metadata:
          labels:
            app: vllm-mistral-inf2-server
        spec:
          tolerations:
          - key: "aws.amazon.com/neuron"
            operator: "Exists"
            effect: "NoSchedule"
          containers:
          - name: inference-server
            image: public.ecr.aws/u3r1l1j7/eks-genai:neuronrayvllm-100G-root
            resources:
              requests:
                aws.amazon.com/neuron: 1
              limits:
                aws.amazon.com/neuron: 1
            args:
            - --model=$(MODEL_ID)
            - --enforce-eager
            - --gpu-memory-utilization=0.96
            - --device=neuron
            - --max-num-seqs=4
            - --tensor-parallel-size=2
            - --max-model-len=10240
            - --served-model-name=mistralai/Mistral-7B-Instruct-v0.2-neuron
            env:
            - name: MODEL_ID
              value: /work-dir/Mistral-7B-Instruct-v0.2/
            - name: NEURON_COMPILE_CACHE_URL
              value: /work-dir/Mistral-7B-Instruct-v0.2/neuron-cache/
            - name: PORT
              value: "8000"
            volumeMounts:
            - name: persistent-storage
              mountPath: "/work-dir"
          volumes:
          - name: persistent-storage
            persistentVolumeClaim:
              claimName: fsx-lustre-claim
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: vllm-mistral7b-service
    spec:
      selector:
        app: vllm-mistral-inf2-server
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8000

     

    4. 다음 명령이 다음으로 전환될 때까지 주기적으로 다음 명령을 실행하여 vLLM Pod 생성을 모니터링할 수 있습니다. Running

    kubectl get pod

     

    5.  Amazon EKS 클러스터 콘솔  로 이동합니다.

    6. 클러스터 이름(예: eksworkshop)을 클릭합니다.

    7. 컴퓨팅 탭을 클릭하면 이제 새로운 AWS Inferentia inf2.xlarge 컴퓨팅 노드가 있음을 확인할 수 있습니다.

    8. 노드 이름을 클릭하면 inf2.xlarge 컴퓨팅 노드와 관련된 용량 할당 및 Pod 세부 정보가 표시됩니다.

    [ Summary ]

    더보기

    이제 vLLM Pod를 구축했습니다. vLLM(모델 제공 및 추론)을 통해 Mistral-7B 모델과 상호 작용할 수 있도록 WebUI Pod를 배포하려면 다음 랩 섹션으로 계속 진행하세요.


    3.2 WebUI 채팅 애플리케이션을 배포하여 모델과 상호 작용

    3.2.1 추론 서비스 사용하는 방법

    더보기

    워크숍에서 배포할 vLLM 호스팅 Mistral-7B-Instruct 모델에서 제공하는 OpenAI 호환 엔드포인트를 사용하도록 설계된 "Open WebUI" 애플리케이션을 사용하여 추론 서비스에 연결할 수 있습니다. Open WebUI 애플리케이션을 사용하면 채팅 기반 인터페이스를 통해 LLM 모델과 상호 작용할 수 있습니다. Open WebUI 애플리케이션을 사용하려면 애플리케이션 컨테이너를 배포하고 제공된 WebUI URL에 연결한 다음 LLM 모델과 채팅을 시작하기만 하면 됩니다. WebUI 애플리케이션은 VLLM 호스팅 Mistral-7B-Instruct 모델과의 통신을 처리하여 원활한 사용자 경험을 제공합니다.

     

    3.2.2 Open WebUI Pod를 배포하고 부하를 분산

    더보기

    Step1. Load Balancer 배포

    아래 명령을 실행하여 Open WebUI 애플리케이션 Pod를 배포하면 이전 단계에서 배포한 vLLM Mistral 모델과 상호 작용할 수 있습니다. 이렇게 하면 챗봇 Open WebUI Chat 사용자 인터페이스를 제공하는 애플리케이션 로드 밸런서도 배포됩니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: open-webui-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: open-webui-server
      template:
        metadata:
          labels:
            app: open-webui-server
        spec:
          containers:
          - name: open-webui
            image: kopi/openwebui
            env:
            - name: WEBUI_AUTH
              value: "False"
            - name: OPENAI_API_KEY
              value: "xxx"
            - name: OPENAI_API_BASE_URL
              value: "http://vllm-mistral7b-service/v1"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: open-webui-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: external
        service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
        service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
    spec:
      selector:
        app: open-webui-server
      # type: LoadBalancer
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: open-webui-ingress
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
        alb.ingress.kubernetes.io/healthcheck-path: /
        alb.ingress.kubernetes.io/healthcheck-interval-seconds: '10'
        alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '9'
        alb.ingress.kubernetes.io/healthy-threshold-count: '2'
        alb.ingress.kubernetes.io/unhealthy-threshold-count: '10'
        alb.ingress.kubernetes.io/success-codes: '200-302'
        alb.ingress.kubernetes.io/load-balancer-name: open-webui-ingress
      labels:
        app: open-webui-ingress
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: open-webui-service
                port: 
                  number: 80
    kubectl apply -f open-webui.yaml

     

    Step2. Open WebUI Chat 인터페이스의 URL ADDRESS 확인

    kubectl get ing

     

     

     Step3. 웹 브라우저로 Open WebUI 채팅 클라이언트 인터페이스 열기 ( UI 배포까지 1~2분 소요 예정 )

     

    ☞ 위의 주소를 웹 브라우저에 붙여넣고 확인!!

     

     

    Step4. 채팅하기

    WebUI 인터페이스의 상단 메뉴 표시줄에 모델을 선택하는 데 사용되는 드롭다운이 표시됩니다. 드롭다운에서 Mistral-7B 모델을 선택하고 새로 배포된 제너레이티브 AI 채팅 애플리케이션으로 채팅을 시작합니다.

     

    Mistral-7B 모델이 표시되지 않으면 상단 드롭다운 선택 메뉴에서 모델을 볼 수 있을 때까지 WebUI 페이지를 새로 고칩니다. (이전 실습 모듈에서 vLLM Pod와 모델을 메모리에 로드하는 데 약 7-8분이 걸린다는 점을 기억하십시오.)

     

     [ 실제 사용 화면 ]

     


    4. Mistral-7B 데이터를 검사하고 생성된 데이터 자산을 공유 및 복제합니다.

    [ 모듈 개요 ]

    더보기

    이 모듈에서는 vLLM Pod에 로그인하고 퍼시스턴트 볼륨에 저장된 Mistral 모델 데이터 구조를 확인합니다. vLLM Pod에 로그인하면 FSx Lustre 파일 시스템에서 지원하는 퍼시스턴트 볼륨을 사용하여 S3 버킷에 저장된 모든 데이터를 보고 액세스하는 방법도 확인할 수 있습니다. 모델 또는 훈련 데이터(S3 버킷에 저장)를 공유하거나 Pod에서 생성된 자산을 다른 리전의 EKS 클러스터와 공유해야 하는 시나리오를 상상해 보십시오(예: DR 또는 다른 팀 중 하나의 분산 액세스). 따라서 이 실습 섹션에서는 퍼시스턴트 볼륨(FSx for Lustre 지원)의 EKS Pod에서 테스트 파일을 생성하고, 이 파일이 S3 버킷으로 자동으로 내보내지는 것을 확인하며, 구성할 S3 복제를 통해 해당 테스트 파일이 사용자를 위해 생성된 다른 대상 AWS 리전(us-east-2)의 S3 버킷에도 자동으로 복제되는 방법을 확인할 수 있습니다.

     

    [ 정보 ]

    많은 파드와 공유되는 하나의 퍼시스턴트 볼륨 클레임 - 많은 AI 모델 또는 방대한 양의 훈련 데이터 세트를 호스팅해야 하는 시나리오를 상상해 보세요. 이 데이터는 FSx for Lustre에서 지원하는 단일 PV(Persistent Volume) 및 PVC(Persistent Volume Claim)에 저장할 수 있습니다. 이렇게 하면 셀 수 없이 많은 파드에 연결된 많은 개별 로컬 스토리지 볼륨을 생성하는 대신 중앙 집중식 고성능 모델/데이터 캐시 위치를 확보하여 애플리케이션 파드에 서비스를 제공할 수 있으며, 로컬 볼륨에서 중복된 데이터의 비효율성을 제거하는 데 도움이 되며, 새 파드를 시작할 때 각 로컬 볼륨에 데이터를 복사하는 것과 관련된 대기 시간도 줄일 수 있다.

     

     


    4.1 S3 연결 FSx for Lustre 인스턴스에 대한 S3 교차 리전 복제 구성 

    4.1.1 Amazon S3 버킷 간에 S3 교차 리전 복제 구성

    더보기
    메모

    AWS 후원 워크숍을 위해 두 개의 Amazon S3 버킷을 생성했습니다. 첫 번째는 선택한 리전에 있으며, 이름이 fsx-lustre-bucket-2ndregion-xxxx us-east-2의 대상 Amazon S3 버킷입니다.

     

    Step1. Amazon S3 콘솔로 이동

     

    Step2. 해당 지역에서 생성된 아래와 같은 S3 버킷을 클릭합니다. (2ndregion이 있는 S3 버킷 이름을 클릭하지 마십시오).

     

     Step3. 관리 탭을 선택하고 복제 규칙까지 아래로 스크롤한 다음 복제 규칙 만들기를 선택합니다

     

    Step4. 화면 상단의 빨간색 팝업 상자에서 Enable Bucket Versioning(버킷 버전 관리 활성화)을 클릭한 다음 Rule name(규칙 이름)에서 나중에 규칙을 식별하는 데 도움이 되는 규칙 이름을 입력합니다. Status(상태)에서 Enabled(사용)가 기본적으로 선택되어 있는지 확인합니다

     

    Step5. 소스버킷에서 하나 이상의 필터를 사용하여 이 규칙의 범위 제한 선택한 다음, 필터링할 값으로 test/를 입력합니다.

     

     

    Step6. 대상(Destination)에서 S3 찾아보기(Browse S3)를 클릭하고, us-east-2에서 생성한 대상 S3 버킷(예: fsx-lustre-bucket-2ndregion-xxxx)을 선택한 다음 경로 선택(Choose path)을 클릭합니다.

     

    Step7. 빨간색 팝업 상자에서 Enable Bucket Versioning(버킷 버전 관리 활성화)을 클릭합니다.

     

    Step8. 이제 Amazon S3가 사용자를 대신하여 S3 버킷 간에 S3 객체를 복제할 수 있는 AWS Identity and Access Management(IAM) 역할을 설정합니다. 미리 생성된 기존 역할을 선택합니다(이름은 s3-cross-region-replication-role로 시작합니다. )

     

     

    Step9. 암호화의 경우 AWS KMS로 암호화된 객체 복제를 선택하고 "사용 가능한 AWS KMS 키"를 클릭한 다음 표시된 항목만 선택합니다.

     

    Step10. 다른 모든 기본 옵션을 유지하고 Save(저장)를 클릭하여 구성을 저장합니다

     

    Step11. 기존 개체를 복제할 수 있는 팝업이 표시되면 NO(아니요)를 선택하고 기존 개체를 복제하지 않음을 선택한 다음 Submit(제출)을 클릭합니다.

     

    Step12. S3 복제 규칙 페이지로 돌아가서 규칙이 성공적으로 생성되었는지 확인한다.

     

     


    [ 실행 결과 - 한 눈에 보기 ]

     

    [ Summary ]

    더보기

    이 섹션에서는 두 S3 버킷 간에 S3 교차 리전 복제 규칙을 성공적으로 생성했습니다. 다음 섹션에서는 파드 중 하나에 마운트된 퍼시스턴트 볼륨에 테스트 데이터를 생성하고, 생성된 데이터가 타겟 S3 버킷에 얼마나 원활하게 복사되는지 확인한다. Amazon S3 기본 복제 기능은 컨테이너화된 워크로드 배포를 위한 DR/BCP 계획의 일부가 되는 데 도움이 될 수 있습니다.


    4.2 Mistral -7B를 검사하고, 파드에서 테스트 파일을 생성하여 데이터 자동 내보내기 및 복제하기

    Step1. Pod에 로그인하고, 모델 데이터를 검사하여 복제할 테스트 파일을 생성한다.

    더보기

    ☞ Cloud9 터미널로 돌아가서 실행

    cd /home/ec2-user/environment/eks/FSxL

     

    이제 vLLM Pod에 로그인할 수 있으며, 먼저 다음 명령을 실행하여 Pod 이름을 가져와야 합니다.

    WSParticipantRole:~/environment/eks/genai $ cd /home/ec2-user/environment/eks/FSxL
    WSParticipantRole:~/environment/eks/FSxL $ kubectl get pods
    NAME                                            READY   STATUS    RESTARTS   AGE
    kube-ops-view-5d9d967b77-c7nk5                  1/1     Running   0          31h
    open-webui-deployment-5d7ff94bc9-w6rtl          1/1     Running   0          51m
    vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr   1/1     Running   0          61m
    WSParticipantRole:~/environment/eks/FSxL $

     

    출력에서 vllm으로 시작하는 환경에 표시된 이름을 복사합니다. (vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr)

     

    방금 복사한 값을 이용하여 vllm POD 에 접속합니다.

    kubectl exec -it <YOUR-vLLM-POD-NAME> -- bash
    WSParticipantRole:~/environment/eks/FSxL $ kubectl exec -it vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr -- bash
    bash: /home/ray/anaconda3/lib/libtinfo.so.6: no version information available (required by bash)
    (base) root@vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr:~#

     

    (base) root@vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr:~# df -h
    Filesystem                Size  Used Avail Use% Mounted on
    overlay                   100G   23G   78G  23% /
    tmpfs                      64M     0   64M   0% /dev
    tmpfs                     7.7G     0  7.7G   0% /sys/fs/cgroup
    10.0.42.72@tcp:/y4ztbb4v  1.2T   28G  1.1T   3% /work-dir
    /dev/nvme0n1p1            100G   23G   78G  23% /etc/hosts
    shm                        64M     0   64M   0% /dev/shm
    tmpfs                      15G   12K   15G   1% /run/secrets/kubernetes.io/serviceaccount
    tmpfs                     7.7G     0  7.7G   0% /proc/acpi
    tmpfs                     7.7G     0  7.7G   0% /sys/firmware

     

    work-dir은 Persistent Volume Claim의 마운트 위치입니다(FSx for Lustre 파일 시스템에서 지원).

     

    이 퍼시스턴트 볼륨에 저장된 내용을 검사할 수 있습니다.

    cd /work-dir/
    ls -ll

    Mistral-7B 모델이 여기에 저장되어 있는 것을 볼 수 있습니다. 모델 데이터 구조가 어떻게 생겼는지 살펴보겠습니다.

    cd Mistral-7B-Instruct-v0.2/
    ls -ll

     

    다음으로 퍼시스턴트 볼륨(FSx for lustre에서 지원)에 테스트 파일을 만듭니다. 여기에서 FSx for Lustre가 신규/변경된 파일을 Amazon S3로 자동 내보내는 기능과 S3 버킷에서 S3 버킷으로 복제를 볼 수 있으며, 여기서 vLLM Pod에서 생성한 파일은 us-east-2의 대상 S3 버킷으로 원활하게 복사됩니다. 그런 다음 해당 데이터를 기존 환경의 일부로 사용하거나 DR 시나리오를 위해 데이터를 보유할 수 있으며, Amazon EKS 클러스터, Pod 및 FSx Lustre 인스턴스를 가동하여 복제된 데이터를 자동화된 방식으로 사용할 수 있습니다.

     

    test라는 새 폴더 아래에 testfile이라는 테스트 파일을 생성하면 테스트 파일이이 FSx 인스턴스에 연결된 S3 버킷으로 내보내고, 이후에 S3 버킷에서 대상 S3 버킷 (us-east-2 지역)으로 테스트 파일의 S3 복제가 트리거됩니다.

    cd /work-dir
    mkdir test
    cd test
    cp /work-dir/Mistral-7B-Instruct-v0.2/README.md /work-dir/test/testfile
    ls -ll /work-dir/test

      

    Step2. S3 버킷으로 내보내고 리전 간에 복제된 데이터 확인

    더보기

    ☞  Amazon S3 콘솔로 이동

    ☞ 해당 지역(FSx 인스턴스에 연결됨) 에 있는 S3 버킷을 클릭  ( 2ndregion  버킷 클릭하지 마시요!! )

     

    거기에 테스트 폴더가 있습니다. 테스트 폴더를 클릭합니다. 이제 파드의 퍼시스턴트 볼륨에서 생성한 테스트 파일도 FSx for Lustre 파일 시스템에서 S3 버킷으로 자동으로 내보내진 것을 볼 수 있다.

     

    이제 다른 AWS 리전(us-east-2)에 있는 대상 S3 버킷을 확인하여 이 테스트 파일도 자동으로 복제되었는지 확인합니다.

    이제 창 맨 위에 있는 Buckets 하이퍼링크를 클릭합니다.

    이제 us-east-2에 있는 이름에 2ndregion이 있는 S3 버킷을 클릭합니다. test 폴더 및 testfile도 S3 복제에 의해 자동으로 복제되었음을 알 수 있습니다.

     

    [ Summary ]

    더보기

    이 섹션에서는 FSx for Lustre를 사용하여 Pod 내에서 생성된 데이터를 공유 및 복제하는 방법과 Amazon S3로 자동 가져오기/내보내기 기능을 관찰했습니다. S3 복제를 사용하여 S3 버킷 간에 생성된 데이터를 원활하게 복제하는 방법을 관찰했습니다. 이는 보조 리전(예: DR)에 기존 EKS 클러스터가 있을 수 있는 DR 시나리오에 대한 분산 데이터 요구 사항과 같은 시나리오에 유용하며, FSx for Lustre 인스턴스(S3 버킷에 연결됨)를 생성하고, 연결된 영구 볼륨(FSx 인스턴스 사용)을 생성하여, S3 버킷에 저장된 복제된 데이터를 활용할 수 있습니다. 그런 다음 애플리케이션 Pod를 스핀업하여 다른 AWS 리전에서 이 데이터를 원활하게 사용할 수 있습니다.

    ☞ 정보

    많은 AI 모델 또는 방대한 양의 훈련 데이터 세트를 호스팅해야 하는 시나리오를 상상해 보세요. 이 데이터를 FSx for Lustre에서 지원하는 단일 영구 볼륨(PV)에 저장할 수 있습니다. 이렇게 하면 중복 데이터가 있을 수 있는 각 파드에 연결된 많은 개별 로컬 스토리지 볼륨을 생성하는 대신 애플리케이션 파드에 서비스를 제공할 수 있는 중앙 집중식 고성능 모델/데이터 캐시 위치를 가질 수 있으며, 파드가 액세스할 수 있기 전에 각 로컬 볼륨에 데이터를 복사하는 것과 관련된 대기 시간도 가질 수 있다. 

     


    5. 데이터 계층 테스트를 위한 고유한 환경 만들기

    [ 모듈 개요 ]

    더보기

    이전 모듈에서는 기존 스토리지 인스턴스(관리자가 미리 생성)와 함께 정적 프로비저닝을 사용하여 EKS 클러스터에서 영구 볼륨 및 클레임을 생성하는 방법을 배웠습니다. 이 섹션에서는 파드를 배포할 자체 테스트 환경을 생성하고, 사용자가 동적 프로비저닝 기능을 사용하여 온디맨드 퍼시스턴트 볼륨(PV) 및 퍼시스턴트 볼륨 클레임을 배포하는 방법을 배우며, 이는 백엔드에 연결된 FSx Lustre 인스턴스를 자동으로 생성한다(관리자 사전 프로비저닝 필요 없음). 그런 다음 해당 PVC를 파드에 마운트하고 이 랩 섹션에서 몇 가지 테스트를 수행한다.

    5.1 Dynamic Provisioning을 사용하여 테스트를 위한 새 PV 및 FSx Lustre 인스턴스 배포

    더보기

    이전 모듈에서는 기존 스토리지 개체(관리자가 생성)와 함께 정적 프로비저닝을 사용하여 퍼시스턴트 볼륨 및 클레임을 생성하는 방법을 배웠습니다. 이 섹션에서는 사용자가 CSI 드라이버와 동적 프로비저닝 기능을 사용하여 온디맨드 퍼시스턴트 볼륨 및 클레임을 배포하고, 백엔드에 연결된 FSx Lustre 인스턴스도 생성하는 방법을 알아봅니다(관리자 사전 프로비저닝 필요 없음). StorageClass, PersistentVolume 및 PersistentVolumeClaims에 대한 정의를 생성하여 정적 프로비저닝과 동적 프로비저닝의 차이점을 강조하고, 이 랩 섹션에서는 이 프로비저닝을 몇 가지 테스트에 사용할 것입니다.


     Step1. Define StorageClass

    다음 단계에서는 아래 환경 변수를 사용하므로 설정할 수 있습니다. 아래 내용을 복사하여 Cloud9 터미널에 붙여넣습니다.

    VPC_ID=$(aws eks describe-cluster --name $CLUSTER_NAME --region $AWS_REGION --query "cluster.resourcesVpcConfig.vpcId" --output text)
    SUBNET_ID=$(aws eks describe-cluster --name $CLUSTER_NAME --region $AWS_REGION --query "cluster.resourcesVpcConfig.subnetIds[0]" --output text)
    SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=${VPC_ID} Name=group-name,Values="FSxLSecurityGroup01"  --query "SecurityGroups[*].GroupId" --output text)

     

     1. 입력 된 변수 확인

    WSParticipantRole:~/environment/eks/FSxL $ echo $SUBNET_ID
    subnet-01f63635c688252c3
    WSParticipantRole:~/environment/eks/FSxL $ echo $SECURITY_GROUP_ID
    sg-04cf50c1975542f36

     

    2. lab 명령어 동작을 위한 작업 디렉토리 변경

    cd /home/ec2-user/environment/eks/FSxL

     

    아래는 파일의 출력입니다. 이 파일에는 FSx for Lustre에서 PVC(Persistent Volume Claim)를 동적으로 프로비저닝하기 위해 CSI 드라이버와 함께 사용할 StorageClass 정의가 있습니다. 잠시 시간을 내어 표시된 매개 변수를 검사하면 CSI 드라이버에 의해 프로비저닝될 FSx for Lustre 인스턴스를 구성할 수 있습니다.fsxL-storage-class.yaml

     

    메모: 여기에 스토리지 용량 값 또는 accessModes가 없다는 것을 알고 계셨습니까? 실제로 후속 퍼시스턴트볼륨클레임(PersistentVolumeClaim) 요청에서 필요한 스토리지 용량과 퍼시스턴트 볼륨에 대한 PoD에 필요한 액세스 모드를 정의하게 됩니다.

    # fsxL-storage-class.yaml
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
        name: fsx-lustre-sc
    provisioner: fsx.csi.aws.com
    parameters:
      subnetId: SUBNET_ID
      securityGroupIds: SECURITY_GROUP_ID
      deploymentType: SCRATCH_2
      fileSystemTypeVersion: "2.15"
    mountOptions:
      - flock

     

    아래 명령을 실행하여 파일의 자리 표시자 값을 실제 환경 값으로 바꿉니다.

    fsxL-storage-class.yamlSUBNET_IDSECURITY_GROUP_ID  

    sed -i'' -e "s/SUBNET_ID/$SUBNET_ID/g" fsxL-storage-class.yaml
    sed -i'' -e "s/SECURITY_GROUP_ID/$SECURITY_GROUP_ID/g" fsxL-storage-class.yaml

     

     3. fsxL-storage-class.yaml 파일을 검사하여 대체된 값이 올바른지 확인한다.

    WSParticipantRole:~/environment/eks/FSxL $ cat fsxL-storage-class.yaml
    ---
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
        name: fsx-lustre-sc
    provisioner: fsx.csi.aws.com
    parameters:
      subnetId: subnet-01f63635c688252c3
      securityGroupIds: sg-04cf50c1975542f36
      deploymentType: SCRATCH_2
      fileSystemTypeVersion: "2.15"
    mountOptions:
      - flock

     

    ☞ 참고 :  fsxL-storage-class.yaml 파일 필드 값 이해

    subnetId— Amazon FSx for Lustre 파일 시스템을 생성해야 하는 서브넷 ID입니다. Amazon FSx for Lustre는 일부 가용 영역에서 지원되지 않습니다. 에서 Amazon FSx for Lustre 콘솔을 열어 사용하려는 서브넷이 지원되는 가용 영역에 있는지 확인합니다. 서브넷은 노드를 포함하거나 다른 서브넷 또는 VPC일 수 있습니다. 지정한 서브넷이 노드가 있는 서브넷과 동일하지 않은 경우 VPC가 연결되어야 하며 보안 그룹에서 필요한 포트가 열려 있는지 확인해야 합니다.https://console.aws.amazon.com/fsx/
    
    securityGroupIds – 노드의 보안 그룹 ID입니다.
    
    s3ImportPath – 영구 볼륨으로 데이터를 복사하려는 Amazon Simple Storage Service 데이터 리포지토리입니다.
    
    s3ExportPath – 새 파일 또는 수정된 파일을 내보낼 Amazon S3 데이터 리포지토리입니다.
    
    deploymentType – 파일 시스템 배포 유형입니다. 유효한 값은 SCRATCH_1, SCRATCH_2 및 PERSISTENT_1입니다. 배포 유형에 대한 자세한 내용은 Amazon FSx for Lustre 파일 시스템 생성을 참조하세요.
    
    autoImportPolicy - 연결된 데이터 저장소의 변경 사항으로 파일 시스템이 자동으로 업데이트되는 방법을 결정하는 FSx가 따르는 정책입니다. 허용되는 정책 목록은 공식 FSx for Lustre 설명서 
    
    perUnitStorageThroughput - 배포 유형 PERSISTENT_1의 경우 고객은 스토리지 처리량을 지정할 수 있습니다. 기본값: "200". 여기서 고객은 "200" 또는 "100" 등과 같은 문자열로 지정해야 합니다.

     

    ☞  메모:

    s3ImportPath 및 s3ExportPath에 대한 Amazon S3 버킷은 동일해야 하며, 그렇지 않으면 드라이버가 Amazon FSx for Lustre 파일 시스템을 생성할 수 없습니다. s3ImportPath는 단독으로 사용할 수 있습니다. s3://ml-training-data-000/FSxLustre20190308T012310Z와 같은 임의 경로가 자동으로 생성됩니다. S3ImportPath에 대한 값을 지정하지 않으면 s3ExportPath를 사용할 수 없습니다.


     

     Step2. Storage Class 생성

    아래 명령을 복사하고 실행하여 1단계에서 정의된 설정을 적용합니다. 그러면 storageclass가 생성됩니다.

    kubectl apply -f fsxL-storage-class.yaml
    
    ##
    WSParticipantRole:~/environment/eks/FSxL $ cat fsxL-storage-class.yaml
    ---
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
        name: fsx-lustre-sc
    provisioner: fsx.csi.aws.com
    parameters:
      subnetId: subnet-01f63635c688252c3
      securityGroupIds: sg-04cf50c1975542f36
      deploymentType: SCRATCH_2
      fileSystemTypeVersion: "2.15"
    mountOptions:
      - flock

     

      스토리지 클래스 생성여부 확인

    WSParticipantRole:~/environment/eks/FSxL $ kubectl get sc
    NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
    fsx-lustre-sc   fsx.csi.aws.com         Delete          Immediate              false                  63s
    gp2             kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  32h
    gp3 (default)   ebs.csi.aws.com         Delete          WaitForFirstConsumer   true                   32h

     


     Step3. PVC(Persistent Volume Claim) 생성

    이전에 정의한 PV에 대한 영구 볼륨 클레임을 생성합니다.

     

    1. yaml 내용 확인

    WSParticipantRole:~/environment/eks/FSxL $ cat fsxL-dynamic-claim.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: fsx-lustre-dynamic-claim
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: fsx-lustre-sc
      resources:
        requests:
          storage: 1200Gi

     

     2. PVC 를 생성

    WSParticipantRole:~/environment/eks/FSxL $ kubectl apply -f fsxL-dynamic-claim.yaml
    persistentvolumeclaim/fsx-lustre-dynamic-claim created

     

    3. PVC 상태 확인

    WSParticipantRole:~/environment/eks/FSxL $ kubectl describe pvc/fsx-lustre-dynamic-claim
    Name:          fsx-lustre-dynamic-claim
    Namespace:     default
    StorageClass:  fsx-lustre-sc
    Status:        Pending
    Volume:        
    Labels:        <none>
    Annotations:   volume.beta.kubernetes.io/storage-provisioner: fsx.csi.aws.com
                   volume.kubernetes.io/storage-provisioner: fsx.csi.aws.com
    Finalizers:    [kubernetes.io/pvc-protection]
    Capacity:      
    Access Modes:  
    VolumeMode:    Filesystem
    Used By:       <none>
    Events:
      Type    Reason                Age               From                                                                                      Message
      ----    ------                ----              ----                                                                                      -------
      Normal  Provisioning          12s               fsx.csi.aws.com_fsx-csi-controller-6f4c577bd4-zvpc6_2522e65a-c52e-4ace-a173-ad265014a2dc  External provisioner is provisioning volume for claim "default/fsx-lustre-dynamic-claim"
      Normal  ExternalProvisioning  5s (x3 over 12s)  persistentvolume-controller                                                               Waiting for a volume to be created either by the external provisioner 'fsx.csi.aws.com' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.

     

     4. PVC 요청상태 확인

     - "fsx-lustre-dynamic-claim"에 대해 방금 요청한 PVC 클레임이 보류 중인 상태이며 이전에 생성한 fsx-lustre-sc StorageClass에 바인딩된 것을 볼 수 있습니다.

    WSParticipantRole:~/environment/eks/FSxL $ kubectl get pvc
    NAME                       STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS    VOLUMEATTRIBUTESCLASS   AGE
    fsx-lustre-claim           Bound     fsx-pv   1200Gi     RWX                            <unset>                 124m
    fsx-lustre-dynamic-claim   Pending                                      fsx-lustre-sc   <unset>                 89s

     Step4. FSx Lustre 인스턴스가 프로비저닝 되었고, PVC가 바인딩 되었는지 확인

    약 15분 기다린 후 아래 명령어 실행하여 PVC 상태 확인 - "Bound" 인지 확인한다.

    WSParticipantRole:~/environment/eks/FSxL $ kubectl get pvc
    NAME                       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    VOLUMEATTRIBUTESCLASS   AGE
    fsx-lustre-claim           Bound    fsx-pv                                     1200Gi     RWX                            <unset>                 129m
    fsx-lustre-dynamic-claim   Bound    pvc-3e347b1d-ad09-4b03-847b-f59d6327f757   1200Gi     RWX            fsx-lustre-sc   <unset>                 6m25s

     

    다음은 FSx 인스턴스와 세부 정보를 보여주는 Amazon FSx 콘솔의 이미지입니다. 사용할 준비가 되면 Status(상태)가 Creating (생성)에서 Available(사용 가능)로 변경됩니다.

     

    [ 생성 확인 ]

    [ Summary ]

    더보기

    이 섹션에서는 Dynamic Provisioning을 사용하여 Amazon S3 버킷에 연결된 새 PV 및 관련 FSx for Lustre 파일을 성공적으로 생성했습니다. 퍼시스턴트 볼륨에 FSx for Lustre를 사용하기 위해 StoragClass 정의를 생성하고, 파드가 생성된 퍼시스턴트 볼륨에 액세스할 수 있도록 퍼시스턴트 볼륨 클레임을 생성했다. 다음 실습 섹션에서는 FSx Lustre 인스턴스의 성능 테스트를 위해 배포할 새 Pod와 함께 이 PV를 사용합니다.


    5.2 성능 테스트

    이 섹션에서는 CSI 드라이버에 의해 프로비저닝된 FSx for Lustre 파일 시스템의 스토리지 성능, IOPS, 처리량 및 지연 시간과 관련된 중요한 파라미터를 살펴봅니다.
     
    Step1. FSx for Lustre에서 yaml 파일 및 10GB 스토리지 사용하여 테스트 Pod 프로비저닝

    더보기

    ☞ 작업디렉토리 이동

    cd /home/ec2-user/environment/eks/FSxL

     

    ☞ 가용영역 확인 후, 기록해 두자!!

    WSParticipantRole:~/environment/eks/FSxL $ aws ec2 describe-subnets --subnet-id $SUBNET_ID --region $AWS_REGION | jq .Subnets[0].AvailabilityZone
    "us-west-2b"

     

    ☞ Pod 배포 구성 편집 및 업데이트

    • "i"를 눌러 편집 모드로 들어갑니다.
    • 아래 스크린샷과 같이 nodeSelector  topology.kubernetes.io/zone 로 시작하는 마지막 두 줄을 제거하여 주석 처리를 제거합니다.#
    • 아래 스크린샷과 같이 이전 단계에서 기록한 가용성 영역으로 바꿉니다.us-east-2c
    • ESC를 누르고 입력한 다음 Enter 키를 누릅니다.:wq
    vi pod_performance.yaml
    ##=======<<수정 전>>==========================##
    kind: Pod
    apiVersion: v1
    metadata:
      name: fsxl-performance
    spec:
      containers:
        - name: fsxl-performance
          image: nginx
          ports:
            - containerPort: 80
              name: "http-server"
          volumeMounts:
            - name: persistent-storage
              mountPath: /data
      volumes:
      - name: persistent-storage
        persistentVolumeClaim:
          claimName: fsx-lustre-dynamic-claim
    #  nodeSelector:
    #    topology.kubernetes.io/zone: us-east-2c
    ##======<< 수정 후 >>===========================##
    kind: Pod
    apiVersion: v1
    metadata:
      name: fsxl-performance
    spec:
      containers:
        - name: fsxl-performance
          image: nginx
          ports:
            - containerPort: 80
              name: "http-server"
          volumeMounts:
            - name: persistent-storage
              mountPath: /data
      volumes:
      - name: persistent-storage
        persistentVolumeClaim:
          claimName: fsx-lustre-dynamic-claim
      nodeSelector:
        topology.kubernetes.io/zone: us-west-2b

     

    ☞ 프로비저닝 및 결과 확인

    • 아래 명령을 실행하여 Pod의 상태를 확인합니다. 약 1이 소요됩니다. 분이 지나면 파드의 상태가 RUNNING으로 변경된다.
    WSParticipantRole:~/environment/eks/FSxL $ kubectl apply -f pod_performance.yaml
    pod/fsxl-performance created
    WSParticipantRole:~/environment/eks/FSxL $ kubectl get pods
    NAME                                            READY   STATUS    RESTARTS   AGE
    fsxl-performance                                0/1     Pending   0          18s
    kube-ops-view-5d9d967b77-c7nk5                  1/1     Running   0          32h
    open-webui-deployment-5d7ff94bc9-w6rtl          1/1     Running   0          102m
    vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr   1/1     Running   0          113m
    WSParticipantRole:~/environment/eks/FSxL $ kubectl get pods
    NAME                                            READY   STATUS    RESTARTS   AGE
    fsxl-performance                                1/1     Running   0          4m21s
    kube-ops-view-5d9d967b77-c7nk5                  1/1     Running   0          32h
    open-webui-deployment-5d7ff94bc9-w6rtl          1/1     Running   0          106m
    vllm-mistral-inf2-deployment-7d886c8cc8-xlsfr   1/1     Running   0          117m

     

     

    Step2. 컨테이너에 로그인 하고 FIO 및 IOping 테스트 수행

    더보기

    ☞ FIO 및 IOPing 툴을 설치하여 부하테스트 수행 및 처리량을 관찰합니다.

    1. 컨테이너 로그인

    WSParticipantRole:~/environment/eks/FSxL $ kubectl exec -it fsxl-performance  -- bash
    root@fsxl-performance:/#

     

    2. FIO 및 IOPing 설치

    apt-get update
    apt-get install fio ioping -y

     

    3. IOping 명령어 수행하여 FSx for Lustre 파일 시스템 대기 시간 테스트 한다.

    • 일반적으로 0.5ms(500us) <인 평균 지연 시간 수치를 기록해 두며, 이는 FSx for Lustre 파일 시스템이 제공할 수 있는 짧은 지연 시간과 높은 성능을 강조합니다.
    root@fsxl-performance:/# ioping -c 20 .
    4 KiB <<< . (overlay overlay 20.0 GiB): request=1 time=343.8 us (warmup)
    4 KiB <<< . (overlay overlay 20.0 GiB): request=2 time=803.1 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=3 time=584.5 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=4 time=633.4 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=5 time=780.0 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=6 time=692.8 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=7 time=804.0 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=8 time=794.4 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=9 time=537.5 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=10 time=617.1 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=11 time=737.4 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=12 time=517.0 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=13 time=770.2 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=14 time=595.9 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=15 time=940.4 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=16 time=627.4 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=17 time=684.5 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=18 time=603.1 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=19 time=510.3 us
    4 KiB <<< . (overlay overlay 20.0 GiB): request=20 time=702.1 us
    
    --- . (overlay overlay 20.0 GiB) ioping statistics ---
    19 requests completed in 12.9 ms, 76 KiB read, 1.47 k iops, 5.74 MiB/s
    generated 20 requests in 19.0 s, 80 KiB, 1 iops, 4.21 KiB/s
    min/avg/max/mdev = 510.3 us / 680.8 us / 940.4 us / 112.4 us

     

    4. 아래 지침과 FIO 명령어 실행하여 부하테스트 수행하고 처리량 값을 기록해 둡니다.

    root@fsxl-performance:/# mkdir -p /data/performance
    root@fsxl-performance:/# cd /data/performance
    root@fsxl-performance:/data/performance# fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=fiotest --filename=testfio8gb --bs=1MB --iodepth=64 --size=8G --readwrite=randrw --rwmixread=50 --numjobs=8 --group_reporting --runtime=10
    fiotest: (g=0): rw=randrw, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=libaio, iodepth=64
    ...
    fio-3.33
    Starting 8 processes
    fiotest: Laying out IO file (1 file / 8192MiB)
    ^Cbs: 8 (f=8): [m(8)][66.7%][r=179MiB/s,w=146MiB/s][r=179,w=146 IOPS][eta 00m:04s]
    fio: terminating on signal 2
    
    fiotest: (groupid=0, jobs=8): err= 0: pid=724: Fri Apr 18 10:12:17 2025
      read: IOPS=171, BW=171MiB/s (180MB/s)(1345MiB/7848msec)
       bw (  KiB/s): min=89158, max=319191, per=100.00%, avg=190977.15, stdev=9197.56, samples=91
       iops        : min=   87, max=  311, avg=186.14, stdev= 8.97, samples=91
      write: IOPS=174, BW=174MiB/s (183MB/s)(1368MiB/7848msec); 0 zone resets
       bw (  KiB/s): min=77394, max=357050, per=100.00%, avg=184370.11, stdev=10958.74, samples=92
       iops        : min=   74, max=  348, avg=179.63, stdev=10.70, samples=92
      cpu          : usr=0.03%, sys=3.02%, ctx=4232, majf=0, minf=53
      IO depths    : 1=0.3%, 2=0.6%, 4=1.2%, 8=2.4%, 16=4.7%, 32=9.4%, >=64=81.4%
         submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
         complete  : 0=0.0%, 4=99.6%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.4%, >=64=0.0%
         issued rwts: total=1345,1368,0,0 short=0,0,0,0 dropped=0,0,0,0
         latency   : target=0, window=0, percentile=100.00%, depth=64
    
    Run status group 0 (all jobs):
       READ: bw=171MiB/s (180MB/s), 171MiB/s-171MiB/s (180MB/s-180MB/s), io=1345MiB (1410MB), run=7848-7848msec
      WRITE: bw=174MiB/s (183MB/s), 174MiB/s-174MiB/s (183MB/s-183MB/s), io=1368MiB (1434MB), run=7848-7848msec

     

    5. POD 를 종료합니다.

    exit

      

    ☞  성능 요약

    워크로드가 FSx for Lustre 파일 시스템에서 구동할 수 있는 특정 처리량 및 IOPS는 처리량 용량, 파일 시스템의 스토리지 용량 구성 및 워크로드의 특성에 따라 다릅니다. Amazon FSx for Lustre 성능에 대한 자세한 내용은 이 링크를 참조하십시오. Amazon FSx for Lustre 성능 차트 

     

    [ Summary ]

    더보기

    FIO 및 IOping 도구를 사용하여 Amazon FSx for Lustre 파일 시스템의 성능 테스트에 대한 이 섹션을 성공적으로 완료했습니다. FSx for Lustre에서 높은 처리량과 밀리초 미만의 지연 시간으로 로드를 실행하는 EKS 포드에서 다양한 성능 지표를 관찰했습니다.


    [ 마무리 ]

    이번에는 AWS 워크샵을 통해 AWS 의 Lustre 에서 제공하는 FSx 기반의 ML 모델과  파일시스템의 DR 복제 구성 및 성능테스트를 경험해 볼 수 있었다. 최근 다양한 버전의 ML 툴이 제공되고 있고, 각 툴마다 기반하는 인프라의 특성도 있어 흐름을 파악하기에 좋은 실습이었던 것 같다. 개인적으로 고비용의 GPU 기반 인프라 환경을 만들어보고 경험해 보기가 상당히 부담스러웠는데, 해당 워크샵을 통해 필요한 기술요소들을 테스트 할 수 있는 환경이 주어져서 매우 유익했던 것 같다.