BESTNET-CLOUD
GPU-VPS
GPUStack
10G Private Network
NFS Shared Cache
기술 블로그 / 인프라 구축 가이드
Bestnet Cloud × GPU-VPS를 10G 프라이빗 네트워크로 연결하여
GPUStack 클러스터를 구현하는 절차
베스트넷 클라우드를 컨트롤 플레인으로, GPU-VPS를 추론 워커로 분리하고,
공유 NFS 캐시로 모델 파일을 일원화하는 구성입니다.
클라이언트 포털 측 준비부터
Ubuntu 상의 구현, 운영 확인까지를 사용 방법 문서로 정리했습니다.
Private Link
모델 다운로드
GPU Worker
공유 모델 보관처
이 문서에서 다루는 범위
본 문서는 Bestnet Cloud 상에 AI-SRV를 구축하여 GPUStack Server + NFS를 집약하고,
GPU-VPS 측에 여러 GPU 워커를 배치하는 초기 구축 패턴을 다룹니다.
역할 분리와 공유 캐시 설계가 주제이므로, 공개용으로 실제 IP나 내부 명명 규칙은 예시 값으로 치환했습니다.
설계의 핵심은 GPU가 필요 없는 컨트롤 플레인과 모델 보관처를 범용 클라우드 측으로 옮기고,
GPU-VPS는 오로지 추론 실행용 노드로 한정하는 것입니다.
이렇게 해두면 워커를 늘려도 스토리지의 중복 투자를 피하기 쉽고,
모델의 실체는 Bestnet Cloud 측 공유 영역에서만 관리할 수 있습니다.
모델 등록은 GUI에서만
AI-SRV에 GPUStack Server + NFS를 통합
모든 worker는 NFS 마운트 포인트 /models를 공유
여기에서는 0.6.x 계열의 구축 패턴을 알기 쉽게 정리합니다.
Bestnet Cloud 지식을 실제 구축 순서로 재구성하기
Bestnet Cloud의 지식 문서에서는 클라이언트 포털의 운영 작업이 세밀하게 나뉘어 있습니다.
따라서 GPU 클러스터 구축에서는 “어느 시점에 어떤 지식 문서를 사용할지”를 먼저 정해두면 작업 재시도를 줄일 수 있습니다.
본 문서에서는 포털 측 준비를 다음 순서로 정리했습니다.
포털 보호
MFA·허용 IP 개념을 먼저 확립
SSH 키 등록
OS 배포 전에 관리 키 정비
템플릿 생성
AI-SRV와 GPU-VPS를 Ubuntu 24로 준비
Private Network
10G 세그먼트에 모든 노드 연결
Firewall / NAT
공개 범위와 통신 방향 제한
Snapshot
초기 상태로 복원 가능한 지점 보존
Access
SSH 키 등록·관리
서버 생성 후에 수작업으로 키를 삽입하는 것이 아니라, 템플릿 배포 전에 키 운영을 결정해둡니다.
Provision
템플릿에서 서버 생성
AI-SRV와 GPU 워커를 같은 베이스 OS로 통일하면, 이후의 명령 절차가 흔들리지 않습니다.
스냅샷 관리
OS 초기화 후, GPU 드라이버 도입 후, 앱 도입 전 등에서 복원 지점을 만들어두면 검증이 편리해집니다.
Scale
클라우드 리소스 업그레이드
용량 부족이 발생하면, 먼저 AI-SRV 쪽의 공유 모델 영역을 확장하는 설계로 하면 비용 효율이 좋아집니다.
가상 라우터 NAT
GPU 워커를 private-only로 두고 싶은 경우에는, 외부 통신만 NAT 경유로 하는 구성도 선택할 수 있습니다.
아키텍처의 사고방식
역할은 심플합니다. Bestnet Cloud 쪽의 AI-SRV가 Web UI / API / NFS 공유를 담당하고,
GPU-VPS 쪽의 노드는 GPUStack Worker와 추론 실행만 집중합니다.
10G 프라이빗 네트워크를 사용해 내부 통신을 폐쇄함으로써,
모델 배포·NFS·클러스터 접속을 모두 private side로 몰아넣을 수 있습니다.
BESTNET-CLOUD
control-01
GPUStack Server + NFS를 통합한 AI-SRV
- Web UI / API 제공
/srv/gpustack_models를 NFS export- 로컬에서는
/models에 bind mount - 모델 실체를 한 곳으로 집약
NFS / UI / Worker Join / 내부 통신
GPU-VPS
gpu-worker-01 / 02
/models를 공유 마운트하고, 추론만 담당하는 worker 그룹
- GPUStack Worker 기동
--cache-dir /models를 통일- 각 worker에 대용량 모델 보관 영역을 가지지 않음
- 수평 확장 시에는 같은 패턴으로 대수 추가
→
최초의 worker가 모델을 1회만 취득
→
다른 worker는 같은
/models에서 읽어오기만스토리지는 AI-SRV 쪽으로 몰아넣기
용량 설계의 주전장은 AI-SRV입니다. 모델 본체·임시 다운로드·향후 교체분을 고려하여, 공유 영역을 넉넉하게 확보합니다.
GPU-VPS는 lean하게 유지
GPU 워커 쪽은 OS, GPU driver, GPUStack Worker, 최소한의 로그 영역을 중심으로 설계하고, 모델 본체를 복제하지 않습니다.
통신은 private side로 몰아넣기
UI, worker join, NFS, 모델 재사용 전부를 private network에서 완결시키면, 공개 범위가 작아집니다.
사전에 결정해둘 항목
| 역할 | 배치처 | 호스트명(예) | Private IP(예) | 주요 책무 |
|---|---|---|---|---|
| Server + NFS | Bestnet Cloud | control-01 | 10.10.0.10 | GPUStack UI / API, NFS, 모델 보관처 |
| GPU Worker #1 | GPU-VPS | gpu-worker-01 | 10.10.0.21 | 추론 실행, 공유 /models 사용 |
| GPU Worker #2 | GPU-VPS | gpu-worker-02 | 10.10.0.22 | 추론 실행, 공유 /models 사용 |
공개용 예시입니다. 실제 환경에서는 자사의 naming rule과 private subnet에 맞춰 주십시오.
설계 시 체크포인트
- 어느 노드에 public IP를 부여할 것인가
- worker를 private-only로 할 것인가
- NAT 라우터를 사용할 것인가, 개별로 외부 통신을 제공할 것인가
- 공유 모델 영역의 초기 용량과 증설 방침
스토리지 견적 산정 방법
- 가동 중인 모델의 총 크기
- 전환 중 신구 모델이 일시적으로 공존하는 여유 공간
.part등 임시 파일의 여유 공간- 로그·운용 파일·향후 worker 추가 여유 공간
클라이언트 포털 측 준비를 먼저 확정한다
클라이언트 포털 자체의 방어를 정비한다
서버 생성보다 먼저 관리면의 방어 방침을 결정합니다. 특히 팀 운용에서는
MFA와 허용 IP 처리를 먼저 정리해 두면 나중에 “누가 어디서 관리면에 들어갈 수 있는가”로 고민하지 않습니다.
SSH 키를 등록한 후 서버를 만든다
AI-SRV와 GPU 워커를 생성한 후 개별적으로 키를 삽입하는 것보다, 클라이언트 포털의 SSH 키 관리에서
먼저 키를 정비해 두는 것이 템플릿 배포 후 바로 관리에 들어갈 수 있습니다.
- 운용 팀용 공개키를 정리한다
- 긴급 시 공유키와 개인키를 혼재시키지 않는다
- 기사 공개 시 키 fingerprint도 게재하지 않는다
Bestnet Cloud 상에 AI-SRV를 템플릿에서 생성한다
AI-SRV에는 Ubuntu 24 계열 템플릿을 사용하며, GPUStack Server와 NFS 모두를 탑재합니다.
이 노드는 모델 보관처도 겸하므로, OS 디스크와 별도로 충분한 저장 영역을 확보하는 설계가 적합합니다.
- 역할은 GPUStack Server + NFS
- private network에 연결한다
- UI 공개가 필요한 경우에만 public 측을 검토한다
- 모델 저장처의 용량은 worker보다 AI-SRV 측을 두껍게 한다
GPU-VPS 측에 worker를 필요 대수만큼 생성한다
worker는 추론용이므로, GPU 종류·VRAM·향후 모델 크기를 기준으로 GPU-VPS의 플랜을 선택합니다.
한편, 모델 본체는 NFS 측에 배치하므로, worker의 스토리지는 OS와 실행에 필요한 최소한으로 줄이기 쉽습니다.
- Ubuntu 24 계열로 통일한다
- GPU driver / CUDA를 사용할 수 있는 전제로 생성한다
- private network에 연결한다
- 필요 없으면 public IP를 부여하지 않는 구성도 검토한다
10G 프라이빗 네트워크에 전체 노드를 탑재한다
NFS와 GPUStack의 내부 통신은 Bestnet Cloud와 GPU-VPS를 연결하는 10G private link 상에서 흐릅니다.
이를 통해 모델 읽기나 worker join을 public 측으로 내보내지 않아도 됩니다.
- AI-SRV와 전체 worker를 동일 private segment에 수용한다
- 고정 IP를 할당하여 후속 NFS export와 systemd 설정을 안정화한다
- worker에 외부 통신이 필요하면 NAT 라우터 방식 또는 임시 public egress를 선택한다
worker를 private-only로 배치하고 싶은 경우, Bestnet Cloud의 가상 라우터 / NAT 패턴을 사용하여
OS 업데이트나 외부 획득만 밖으로 내보내는 설계가 다루기 쉽습니다.
방화벽의 초기 규칙을 결정한다
규칙은 “AI-SRV에 필요한 inbound를 최소한만 허용하고, worker는 SSH 이외의 inbound를 거의 부여하지 않는다”는 방침으로 충분합니다.
포털의 방화벽 화면에서 먼저 기존 규칙을 확인한 후, 필요한 포트만 추가합니다.
| 대상 | 포트 / 프로토콜 | 송신원 고려사항 | 용도 |
|---|---|---|---|
| AI-SRV | 22/tcp | 관리 원본 IP만 제한 | SSH |
| AI-SRV | 80/tcp | 관리 네트워크 or private side | GPUStack Web UI / API |
| AI-SRV | 2049/tcp | private subnet만 | NFS v4 |
| AI-SRV | 111/tcp,111/udp | 필요 시에만 private subnet | rpcbind를 사용하는 구성용 |
| GPU Worker | 22/tcp | 관리 원본 IP만 제한 | SSH |
NFS v4 전제라면 2049/tcp에 집중하기 쉬운 반면, 환경에 따라 rpcbind를 사용하는 경우가 있습니다. 공개 범위는 반드시 private subnet으로 제한합니다.
첫 스냅샷을 취득한다
OS 초기 생성, 키 투입, private network 연결, 방화벽 정비가 끝나면,
일단 AI-SRV와 GPU worker의 스냅샷을 취득해 두면, 이후 미들웨어 도입에서 실패해도 복구하기 쉬워집니다.
OS 측 베이스라인 만들기
서버와 worker 모두에서, 먼저 시각 동기화와 NFS 기반을 맞춥니다. GPU 워커는 이후에 GPU driver / CUDA를 설치하므로,
먼저 OS 업데이트와 재시작 포인트를 완료해 두면 안정적입니다.
# 전체 노드
sudo apt update
sudo apt install -y nfs-common
# NFS 서버용 (AI-SRV만)
sudo apt install -y nfs-kernel-serverAI-SRV에서 맞출 것
- 시각 동기화
- NFS 서버
- 모델 저장소 마운트 설계
- GPUStack Server 초기 도입
GPU 워커에서 맞춰야 할 것
- 시각 동기화
- NFS 클라이언트
- GPU driver / CUDA
- GPUStack Worker와
/models마운트
AI-SRV에 GPUStack Server + NFS 구축하기
GPUStack Server 설치하기
초기 구축 예시에서는 AI-SRV에 GPUStack Server를 도입하여 관리 UI에 로그인할 수 있는 상태를 만듭니다.
초기 관리자 비밀번호는 기록한 후 안전한 vault로 이동하며, 기사에는 게재하지 않습니다.
curl -sfL https://get.gpustack.ai | sh -s -
cat /var/lib/gpustack/initial_admin_password
# Web UI (예시)
# http://10.10.0.10/NFS 공유 디렉터리 만들기
모델 파일의 실체는 /srv/gpustack_models에 둡니다.
이를 private subnet에만 export하고, AI-SRV 자체에서도 /models로 bind mount합니다.
이렇게 해두면, 서버에서 보이는 경로와 worker에서 보이는 경로가 통일됩니다.
sudo mkdir -p /srv/gpustack_models
echo "/srv/gpustack_models 10.10.0.0/24(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -ra
# Server 자체도 bind mount
sudo mkdir -p /models
sudo mount --bind /srv/gpustack_models /models
echo "/srv/gpustack_models /models none bind 0 0" | sudo tee -a /etc/fstabworker 참가 토큰 발급하기
GPUStack의 GUI에서 worker join token을 생성합니다. 공개 문서에서는 <WORKER_JOIN_TOKEN>으로 표기하며,
실제 값은 게재하지 않습니다. 또한 GUI에 로그인할 수 있는 관리 주체도 private network 쪽으로 맞추는 운영이 더 안전합니다.
GPU-VPS 측에 공유 cache를 마운트하여 worker를 참가시키기
먼저 /models를 NFS 마운트하기
각 worker는 AI-SRV가 export하고 있는 공유 영역을 동일한 경로 /models로 마운트합니다.
이 시점에서 모든 worker의 cache path가 통일되므로 모델의 중복 저장을 방지할 수 있습니다.
sudo mkdir -p /models
echo "10.10.0.10:/srv/gpustack_models /models nfs defaults 0 0" | sudo tee -a /etc/fstab
sudo mount -a마운트 후에는 mount | grep /models로 의도한 공유 대상이 보이는지 확인합니다.
GPUStack Worker 설치하기
AI-SRV 측에서 발급한 token을 사용하여 각 GPU-VPS를 worker로 클러스터에 참가시킵니다.
curl -sfL https://get.gpustack.ai | sh -s - --server-url http://10.10.0.10 --token <WORKER_JOIN_TOKEN>worker 서비스에서 --cache-dir /models 고정하기
공유 cache 구성에서는 이 지정이 가장 중요합니다. GPUStack Worker의 systemd 정의에--cache-dir /models를 추가하고, data-dir도 함께 고정해 둡니다.
[Service]
ExecStart=/root/.local/bin/gpustack start --server-url http://10.10.0.10 --token <WORKER_JOIN_TOKEN> --cache-dir /models --data-dir /var/lib/gpustack-datasudo systemctl daemon-reload
sudo systemctl enable --now gpustack
# Using cache dir: /models 가 출력되면 OK
journalctl -u gpustack -fGPUStack GUI에서 worker가 Ready 상태가 되는지 확인
GUI의 Workers 화면에서 모든 GPU-VPS가 Ready 상태가 되는지 확인합니다.
여기서 Not Ready 상태로 남아 있다면, GPU driver / CUDA, NFS 마운트, worker 로그 순으로 확인하면 빠릅니다.
모델 배포 및 동작 확인
구축 완료 판단은 단순히 worker가 Ready 상태가 되는 것만이 아닙니다.
실제로 GUI에서 모델을 2 replicas 이상으로 deploy하고, 첫 번째 1대만 다운로드하며,
2대째 이후는 동일한 공유 파일을 재사용하는 것까지 확인하여 완료로 간주합니다.
1
Catalog에서 Deploy
replicas를 2 이상으로 설정하여 worker가 여러 대 사용되는 조건을 만듭니다.
2
첫 번째 worker가 가져옴
/models에 저장되지 않았다면, 할당된 첫 번째 worker가 모델을 가져옵니다.
3
2대째는 공유 파일을 읽음
동일한 모델이 공유 캐시에 있으면, 추가 다운로드 없이 로드됩니다.
4
교체 시 재 Deploy
모델 업데이트는 GUI에서 구 버전을 정리하고 신 버전을 재 deploy하는 운용으로 진행하면 추적하기 쉬워집니다.
이 구성에서 효과적인 비용 최적화
GPU-VPS마다 모델을 전체 보유하지 않으므로, GPU 노드의 스토리지를 얇게 설계하기 쉬워집니다.
큰 모델일수록 공유 NFS 캐시 방식의 효과가 명확하게 나타납니다.
운용 시 핵심 포인트
worker를 늘릴 때
GPU-VPS를 추가하고, 동일한 private network·동일한 /models 마운트·동일한 --cache-dir로 확장합니다.
용량이 부족할 때
먼저 AI-SRV 측의 공유 모델 영역을 검토합니다. 각 worker의 스토리지를 개별 확장하는 것보다 공유 측을 늘리는 것이 효율적입니다.
변경 전 복원 지점
GPU driver 업데이트, CUDA 업데이트, GPUStack 업데이트 전에는 스냅샷이나 백업을 취하는 습관을 들여두면 안전합니다.
모니터링 및 문제 해결
GPUStack 로그
journalctl -u gpustack -fServer / Worker의 동작 확인은 우선 여기서부터 보는 것이 기본입니다.
모델 다운로드 진행 상황
ls -lh /models
find /models -name "*.part".part가 남아 있는 경우는 다운로드 중이거나 미완료 가능성이 있습니다.
NFS 상태 확인
mount | grep /modelsworker 측에서 예상한 공유 대상이 보이는지 확인합니다.
Q. replicas를 늘리면 재다운로드하나요?
기본적으로 하지 않습니다. 공유 /models에 파일이 존재하면 worker는 이를 재사용합니다.
Q. worker는 public IP가 필수인가요?
필수가 아닙니다. 외부 통신 방식을 NAT 방식으로 맞춘다면 private-only로 운영하는 선택도 있습니다.
Q. 어디를 강화하면 비용 효율이 좋아지나요?
각 GPU worker의 스토리지가 아니라 공유 모델 저장소를 갖는 AI-SRV 측입니다. 모델을 한 곳에서 관리할 수 있기 때문입니다.
Bestnet Cloud를 제어계, GPU-VPS를 실행계로 분리하면 GPU 클러스터는 다루기 쉬워진다
AI-SRV에 GPUStack Server와 NFS를 통합하고, GPU-VPS 그룹은 worker로서 private network에 연결합니다.
그 위에서 /models를 공유 캐시로 만들면 스토리지 중복을 피하면서 GPU 클러스터를 자연스럽게 확장할 수 있습니다.
포털 측에서는 SSH 키, 템플릿 배포, private network, 방화벽, 스냅샷 순서로 정비하고,
OS 측에서는 NFS와 GPUStack의 경로를 통일합니다. 이것만으로도 실운영하기 쉬운 구성이 됩니다.
BESTNET-CLOUD × GPU-VPS
NFS Shared Cache
모델은 1회만 취득