데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      HPC를 여행하는 히치하이커를 위한 안내서 Part 3 - 8단계로 완성하는 클러스터

      alankim 26.05.20
      2,027 4 1
      DEVOTEE 요약
      본 블로그는 온프레미스 HPC 클러스터를 처음부터 구축하는 단계별 과정을 안내합니다. 하드웨어부터 OS 설정, GPU 스택, 공유 스토리지, 스케줄러에 이르기까지, 각 단계의 기술적 의존성을 따르는 순서가 클러스터의 안정성과 성능에 핵심임을 강조합니다. 이 정공법을 통해 분산 학습에 최적화된 클러스터를 효율적으로 구축하고 문제 해결 능력을 키울 수 있도록 돕습니다.
      DEVOTEE 추천 블로그

      들어가며

      지난 글에서 Slurm 스케줄러의 내부 구조와 실전 활용을 다루며, 마지막에 이렇게 말씀드렸습니다.

      "안정적인 클러스터는 Slurm 설정만으로 완성되지 않습니다. 네트워크, 스토리지, 모니터링, 사용자 정책 등 여러 퍼즐 조각이 맞물려야 합니다."

      이번 글은 바로 그 퍼즐 조각을, 온프레미스 환경에서 어떤 순서로 어떻게 맞춰야 하는지에 관한 이야기입니다.

      요즘은 클라우드의 시대입니다. AWS나 Azure의 관리형 HPC 서비스를 사용하면, 정말로 30분 만에 GPU 클러스터를 띄울 수도 있죠.

      그런데 막상 학습을 돌려보면 여러 문제와 질문들이 줄지어 등장합니다.

      “분산 학습 코드가 실행이 안되요!”, "GPU 활용률이 왜 이 모양이지?", "학습 상황을 좀 더 자세하게 모니터링할 순 없을까?"

      클라우드의 관리형 서비스는 손쉽게 HPC 클러스터를 띄워주지만, 성능을 최적화하고 장애를 풀어내는 일은 결국 사용자의 몫입니다.

      베어메탈에 직접 클러스터를 구성하고 튜닝한 경험이 있어야 클라우드 서비스의 옵션 하나하나가 무엇을 대신해 주고 있는지 보이거든요.

      그래서 이번 글에서는 정공법으로, 온프레미스 환경에서 HPC 클러스터를 처음부터 끝까지 쌓아 올리는 흐름을 따라가 보려고 합니다.

      HPC 클러스터는 하드웨어 사양 결정부터 OS, 인증, 스토리지, 스케줄러, 모니터링까지 수많은 컴포넌트가 정확한 순서와 일관된 정책으로 맞물려야 비로소 동작합니다.

      자, 그럼 본격적으로 온프레미스 HPC 클러스터를 어떻게 만들어야 하는지 같이 살펴봅시다.


      이 글은 다음과 같은 주제를 다룹니다.

      • 온프레미스 HPC 클러스터의 단계별 구축 흐름과 단계 간 의존성

      • 각 단계에서 분산 학습 환경이라면 특히 신경 써야 할 포인트

      • 단계별로 흔히 마주치는 함정과 운영 팁

      • 자동화의 진짜 가치와 도구 선택

      사전 안내

      본문에서 구현 사례로 EasyHPC의 예시를 다루고 있습니다.

      EasyHPC는 제가 개인 프로젝트로 진행하고 있는 Ansible 기반의 Slurm 클러스터 자동화 도구로, 이 글의 원리들이 코드로 어떻게 구현되는지 보여주는 사례입니다.

      https://github.com/superdom/easyhpc

      1. 구축 단계 한눈에 보기

      HPC 클러스터는 하드웨어, OS와 시스템 구성, 스케줄러, 모니터링, 사용자 관리 같은 여러 요소가 맞물려 동작합니다.

      한 요소의 결정이 다른 요소의 운영 방식을 좌우하는 데다, 한번 구성하고 나면 바꾸기가 쉽지 않죠.

      그래서 어떤 순서로 무엇을 쌓을지 를 처음부터 잘 짚고 가는 게 중요합니다.

      이 글에서 설명할 구축 단계는 다음과 같습니다.


      [ 그림 1. HPC 구축 단계 ]


      이 순서는 어떤 도구가 정한 규칙이 아닙니다. 앞 단계가 갖춰지지 않으면 다음 단계가 동작하지 않는, 기술적 의존성이 만들어낸 자연스러운 흐름입니다.

      EasyHPC 같은 자동화 프로젝트들도 본질적으로 동일하게 따릅니다.

      비유하자면 주택 건축과 비슷합니다. 땅을 다지지 않고 골조를 올릴 수 없고, 배관이 들어오기 전에 마감재를 붙이면 처음부터 다시 해야 하죠.

      HPC 클러스터 구축도 똑같아서, 이 의존성을 무시하면 어디서부터 손대야 할지 알 수 없는 디버깅 지옥이 시작됩니다.

      2. Phase 0 — 하드웨어 계획

      분산 학습용 클러스터의 하드웨어 계획에서 신경 써야 할 핵심을 한 줄씩 정리하면 다음과 같습니다.

      • Compute: GPU만 보지 말고 CPU·메모리·로컬 디스크의 균형을 함께 봐야 합니다. 주변 자원이 받쳐 주지 못하면 비싼 GPU가 데이터를 기다리며 놀게 됩니다.

      • Network: 분산 학습에서 노드 간 통신 속도는 GPU 만큼 중요합니다. 토폴로지와 대역폭 설계가 학습 성능 전체를 좌우합니다.

      • Storage: 노드 수가 늘어나면 단순한 공유 스토리지 한 층으로는 데이터 I/O 병목이 옵니다. 규모와 워크로드에 맞는 스토리지 시스템 선정이 핵심입니다.

      원래는 하드웨어 계획도 본문에서 다루려 했으나 분량이 많아 질 것 같아서, 기회가 된다면 별도의 포스팅으로 분리하려고 합니다.

      이번 글에서는 각 구성 요소가 분산 학습 성능에 어떻게 직결되는가 정도만 짚고 다음 단계로 이어가겠습니다.

      3. Phase 1 — OS와 시스템 설정

      발주한 하드웨어가 들어와서 준비 완료된 상태라면 이제 본격적인 클러스터 구성 작업이 시작됩니다.


      3.1 OS 선택

      가장 먼저 결정할 것은 노드에 어떤 OS를 설치할지입니다. 다음과 같은 요소를 고려해야 합니다.

      기준

      설명

      NVIDIA 드라이버/CUDA 지원

      GPU 클러스터의 출발점. 공식 지원 매트릭스에 들어 있어야 함

      장기 지원(LTS) 기간

      한 번 설치한 OS를 장기간 운영하는 게 보통이라 LTS는 사실상 필수

      HPC 패키지 생태계

      Slurm, PMIx, Lustre 클라이언트 등이 패키지로 잘 제공되는가

      사내 운영 친숙도

      이미 운영 중인 다른 시스템과 같은 계열인지

      업계에서 흔히 선택되는 후보는 다음과 같습니다.

      배포판

      특징

      Ubuntu LTS (22.04 / 24.04)

      AI 생태계에서 가장 많이 사용, NVIDIA 자료와 커뮤니티 가이드 풍부

      RHEL 9

      엔터프라이즈 표준, 유료 지원, 대기업·금융권에서 선호

      Rocky Linux 9

      RHEL 호환, 무료. CentOS의 후계로 가장 많이 채택됨

      SUSE Linux Enterprise (SLES)

      일부 슈퍼컴퓨팅 사이트 표준. 국내에서는 흔치 않음

      쉽게 말하면, AI 모델 학습이 주된 목적이면 Ubuntu LTS, 회사 표준이 RHEL 계열이면 RHEL이나 Rocky 가 무난합니다.

      두 계열은 패키지 매니저(apt vs dnf`)와 일부 경로가 다를 뿐, HPC 컴포넌트 운영 면에서 큰 차이는 없습니다.

      실무 Tip

      한 클러스터 안에서 OS 배포판을 섞지 마세요. Ubuntu와 RHEL이 같은 클러스터에 공존하면 NVIDIA 드라이버 패키지명이 다르고, systemd 유닛 경로가 다르고, 라이브러리 위치가 다릅니다.

      자동화 코드의 분기가 두 배로 늘고, 디버깅도 두 배로 어려워집니다. 모든 노드는 같은 배포판, 같은 메이저 버전을 원칙으로 가시기를 권장드립니다.

      OS 설치가 끝났다면, 이제 모든 노드에 다음 다섯 가지를 맞추는 기초 작업을 해줘야 합니다.

      1. 인증 키 — Slurm 데몬이 서로 RPC를 주고받을 때 인증용

      2. 시간 동기화 — 노드 간 1초의 어긋남도 허용되지 않음

      3. 사용자/그룹의 UID/GID — 공유 스토리지에서 파일 소유권의 기준

      4. 시스템 한도(ulimit) — 학습 프로세스가 파일 디스크립터, 메모리락 등에 막히지 않도록

      5. 커널 파라미터 — 네트워크 버퍼, 가상 메모리 정책 등

      이 다섯 가지가 어긋나면 그 위에 쌓는 모든 게 흔들립니다. 비유하자면 건물의 기초 콘크리트 입니다. 한 번 굳고 나면 위에서 보이지 않지만, 어긋나면 건물 전체가 기울어요.

      이제 하나씩 살펴보겠습니다.


      3.2 Munge

      Slurm 환경에서 노드 간 인증은 보통 Munge가 담당합니다.

      Munge는 HMAC 기반의 공유 키 인증 방식인데, 모든 노드가 정확히 같은 키 파일을 공유합니다.

      전형적인 작업 설정은 다음과 같습니다.

      # 1 컨트롤러에서 키 생성
      $ /usr/sbin/create-munge-key -f
      
      # 2 모든 노드로 안전하게 복사 (퍼미션 0400, owner=munge)
      $ scp /etc/munge/munge.key node:/etc/munge/munge.key
      $ ssh node "chown munge:munge /etc/munge/munge.key && chmod 0400 /etc/munge/munge.key"
      
      # 3 모든 노드에서 Munge 데몬 시작
      $ systemctl enable --now munge


      3.3 시간 동기화

      NTP 또는 chrony로 모든 노드의 시간을 같은 소스(보통 사내 NTP 서버 또는 외부 pool.ntp.org)에 맞춥니다.

      시간이 어긋나면 다음과 같은 일이 벌어집니다.

      • Munge 인증 거부 : 노드 간 통신 자체가 막혀, 노드가 DOWN 상태로 빠집니다.

      • TLS 인증서 검증이 실패할 수 있음 : NotBefore / NotAfter 클레임이 현재 시간 기준으로 판단되기 때문이죠

      • Job accounting 데이터에 비정상 값 : 시작·종료 시각이 음수가 되거나 미래 시점으로 기록될 수 있습니다

      • 로그를 시계열로 정렬할 수 없음 : 디버깅이 매우 어려워집니다

      쉽게 말하면, 시계가 어긋난 클러스터는 인증 자체가 무너지거나, 동작하더라도 디버깅이 불가능해집니다. 그래서 Phase 1에서 가장 먼저 잡습니다.


      3.4 UID/GID 일관성

      NFS를 비롯한 거의 모든 네트워크 파일시스템은 파일 소유권을 이름이 아닌 숫자(UID/GID)로 판단합니다.

      A 노드에서 slurm 사용자의 UID가 1001이고 B 노드에서는 1002라면, B 노드 입장에서 그 파일은 다른 사람의 파일이 되어 버립니다.

      따라서 클러스터의 시스템 사용자(slurm, munge 등)는 모든 노드에서 동일한 UID/GID로 고정 해야 합니다.

      실무 Tip

      패키지 매니저로 Slurm을 설치하면 사용자 생성이 OS 임의의 빈 UID로 됩니다. 노드 A는 999, 노드 B는 998이 되는 식이죠.

      이 문제을 피하는 표준 패턴은 패키지 설치 전에 명시적인 UID/GID로 사용자를 생성 하는 것입니다. 자동화 도구라면 이 규칙을 코드에 박아둡니다.

      예를 들어 EasyHPC는 munge=10010, slurm=10011 처럼 변수에 못 박아놓고 모든 노드에 똑같이 만든 다음 패키지를 설치합니다.

      OS 패키지 매니저가 이미 만들어진 사용자를 보면 새로 만들지 않으니까요.

      운영 중인 클러스터의 UID를 사후에 바꾸는 건 매우 까다롭습니다. 데몬이 실행 중이고 공유 스토리지에 그 UID로 만들어진 파일들이 산더미처럼 쌓여 있기 때문이죠.


      3.5 시스템 한도와 OS 튜닝

      HPC 환경의 분산 학습 워크로드는 일반 서버 워크로드와 패턴이 다릅니다.

      한 노드에서 수백 GB의 메모리를 관리하고, 수천 개의 파일 디스크립터를 동시에 열고, 초당 수십 GB 규모의 네트워크 트래픽을 처리하는 일이 흔하죠.

      이런 환경에서는 애플리케이션 자체뿐 아니라 OS 레벨의 제약도 성능과 안정성에 직접 영향을 줍니다.

      특히 파일 디스크립터 수, 락드 메모리, 프로세스 수, NUMA locality, 네트워크 버퍼 같은 요소들은 일반 서버보다 훨씬 민감하게 작동합니다.

      그래서 HPC 환경에서는 단순히 애플리케이션만 최적화하는 것이 아니라, OS 레벨의 운영 정책과 시스템 한도를 함께 조정해야 합니다.

      예를 들면 다음과 같은 영역을 들 수 있습니다.

      영역

      대표 항목

      왜 살펴보는가

      사용자 자원 한도

      nofile, memlock, nproc, stack

      학습 프로세스가 파일 디스크립터, 메모리 락, 프로세스/스레드 수 제한에 걸리지 않도록

      메모리 정책

      vm.swappiness, vm.overcommit_memory, transparent hugepage

      메모리 할당 정책과 huge page 처리 방식이 학습 안정성과 지연 특성에 영향을 줄 수 있음

      네트워크 버퍼

      net.core.rmem_max, net.ipv4.tcp_*

      TCP/Ethernet 기반 고속 네트워크 환경에서 버퍼 크기와 처리량을 조정하기 위해

      NUMA / IRQ

      NUMA 바인딩, IRQ affinity

      GPU·NIC와 가까운 CPU/메모리에 워크로드를 붙여 지연과 NUMA penalty를 줄이기 위해

      GPU 관련 정책

      persistence mode, MIG 설정, ECC 정책

      GPU 초기화 지연, 자원 분할 정책, 운영 안정성 등에 영향을 주기 때문

      이 영역 하나하나만으로도 별도의 글이 필요할 정도로 깊은 주제입니다.

      여기서 소개한 것은 대표적인 예시일 뿐이며, 실제 운영에서는 GPU 세대, 네트워크(RoCE/InfiniBand), 스토리지 구조, 학습 프레임워크등에 따라 조정 포인트가 달라집니다.

      지면상 자세히 다루지는 못하지만, 운영 환경에 맞는 권장 설정과 벤치마크 자료를 꼭 함께 살펴보시기를 권장드립니다.

      4. Phase 2 — GPU와 컨테이너 런타임

      OS와 시스템 설정이 끝났다면, 이제 GPU 노드에 GPU 관련 S/W 스택을 올립니다.


      4.1 컴포넌트 구성

      분산 학습 환경의 GPU 노드는 보통 다음을 함께 설치합니다.

      계층

      컴포넌트

      역할

      커널

      NVIDIA Driver, NVSwitch FM, peermem

      GPU 디바이스, GPU 간 메모리 직접 접근

      시스템 라이브러리

      CUDA, cuDNN, NCCL

      연산 및 통신 라이브러리

      컨테이너 런타임

      Docker, Enroot

      컨테이너 실행

      컨테이너-GPU 브릿지

      NVIDIA Container Toolkit

      컨테이너에 GPU 노출


      4.2 드라이버 버전 고정의 중요성

      여기서 가장 큰 함정은 드라이버 버전을 "최신"으로 두는 것입니다.

      신규 노드를 합류시킬 때마다 그날의 최신 드라이버가 깔리면, 노드별로 미묘하게 다른 환경이 만들어집니다.

      그러면 NCCL이 갑자기 느려지거나, 특정 노드만 학습이 느려지거나 실패하는 증상이 생깁니다. 디버깅이 정말 어렵죠.

      이런 함정을 피하는 표준 패턴은 다음과 같습니다.

      • 드라이버 버전을 명시적으로 하나로 고정

      • 클러스터 전체에 같은 버전을 배포

      • 검증된 다음에만 일괄 업그레이드

      자동화 코드라면 다음과 같이 변수로 박아두는 게 일반적입니다.

      # 사례 - EasyHPC의 GPU driver 변수 정의
      nvidia_driver_strategy: "specific"
      nvidia_driver_version: "580.126.09"
      nvidia_driver_allow_downgrade: true

      여기서 핵심은 정확한 버전 숫자가 아니라 사내에서 검증된 하나의 버전으로 고정한다 는 원칙입니다.

      어떤 버전을 고를지보다, 고정된 버전을 모든 노드에 일관되게 적용한다 는 점이 더 중요합니다.


      4.3 왜 스케줄러보다 먼저 설치해야 하는가?

      이 순서가 필요한 이유는 단순합니다.

      Slurm을 소스에서 빌드하는 경우, GPU 자동 감지(GRES autodetect) 기능을 켜려면 빌드 환경에서 NVML 라이브러리(libnvidia-ml.so)를 인식할 수 있어야 합니다.

      • 빌드 시: -with-nvml 플래그로 GPU 자동 감지를 활성화. 이때 NVML 헤더와 라이브러리가 설치되어 있어야 함

      • 시작 시: gres.conf`에서 GPU 디바이스 경로를 검증

      만약 Slurm을 먼저 빌드하고 나중에 GPU 드라이버를 설치하면, Slurm은 GPU 인식 기능 없이 빌드된 상태로 남아 있게 됩니다.

      결국 다시 빌드해야 하죠. 배포판이 제공하는 사전 빌드 패키지에는 NVML 지원이 이미 포함된 경우도 있지만, 소스에서 직접 빌드한다면 이 순서를 반드시 지켜야 합니다.


      4.4 컨테이너 런타임 — Docker와 Enroot의 역할 분담

      1편에서 다뤘듯, HPC 환경에서는 보안상의 이유로 Docker보다 Enroot/Apptainer 같은 rootless 컨테이너 기술이 선호됩니다. 그렇다고 Docker를 안 쓰는 건 아닙니다.

      도구

      어디에 쓰는가

      Docker

      모니터링/로깅 스택, 관리용 컨테이너 (관리 노드 위주)

      Enroot/Apptainer

      사용자 학습 워크로드 (컴퓨트 노드)

      Pyxis

      Slurm과 Enroot를 통합 (srun --container-image=...)

      이 분리가 중요합니다.

      컴퓨트 노드에서 Docker를 사용자에게 직접 노출하면 root 권한 노출 위험이 큽니다.

      사용자는 Enroot를 통해 컨테이너를 실행하고, 운영자는 Docker로 시스템 컴포넌트를 관리하는 식으로 역할을 나누는 게 좋습니다.

      5. Phase 3 — 공유 스토리지

      5.1 무엇을 공유해야 하는가?

      클러스터에서 공유 스토리지가 필요한 영역은 크게 셋입니다.

      1. 사용자 홈 — Python 가상환경, 실행 코드

      2. 소프트웨어 모듈 — 1편에서 다룬 Lmod 트리, 컴파일된 라이브러리

      3. 학습 데이터셋과 체크포인트 — 가장 무겁고, 가장 빠른 I/O가 필요한 부분



      5.2 NFS — 작은 클러스터의 합리적 출발점

      테스트 환경이나 노드 10대 안팎의 작은 클러스터라면 NFS만으로도 가능합니다.

      다만 NFS는 단일 서버 병목과 파일 시스템 성능에서 근본적인 한계가 있어, 분산 학습용으로는 권장되지 않습니다.


      5.3 병렬 파일시스템 — 대규모 분산 학습의 표준

      노드가 일정 수준 이상이거나 학습 데이터가 TB 단위라면 병렬 파일시스템이 사실상 필수입니다.

      여러 스토리지 서버에 데이터를 분산해 두고 클라이언트가 병렬로 접근하는 구조라, 노드가 늘어도 대역폭이 함께 늘어납니다.

      시스템

      특성

      적용처

      Lustre

      HPC 표준, 가장 성숙, 무료

      연구소, 대학, 스타트업

      GPFS (IBM Spectrum Scale)

      엔터프라이즈 안정성, 라이선스

      대기업, 금융, 정부

      BeeGFS

      운영 친숙, 무료 (엔터프라이즈는 유료)

      중간 규모 환경

      WekaFS

      NVMe-first, 클라우드 친화

      고성능 어플라이언스

      VAST Data

      단일 계층 어플라이언스

      통합 관리

      6. Phase 4 — 스케줄러 스택

      이제 자원 관리의 핵심인 스케줄러를 올립니다.

      1편과 2편에서 Slurm에 대한 설명 중심으로 다뤘으니, 이번에는 구축 관점으로 정리해보겠습니다.


      6.1 빌드 의존성 — hwloc → PMIx → Slurm

      Slurm을 소스에서 빌드한다면, 다음 순서를 지키는 것이 좋습니다.

      1. hwloc : CPU/NUMA 토폴로지 라이브러리

      2. PMIx : Slurm-MPI 인터페이스 (hwloc·libevent에 의존)

      3. Munge : 인증 데몬 (Phase 1에서 이미 끝남) + Slurm 빌드 시 헤더 필요

      4. Slurm : 위 모두에 의존, --with-pmix --with-hwloc 플래그로 빌드

      예를 들어 Slurm을 먼저 설치하고 나중에 PMIx를 추가하면, Slurm은 PMIx 없이 빌드된 상태이므로 PMIx 기반 MPI 학습이 동작하지 않습니다. 결국 Slurm을 다시 빌드해야 하죠.


      6.2 컨트롤러 HA — Active/Standby와 공유 상태

      대규모 클러스터에서 컨트롤러 단일 장애점은 위험합니다.

      Slurm은 공유 StateSaveLocation 기반 HA를 표준으로 권장합니다.

      원리는 단순합니다. 두 컨트롤러가 같은 상태 디렉터리를 공유 스토리지로 마운트하고, 평소에는 1번이 일하고 1번이 죽으면 2번이 같은 상태를 읽어 이어서 일합니다.

      # 사례 - EasyHPC의 HA 구성
      slurm.conf:
        SlurmctldHost=mgmt01    ← 첫 번째가 primary
        SlurmctldHost=mgmt02    ← 두 번째 이상은 backup
        StateSaveLocation=/data/.slurm_state    ← 공유 스토리지 위치

      여기서 중요한 점은, 상태 디렉터리가 정말로 공유 스토리지 위에 있는지 검증해야 한다는 것입니다.

      로컬 디스크의 /var/spool/slurm을 양쪽에 만들어 놓는 건 HA가 아닙니다. 페일오버해 봐야 다른 노드는 그 상태를 못 보니까요.

      다만 한 가지 문제가 있습니다. 공유 StateSaveLocation 자체가 또 다른 SPOF가 될 수 있다는 점입니다.

      NFS 서버 한 대를 마운트해 쓴다면, 그 NFS가 죽는 순간 컨트롤러 HA도 같이 무력화됩니다.

      그래서 StateSaveLocation에 쓰는 공유 스토리지는 고가용성 구성이거나 적어도 낮은 latency를 보장하는 시스템이어야 합니다.

      컨트롤러를 이중화한 만큼, 그 뒤의 공유 스토리지의 장애 도메인도 함께 따져봐야 한다는 뜻이죠.


      6.3 Accounting DB — 장애 도메인 분리

      slurmdbd가 사용량과 Job 이력을 기록할 데이터베이스(보통 MariaDB)도 함께 셋업합니다.

      여기서 자주 헷갈리는 부분이 있습니다.

      slurmdbd라는 이름 때문에 마치 데이터베이스처럼 들리지만, 실제로는 Slurm과 DB 사이의 통신 데몬일 뿐입니다.

      accounting 데이터를 실제로 보관하는 건 그 뒤의 MariaDB죠. 이 사실이 이중화 전략을 갈라놓습니다.

      slurmdbd는 자기가 가진 상태가 없으니(stateless), 같은 DB를 바라보는 백업 slurmdbd를 다른 호스트에 띄우기만 하면 즉시 이중화가 됩니다.

      반면 진짜 데이터를 들고 있는 MariaDB는 그렇게 간단하지 않습니다. 데이터를 어떻게 복제하고 동기화할지가 별개의 큰 주제거든요.

      그래서 일반적인 권고 패턴은 다음과 같습니다.

      • slurmdbd 백업 노드 두기 — slurm.conf의 AccountingStorageBackupHost로 백업 호스트를 지정

      • MariaDB: 단일 노드로 시작. DB HA는 별도 프로젝트로 분리

      다행히 slurmctld는 자체 StateSaveLocation에 상태를 캐시하기 때문에, DB가 잠시 끊겨도 스케줄링 자체는 멈추지 않습니다.

      그래서 DB HA를 나중에 별도로 다루는 선택이 합리적이죠.

      클라우드라면 관리형 DB로 우회하는 게 가장 깔끔합니다.


      6.4 Configless 모드 — 수십~수백 노드 운영을 위해

      Slurm의 configless 모드를 사용하면, 컴퓨트 노드가 시작 시 컨트롤러로부터 설정을 가져옵니다. 기존에는 slurm.conf`를 모든 노드에 똑같이 배포해야 했지만, configless에서는 그럴 필요가 없죠.

      # 컴퓨트 노드 측
      slurmd --conf-server=mgmt01:6817,mgmt02:6817

      수십~수백 노드 규모에서 진가를 발휘합니다. slurm.conf` 한 줄을 바꾸려고 모든 노드에 다시 배포하는 작업이 사라지니까요.

      7. Phase 5 — 부가 컴포넌트

      스케줄러가 설치된 다음, 실무에서 거의 항상 함께 쓰이는 세 가지를 더 얹습니다.

      컴포넌트

      역할

      1편 / 2편 참고

      Lmod

      Environment Module 시스템 (Lua 기반)

      1편 3.2절

      Pyxis

      Slurm + Enroot 통합 (srun --container-image=...)

      1편 4.2절

      NHC (Node Health Check)

      노드 헬스체크

      1편 1.1절

      NHC는 비유하자면 사전 안전 장치입니다.

      메모리 누수, 좀비 프로세스, 디스크 가득 참, GPU 인식 실패 등을 감지하면 노드를 DRAIN 상태로 만들어 추가 Job 할당을 막습니다.

      실무 Tip

      2편 마무리에서 다뤘던 prolog/epilog 스크립트도 이 단계에서 자리를 잡습니다. 실무에서 자주 쓰이는 패턴은 다음과 같습니다.

      • Prolog: GPU ECC 에러 카운터 확인, 임시 디렉터리 사전 생성, 사용자 환경 변수 검증

      • Epilog: 좀비 프로세스 정리, 임시 디렉터리 청소, GPU 상태 점검

        GPU 강제 reset(nvidia-smi --reset )을 epilog에 일률적으로 넣는 사례도 보이는데, NVSwitch나 MIG 환경에서는 fabric manager와 충돌하거나 reset 자체가 실패할 수 있어 보수적으로 적용하는 게 안전합니다.

        이상이 의심되는 노드는 차라리 DRAIN 상태로 두고 NHC가 처리하도록 맡기는 패턴이 더 일반적입니다.

        /etc/slurm/prolog.d/, /etc/slurm/epilog.d/ 같은 디렉터리에 run-parts 스타일로 스크립트를 떨어뜨리는 패턴이 가장 깔끔합니다.

      이 외에도 사용자가 직접 소프트웨어를 빌드할 수 있도록 EasyBuild나 Spack 같은 빌드 도구를 함께 두는 경우가 많습니다.

      다만 이건 첫 배포 때 빌드에 한참 걸리니, 클러스터가 안정된 다음 천천히 진행하는 걸 권장합니다.

      8. Phase 6 — 모니터링과 로깅

      이 단계가 사실상 클러스터 운영의 본 게임입니다. GPU 사용률을 비롯한 비용 효율 지표가 직접 측정되는 곳이니까요.


      8.1 표준 스택

      업계의 사실상 표준은 다음 조합입니다.

      도구

      역할

      설치 위치

      Prometheus

      메트릭 저장소

      모니터링 노드

      Grafana

      대시보드

      모니터링 노드

      Alertmanager

      알림 라우팅

      모니터링 노드

      node_exporter

      OS 메트릭 (CPU, 메모리, 디스크, 네트워크)

      모든 노드

      slurm-exporter

      Slurm 큐, 작업 상태, 파티션 메트릭

      컨트롤러

      dcgm-exporter

      GPU 메트릭 (사용률, 메모리, 온도, 전력)

      GPU 노드

      Loki + Promtail/Alloy

      로그 수집 및 저장

      로깅 노드 + 모든 노드

      Loki 대신 ELK 스택이나 ClickHouse + Vector 조합도 많이 씁니다.

      어느 쪽이든 메트릭(시계열)과 로그(이벤트)를 분리해서 다룬다는 원칙은 동일합니다.

      9. Phase 7 — 사용자 관리

      마지막 단계는 *최종 사용자(End User)*의 중앙 관리입니다.

      Phase 1에서 다룬 시스템 사용자(slurm, munge 등) 와는 별개로, 실제 클러스터를 사용할 연구원·개발자 계정을 어떻게 관리할지의 문제죠.

      노드 수가 늘어나면 /etc/passwd 로 관리하는 게 불가능해지니까요.


      9.1 선택지 비교

      방식

      적용처

      자체 OpenLDAP + SSSD

      회사 LDAP/AD가 없거나 격리망 환경

      회사 LDAP/AD에 SSSD로 연결

      사내 IDP가 이미 있는 경우

      대부분의 기업 환경에서 GPU 클러스터는 분리망에 두는 경우가 많습니다.

      보안 정책상 회사 LDAP/AD를 클러스터가 직접 바라보게 해주는 사례는 흔치 않죠.

      그래서 클러스터 전용 자체 LDAP을 띄우고 별도 관리하거나, 사용자 정보를 회사 LDAP에서 동기화 하는 형태의 패턴이 가장 흔합니다.


      9.2 Slurm 사용자 정책 — Account, QOS, Fairshare

      LDAP에서 사용자를 받아오는 것만으로는 끝이 아닙니다.

      사용자가 클러스터에 어떻게 자원을 쓸지를 Slurm 측에서도 정의해야 하죠. 2편에서 다뤘던 부분입니다.

      개념

      어디에 쓰는가

      Account

      부서/프로젝트 단위 청구 그룹

      Association (User ↔ Account)

      사용자와 Account의 연결. 한 사용자가 여러 Account에 속할 수 있음

      QOS

      등급별 자원 한도 및 우선순위 (emergency, normal, preemptible 등)

      Fairshare

      그룹별 자원 배분 비율

      여기서 한 가지 알아둘 점

      LDAP과 Slurm 사용자 DB(sacctmgr)는 별개입니다.

      초기 설정 상태에서는 LDAP에 사용자가 있으면 그대로 Job을 제출할 수 있지만, 그 사용자는 어떤 Account에도 속하지 않은 상태로 자원을 씁니다.

      그러면 사용량 추적도, 그룹별 한도도, Fairshare도 작동하지 않죠. 다중 팀이 자원을 나눠 쓰는 운영 환경에서는 곧 혼란이 시작됩니다.

      그래서 운영 클러스터로 넘어가기 전에 다음 두 가지를 챙겨야 합니다.

      • Account/Association 등록을 온보딩 절차에 포함 : 신규 사용자가 LDAP에 추가될 때 Slurm 측에도 함께 등록되도록

      • AccountingStorageEnforce 설정 강화 : associations 이상으로 두면 등록 누락이 조용한 사용량 누수가 아니라 명시적 Job 거부로 드러남


      10. 자동화 — 코드로 클러스터를 표현하기

      여기까지 실제 구성의 7단계를 살펴봤습니다. 이걸 수동으로 한 번씩 한다고 상상해 보세요.

      만일 노드 30대에 위 절차를 손으로 적용하면, 어딘가는 다르게 적용되는 것이 나옵니다.

      게다가 6개월 뒤 신입 엔지니어가 합류했을 때 "이 클러스터는 이렇게 만들어졌다"라고 설명할 방법이 없습니다.

      그래서 자동화는 선택이 아니라 필수입니다.


      10.1 도구 선택지

      업계에서 흔히 쓰이는 도구들과 적합한 영역은 대략 이렇습니다.

      도구

      적합한 영역

      Ansible

      노드 구성, 패키지 설치, 설정 관리 (가장 많이 쓰임)

      Puppet, Chef, Salt

      대규모 환경 (Ansible과 경쟁)

      Terraform

      클라우드 인프라 프로비저닝

      대다수 온프레미스 HPC 자동화 프로젝트는 Ansible 기반입니다.

      EasyHPC도 Ansible을 씁니다. 이유는 단순합니다 에이전트가 필요 없고(SSH만 있으면 됨), idempotent하며, 코드가 읽기 쉽기 때문입니다.


      10.2 자동화 코드의 진짜 가치

      Ansible로 코드를 짜는 진짜 가치는 시간 절약이 아닙니다.

      • 코드가 곧 문서 : "어떤 설정을 어떤 순서로 적용했는가"가 코드에 그대로 남습니다.

      • 멱등성(idempotent)을 가짐 : 같은 코드를 여러 번 돌려도 결과는 같습니다. 부분 실패 시 재실행이 안전합니다.

      • 변경이 추적 : Git으로 누가 언제 무엇을 바꿨는지 보입니다.

      • 검증할 수 있다 : "이 클러스터가 의도한 상태인가?"를 자동으로 확인할 수 있습니다.

      EasyHPC의 Role 구조

      roles/
      ├── common                          ← Phase 1: OS 및 시스템 설정
      ├── nvidia-driver, docker, enroot   ← Phase 2: GPU/컨테이너
      ├── nfs-server, nfs-client          ← Phase 3: 스토리지
      ├── hwloc, pmix, slurm, ha-slurm    ← Phase 4: 스케줄러
      ├── lmod, pyxis, nhc                ← Phase 5: 부가
      ├── monitoring, loki, alloy         ← Phase 6: 모니터링/로깅
      └── ldap-server, ldap-client        ← Phase 7: 사용자 관리

      위 role들을 적용하는 playbook의 단계가 지금까지 설명한 Phase와 1:1로 대응됩니다. 단계화된 사고가 코드 구조에 그대로 박혀 있는 것 이죠.

      실무 Tip

      자동화 코드는 처음부터 완벽하게 짤 필요 없습니다. 다음 순서로 진화시키는 게 보통입니다.

      1. 처음에는 셸 스크립트로 작업 절차를 기록 (잊지 않기 위해)

      2. 반복되는 작업을 Ansible role로 옮김

      3. 단계 간 의존성을 코드로 강제 (assert 등)

      4. 검증 플레이북 추가

      이렇게 차곡차곡 쌓아 가다 보면 어느새 코드가 곧 운영 매뉴얼이 됩니다.

      마무리

      이번 글에서는 대규모 분산 학습을 위한 온프레미스 HPC 클러스터를 어떤 단계로 만들어야 하는지를 살펴봤습니다.

      핵심을 정리하면 이렇습니다.

      • 구축 순서에는 이유가 있음

        • 기초(인증·시간·UID)가 흔들리면 그 위에 쌓는 모든 게 흔들립니다. 의존성을 무시하면 결국 처음부터 다시 해야 합니다.

      • 각 단계마다 결정이 필요

        • OS 통일, 드라이버 버전 고정, NFS vs 병렬 파일시스템, HA 설계, LDAP 연동 방식 이 결정들이 이후 운영 방식 전반을 좌우합니다.

      • 모니터링은 필수

        • GPU 사용률부터 Slurm 큐 상태, 노드 헬스까지, 보이지 않으면 관리할 수 없습니다.

      • 자동화는 재현 가능성을 위한 것

        • 수동으로 적용하면 어딘가는 반드시 달라집니다. 코드가 곧 문서이자 운영 매뉴얼입니다.

      처음에는 "이걸 다 직접 해야 하나?"라는 생각이 드실 수 있습니다.

      중요한 건 각 단계의 원리를 직접 경험해 본 다음, 반복되는 부분을 자동화로 옮기는 흐름입니다.

      단계별 구성 요소를 충분히 이해했다면 EasyHPC 같은 자동화 솔루션을 활용하거나, 직접 자동화 코드를 작성해 보는 것도 좋은 방향입니다.

      오랜만의 연휴 기간이네요. 따뜻한 봄날, 날씨만큼이나 기분 좋은 재충전 시간이 되시길 바라며 다음 글에서 또 뵙겠습니다.

      궁금한 점이나 더 다뤄줬으면 하는 부분이 있다면 언제든 댓글로 알려주세요!

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      alankim 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기