노드 수가 수백~천 대 단위로 커지는 대규모 에어갭 환경에서는 스크립트를 서버마다 수동 복사하거나 ssh 루프로 돌리는 방식은 금방 버전 파편화와 관리 부채로 이어집니다.
검증 주체와 권한 범위에 따라 노드 레벨(호스트 OS/하드웨어)과 파드 레벨(워크로드/K8s 관점)을 명확히 분리하고, 형상 관리(Git)부터 자동 실행 파이프라인까지 단일 체계로 묶는 아키텍처를 권장합니다.
| 구분 | 노드 레벨 점검 (Node-level) | 파드 레벨 점검 (Pod-level) |
|---|---|---|
| 점검 주체 | 베어메탈 OS, 커널, 물리 하드웨어 | K8s 워크로드, 네임스페이스 격리, Egress 통신 |
| 수행 대상 | • HW 무결성 (ECC, NVMe SMART, NIC 링 버퍼) |
• OS 커널 튜닝 (sysctl, conntrack, swap)
• NUMA 바인딩 및 하드웨어 토폴로지
• GPU 드라이버/Fabric Manager 데몬 상태 | • vLLM/LLM 서빙 API 지연(TTFT, TPS)
• CNI 통신 (Pod-to-Pod, Pod-to-MinIO 대역폭)
• Cgroup CPU Throttling 발생 여부
• PVC 마운트 I/O 레이턴시 |
| 실행 타이밍 | • 노드 신규 인수/프로비저닝 시점 (1회성)
• 정기 점검 또는 OS/펌웨어 패치 직후 | • 노드가 Ready 상태로 조인된 직후
• CronJob 기반 상시 주기적(Daily/Weekly) 검증 |
| 권한 수준 | Root, Host Namespace, 물리 장치 직접 접근 | K8s ServiceAccount, Cgroup 읽기 권한 |
호스트 OS에서 돌아야 하는 점검 스크립트(acceptance_test.sh, check_bottlenecks.sh, check_numa_efficiency.sh)는 OS 패키지(RPM)로 형상화하여 배포하는 것이 가장 깔끔합니다.
node-diagnostics/bin/*.shv1.2.0)를 기반으로 사내 CI에서 node-diagnostics-1.2.0.rpm 빌드.dnf install -y node-diagnostics 한 번으로 /usr/local/bin/에 표준화된 경로로 배포.# 운영 중 노드 일괄 점검을 위한 일회성 DaemonSet 예시
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-diagnostics-runner
namespace: kube-system
spec:
selector:
matchLabels:
app: node-diagnostics-runner
template:
metadata:
labels:
app: node-diagnostics-runner
spec:
hostPID: true
hostNetwork: true
containers:
- name: checker
image: nexus.internal:8082/infra/node-diagnostics:v1.2.0
securityContext:
privileged: true
command: ["/bin/bash", "-c"]
args:
- |
/usr/local/bin/check_bottlenecks.sh > /tmp/report.log
# 필요 시 사내 MinIO/S3로 리포트 자동 업로드
mc cp /tmp/report.log myminio/reports/$(hostname)_bottlenecks.log
sleep 3600
vLLM 추론 테스트(k6), MinIO I/O 검증, Cgroup 모니터링 등 파드 내부나 클러스터 네트워크 관점의 테스트는 스크립트를 이미지에 굽지 말고 ConfigMap으로 관리해야 변경이 빠릅니다.
vllm_test.js, locustfile.py, pod_network_test.sh)를 Git 저장소(cluster-health-check)에서 관리.ConfigMap으로 자동 배포.# 파드 관점 성능/네트워크 점검 Job 예시
apiVersion: batch/v1
kind: Job
metadata:
name: vllm-load-check
namespace: ai-validation
spec:
template:
spec:
restartPolicy: Never
containers:
- name: k6-runner
image: nexus.internal:8082/grafana/k6:latest
command: ["k6", "run", "/scripts/vllm_test.js"]
env:
- name: VLLM_URL
value: "http://vllm-service.ai-serving.svc.cluster.local:8000/v1/chat/completions"
volumeMounts:
- name: script-vol
mountPath: /scripts
volumes:
- name: script-vol
configMap:
name: k6-test-scripts
복잡하게 흩어진 스크립트들을 4단계 파이프라인으로 일원화하는 것을 권장합니다.
[Git 저장소 (단일 관리)]
│
├── node-scripts/ ──(사내 CI 빌드)──> node-diagnostics.rpm ──> 호스트 OS 설치 (Ansible)
│
└── pod-scripts/ ──(ArgoCD / Helm)──> K8s ConfigMap ──> K8s Job/CronJob 실행
│
▼
[결과 중앙화 (MinIO AIStor 버킷)]
s3://infra-reports/YYYY-MM-DD/
infra-diagnostics 단일 모노레포에 /node와 /cluster 디렉터리로 구분하여 커밋.mc cp <결과로그> s3://cluster-diagnostics-reports/$(date +%F)/$HOSTNAME.json을 넣어 점검 결과가 한곳(MinIO)으로 모이도록 표준화.[FAIL] 카운트가 1개 이상이면 슬랙/웹훅(또는 Prometheus Alertmanager)으로 알림을 쏘도록 래핑.이렇게 역할을 분리해 두면, 인프라 엔지니어는 OS 레벨 RPM만 최신으로 유지하고, 플랫폼/DevOps 엔지니어는 K8s Manifest(Job/ConfigMap)만 수정하면서 노드와 워크로드를 독립적이면서도 체계적으로 점검할 수 있습니다.