오프라인 환경에서 운영되는 엔터프라이즈급 AI/ML 추론 플랫폼을 구축한 프로젝트입니다. GPU 가속 추론, 3중화 클러스터링, 분산 스토리지, 그리고 완전한 오프라인 운영을 지원하는 마이크로서비스 아키텍처를 설계하고 구현했습니다.
노드 타입 | 호스트명 | 역할 | 주요 리소스 |
---|---|---|---|
Master | master-node | Control Plane, NFS Server | 8 vCPU, 32GB RAM |
GPU Worker 1 | gpu-node-1 | AI/ML 추론 | Tesla T4, 16GB VRAM |
GPU Worker 2 | gpu-node-2 | AI/ML 추론 | Tesla T4, 16GB VRAM |
CPU Worker | cpu-node-1 | 관리 서비스 | 8 vCPU, 16GB RAM |
Infrastructure Layer:
- Kubernetes v1.28
- Docker/Containerd
- Ubuntu 20.04/22.04 LTS
Load Balancing:
- MetalLB (Bare-metal LB)
- NGINX Ingress Controller
Data Layer (3중화):
- MariaDB MaxScale Cluster
- Redis Cluster (6 nodes)
- SeaweedFS Distributed Storage
AI/ML Services:
- NVIDIA Triton Inference Server
- AI Platform Services
- Custom ML Model Registry
Monitoring & Operations:
- Fluent Bit (Logging)
- Kubernetes Native Monitoring
- Auto-recovery Scripts
핵심 특징:
구현 성과:
특징:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin
spec:
template:
spec:
containers:
- name: nvidia-device-plugin
image: nvcr.io/nvidia/k8s-device-plugin:v0.14.0
securityContext:
privileged: true # GPU 접근 권한
volumeMounts:
- name: dev
mountPath: /dev # GPU 디바이스 마운트
배포 전략:
- Dynamic Batching: GPU 효율 85% 달성
- Model Versioning: 무중단 모델 업데이트
- Multi-GPU Scheduling: 로드 밸런싱
성능 지표:
- 추론 처리량: 5,000 req/sec
- P99 레이턴시: < 50ms
- GPU 메모리 활용률: 80%
# 고정 IP 설정 (DHCP 비활성화)
network:
version: 2
ethernets:
eth0:
dhcp4: false
addresses: [10.0.0.100/24] # 내부 네트워크
# MetalLB IP Pool (내부 네트워크)
addresses:
- 10.0.0.240-10.0.0.255
#!/bin/bash
# k8s-auto-recovery.sh
# 1. 필수 서비스 자동 시작
systemctl enable --now containerd kubelet
# 2. 스왑 영구 비활성화
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 3. 커널 모듈 자동 로딩
modprobe br_netfilter overlay
# 4. 클러스터 상태 체크
kubectl wait --for=condition=Ready nodes --all
메트릭 | 측정값 | 목표 대비 |
---|---|---|
처리량 | 5,000 req/sec | +25% |
P50 레이턴시 | 12ms | -40% |
P99 레이턴시 | 48ms | -20% |
GPU 활용률 | 85% | +13% |
메트릭 | 측정값 | 업계 표준 |
---|---|---|
가용성 | 99.99% | 99.9% |
MTTR | 30초 | 5분 |
데이터 손실 | 0% | < 0.01% |
장애 복구율 | 100% | > 95% |
apiVersion: apps/v1
kind: Deployment
metadata:
name: triton-inference-server
namespace: ai-platform
spec:
replicas: 2
selector:
matchLabels:
app: triton-server
template:
metadata:
labels:
app: triton-server
spec:
nodeSelector:
accelerator: nvidia
runtimeClassName: nvidia
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:23.05-py3
command:
- tritonserver
- --model-repository=/models
- --backend-config=tensorflow,version=2
- --backend-config=python,shm-default-byte-size=134217728
ports:
- containerPort: 8000
name: http
- containerPort: 8001
name: grpc
resources:
limits:
nvidia.com/gpu: 1
memory: 8Gi
cpu: 4
requests:
nvidia.com/gpu: 1
memory: 4Gi
cpu: 2
volumeMounts:
- name: model-repository
mountPath: /models
- name: shared-memory
mountPath: /dev/shm
volumes:
- name: model-repository
persistentVolumeClaim:
claimName: model-storage-pvc
- name: shared-memory
emptyDir:
medium: Memory
sizeLimit: 2Gi
#!/bin/bash
# manage-all.sh - 전체 시스템 관리
case "$1" in
install)
echo "🚀 AI/ML 플랫폼 설치 시작..."
kubectl apply -f namespaces/
kubectl apply -f storage/
kubectl apply -f database/
kubectl apply -f cache/
kubectl apply -f ai-services/
echo "✅ 설치 완료"
;;
status)
echo "📊 시스템 상태 확인"
kubectl get nodes
kubectl get pods --all-namespaces | grep -E "gpu|triton|grnd"
kubectl top nodes
nvidia-smi
;;
backup)
BACKUP_DIR="/backup/$(date +%Y%m%d_%H%M%S)"
echo "💾 백업 시작: $BACKUP_DIR"
kubectl get all --all-namespaces -o yaml > $BACKUP_DIR/k8s-resources.yaml
kubectl exec -n database mariadb-master-0 -- mysqldump --all-databases > $BACKUP_DIR/db-backup.sql
;;
*)
echo "Usage: $0 {install|uninstall|status|backup|restart}"
exit 1
;;
esac
문제: 2중화 구성시 투표 방식의 Master 선출이 불가능 (과반수 미달)
원인: MaxScale의 모니터링 모듈이 과반수 투표 방식으로 Master를 선발하는데, 2개 노드에서는 Split Brain 발생
해결:
# 3중화 구성으로 전환
- Master Node: 1개
- Slave Nodes: 2개
- MaxScale Monitor: 과반수(2/3) 투표로 안정적 Master 선출
성과:
문제: Python gRPC 라이브러리가 CoreDNS 설정을 무시하고 외부 DNS 질의 시도
원인: gRPC의 기본 DNS resolver가 c-ares를 사용하여 시스템 DNS 설정 우회
해결:
# gRPC 환경변수 설정으로 native resolver 사용
import os
os.environ['GRPC_DNS_RESOLVER'] = 'native'
# 또는 channel 생성시 옵션 지정
channel_options = [
('grpc.dns_resolver', 'native'),
]
channel = grpc.insecure_channel(target, options=channel_options)
결과:
문제: 3중화 클러스터에서 replication=2 설정시 노드 장애시 쓰기 불가
원인:
# SeaweedFS Master 설정 변경
weed master -defaultReplication="001" # 1개 복제본으로 변경
# Format: xyz where x=다른 데이터센터, y=다른 랙, z=같은 랙 다른 서버
# 실제 운영 설정
- replication: "001" # 같은 랙의 다른 서버 1대에만 복제
- minFreeSpacePercent: 10
- volumeSizeLimitMB: 30000
개선 효과:
문제: CoreDNS가 외부 DNS 서버 접근 시도로 타임아웃 발생
해결:
# CoreDNS ConfigMap 수정
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
data:
Corefile: |
cluster.local {
forward . /etc/resolv.conf {
except cluster.local
}
}
오프라인 환경의 도전
GPU 자원 관리
고가용성 설계
관찰성 강화
보안 강화
Container Orchestration:
- Kubernetes: v1.28
- containerd: v1.7
- CNI: Flannel v0.22
GPU Computing:
- CUDA: 11.8
- cuDNN: 8.6
- TensorRT: 8.5
- Triton Server: 23.05
Data Management:
- MariaDB: 10.11
- MaxScale: 23.08
- Redis: 7.0
- SeaweedFS: 3.55
Monitoring & Logging:
- Fluent Bit: 2.1
- Kubernetes Metrics Server: 0.6
- Custom Health Checks
Development Tools:
- Helm: 3.12
- Kustomize: 5.0
- GitOps: ArgoCD Ready