OCI Container Instances에서 Ollama 실행하기 - 5분 만에 구축하는 Kubernetes 없는 프라이빗 LLM API
요약
Kubernetes 없이 OCI Container Instances를 사용하여 Ollama 기반의 프라이빗 LLM API를 구축하는 방법을 소개합니다. GPU 지원 및 OpenAI 호환 API를 활용하여 소규모 팀을 위한 효율적인 추론 환경을 5분 만에 구성할 수 있습니다.
핵심 포인트
- Kubernetes의 복잡성 없이 OCI Container Instance로 간편하게 배포 가능
- Ollama를 활용하여 OpenAI 호환 API와 자동 모델 관리 기능 제공
- A10 GPU 셰이프를 사용하여 7-13B 파라미터 모델의 원활한 추론 지원
- 컨테이너 재시작 시 모델 유지를 위해 OCI Block Volume 마운트 권장
한 동료가 팀에서 코드 리뷰 제안용으로 사용할 수 있는 프라이빗 LLM 엔드포인트(endpoint)를 구축해 달라고 요청했습니다. 요구 사항은 다음과 같았습니다: OpenAI 호환 API, 우리 클라우드 내부에서 실행(데이터가 테넌시(tenancy)를 벗어나지 않을 것), 그리고 "Kubernetes를 배우고 싶지 않다"는 것이었습니다.
마지막 요구 사항 때문에 OKE(Oracle Kubernetes Engine)는 제외되었습니다. 솔직히 10명에게 서비스를 제공하는 단일 모델 추론 엔드포인트에는 Kubernetes가 과한 측면도 있습니다.
저는 약 5분 만에 GPU가 포함된 OCI Container Instance에서 Ollama를 실행했습니다. 전체 과정을 소개합니다.
vLLM 대신 Ollama를 사용하는 이유
소규모 팀 엔드포인트의 경우, Ollama가 단순성 측면에서 승리합니다:
- 단일 바이너리(binary), Python 의존성 없음
- 첫 실행 시 모델을 자동으로 다운로드
- 간단한
ollama pull명령으로 여러 모델 관리 /v1/chat/completions경로에 OpenAI 호환 API 내장- GPU 메모리로부터 모델 로딩/언로딩을 자동으로 처리
vLLM은 높은 처리량(throughput)을 요구하는 프로덕션 환경(continuous batching, PagedAttention)에 더 적합하지만, 지금 상황은 그렇지 않습니다. 이번 사례는 "10명의 개발자가 한 시간에 몇 번씩 사용하는 정도"입니다.
배포
단 하나의 CLI 명령어로 가능합니다:
oci container-instances container-instance create \
--compartment-id $COMPARTMENT_ID \
--availability-domain "Uocm:US-ASHBURN-AD-1" \
...
주의할 점 몇 가지:
- GPU 셰이프(shape) —
CI.Standard.GPU.A10.1을 사용하면 24GB VRAM을 가진 A10 GPU를 사용할 수 있습니다. 대부분의 7-13B 파라미터 모델을 돌리기에 충분합니다. - 프라이빗 서브넷(Private subnet) — 퍼블릭 IP가 없습니다. 엔드포인트는 VCN 내부에서만 접근 가능합니다. 팀이 접근할 수 있도록 배스천(bastion) 또는 VPN을 추가했습니다.
OLLAMA_HOST=0.0.0.0— 기본적으로 Ollama는 localhost에서만 리스닝(listening)합니다. 컨테이너 내부에서는 모든 인터페이스에서 리스닝하도록 설정해야 합니다.
컨테이너는 약 10초 만에 시작됩니다. 하지만 아직 모델은 로드되지 않은 상태입니다.
모델 로드하기
Ollama는 처음 사용할 때 모델을 다운로드합니다. 저는 배스천을 통해 SSH로 접속하여 첫 번째 pull을 실행했습니다:
# 동일한 VCN 내의 VM에서
OLLAMA_IP=10.0.1.42 # Container Instance의 프라이빗 IP
...
초기 모델 다운로드에는 약 34분이 소요됩니다 (7B 모델, 약 4GB 기준). 그 이후부터는 12초 이내에 응답이 시작됩니다.
문제점: 모델 지속성 (Model Persistence)
여기서 제가 미리 고려했어야 할 주의사항이 있습니다. Container Instance는 기본적으로 지속성 스토리지 (Persistent Storage)를 제공하지 않습니다. 컨테이너가 재시작되면 다운로드된 모델은 사라집니다. 다시 pull 해야 합니다.
저의 해결책은 OCI Block Volume을 마운트하는 것이었습니다:
oci container-instances container-instance create \
... \
--containers '[{
...
컨테이너 재생성 (Recreation) 시에도 진정한 지속성을 유지하려면 OCI File Storage (NFS) 마운트를 사용해야 합니다. 하지만 이번 사용 사례의 경우, 휘발성 스토리지 (Ephemeral Storage)가 재시작 (Restart) 시에는 유지되므로(재생성 시에는 아님), 모델이 없을 경우 다시 pull 하는 간단한 curl 스크립트를 사용했습니다:
#!/bin/bash
# warmup.sh — 컨테이너 인스턴스 생성 후 실행
OLLAMA_IP=$1
...
팀에서 활용하는 용도
이 엔드포인트는 3주 동안 가동되었습니다. 팀은 다음과 같은 용도로 사용하고 있습니다:
- 코드 리뷰 제안 (Code review suggestions) — 함수를 붙여넣고 리뷰 요청
- 커밋 메시지 생성 (Commit message generation) — 변경 사항을 설명하면 Conventional Commit 형식으로 생성
- 문서 초안 작성 (Documentation drafts) — docstring 및 README 섹션 생성
- SQL 쿼리 도움 (SQL query help) — 원하는 내용을 설명하면 쿼리 반환
트래픽은 적은 편입니다 — 하루 총 50100건 정도의 요청이 발생합니다. A10 GPU는 대부분의 시간 동안 515%의 사용률을 유지합니다. 과한 사양(Overkill)이긴 하지만, OCI에서의 과한 사양조차 월 약 $1,094 수준이며, 팀은 비용을 정당화할 만큼 충분히 유용하다고 판단하고 있습니다.
비용 vs 대안
| 옵션 | 월간 비용 | 설정 시간 |
|---|---|---|
| OCI Container Instance + A10 GPU | ~$1,094 | 5분 |
| ... |
네, 이 정도 트래픽이라면 OpenAI가 더 저렴합니다. 하지만 팀의 요구 사항은 "데이터가 우리 클라우드를 벗어나지 않을 것"이었습니다. 컴플라이언스 (Compliance) 규정 때문입니다. Container Instance 방식은 Kubernetes의 복잡성 없이 프라이빗 엔드포인트를 제공했습니다. 때로는 단순함과 프라이버시를 위해 비용을 지불하기도 합니다.
만약 제가 다시 이 작업을 한다면
컨테이너 재생성 시에도 모델이 유지될 수 있도록 휘발성 스토리지 (ephemeral storage) 대신 OCI File Storage를 사용할 것입니다. 그리고 네트워크 수준의 액세스 제어 (access control)에 의존하는 대신, 속도 제한 (rate limiting)과 인증 (auth)을 위해 그 앞에 OCI API Gateway를 배치할 것입니다. 게이트웨이를 사용하면 월 약 $50의 비용이 추가되지만, 적절한 API 키와 요청 로깅 (request logging) 기능을 제공받을 수 있습니다.
약 20명 이상의 규모를 가진 팀이나 더 높은 처리량 (throughput)이 필요한 경우에는, 이전 포스트에서 설명한 설정대로 OKE 상에서 vLLM을 사용하는 방식으로 전환할 것입니다. 하지만 Kubernetes를 건드리지 않고 프라이빗 LLM을 원하는 소규모 팀에게는, Container Instances에서 Ollama를 실행하는 방식이 단순함 측면에서 따라올 자가 없을 것입니다.
Pavan Madduri — Oracle ACE Associate, CNCF Golden Kubestronaut. GitHub | LinkedIn | Website | Google Scholar | ResearchGate
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기