GPU Operator 와 타임슬라이싱 · GPU 를 클러스터에 붙인다는 것 · 이론
왜 GPU Operator 가 생겼나
한 줄 요약
GPU Operator 는 GPU 를 빠르게 해 주는 물건이 아니다. 노드마다 손으로 하던 대여섯 가지 설치를 클러스터 오브젝트 한 장으로 옮긴 것이고, 그 편의의 대가로 노드의 컨테이너 런타임 설정을 오퍼레이터가 대신 고치게 된다.
왜 이게 필요했나
GPU 노드 한 대를 "쓸 수 있는 상태"로 만드는 절차는 예전에 이랬다.
1. 커널 헤더를 맞춰 깔고 드라이버를 빌드해 올린다. 실패하면 커널 버전부터 다시 본다.
2. nvidia-container-toolkit 을 깐다.
3. containerd 설정에 nvidia 런타임 핸들러를 등록한다.
4. containerd 를 재시작한다.
5. nvidia-device-plugin 을 올려 GPU 를 자원으로 광고하게 한다.
6. dcgm-exporter 를 올려 사용률을 긁는다.
노드 한 대에 30분이 걸리고, 일곱 대면 하루가 간다. 문제는 시간이 아니라 드리프트다. 3월에 만든 노드는 드라이버 535, 8월에 추가한 노드는 550. 커널 자동 업데이트가 돌면 그 노드만 드라이버가 깨진다. 사람이 반복하는 절차는 반드시 갈라지고, 갈라진 클러스터는 "왜 저 노드에서만 안 되지" 라는 질문을 매주 만든다.
GPU Operator 는 이 절차를 통째로 원하는 상태 선언으로 바꾼다. ClusterPolicy 라는 커스텀 리소스 한 장을 적으면 오퍼레이터가 필요한 데몬셋들을 세우고, 노드가 새로 들어오면 알아서 같은 절차를 밟는다. 노드를 다시 만들어도 결과가 같다는 것 — 그것이 이 오퍼레이터가 파는 유일한 상품이다.
어떻게 동작하나
ClusterPolicy 하나 아래에 데몬셋이 여럿 선다. 각각이 위 절차의 한 단계를 맡는다.
| 데몬셋 | 하는 일 | 없으면 생기는 증상 |
| --- | --- | --- |
| nvidia-driver-daemonset | 드라이버를 컨테이너 안에서 빌드·적재 | nvidia-smi 자체가 없음 |
| nvidia-container-toolkit-daemonset | 노드의 containerd 설정에 런타임 핸들러 등록 | 파드가 RuntimeHandler 오류로 생성 실패 |
| nvidia-device-plugin-daemonset | 노드 status 에 nvidia.com/gpu 광고 | 파드가 영영 Pending |
| gpu-feature-discovery | GPU 모델·메모리를 노드 라벨로 | 스케줄링 조건을 라벨로 못 씀 |
| nvidia-dcgm-exporter | 사용률·온도·ECC 지표 노출 | 누가 GPU 를 쥐고 있는지 모름 |
여기에 순서 의존이 있다. 드라이버가 준비되기 전에 toolkit 이 뜨면 아무 의미가 없고, toolkit 이 런타임을 등록하기 전에 device plugin 이 GPU 를 광고하면 스케줄러는 파드를 보내는데 노드는 그 파드를 못 만든다. 그래서 오퍼레이터는 노드 라벨(nvidia.com/gpu.deploy.*)로 단계를 게이팅한다. 사람이 순서를 기억하지 않아도 되게 만든 장치다.
그리고 여기서 반드시 붙잡아 둘 사실이 하나 있다. 2번 데몬셋은 노드의 /etc/containerd/ 를 직접 고친다. 클러스터 안의 오브젝트를 만드는 것이 아니라 호스트 파일시스템을 쓴다. 이 코스의 나머지 절반은 전부 그 한 문장에서 나온 이야기다.
현장에서 만나는 모습
첫째, 드라이버는 대개 노드에 미리 깐다. driver.enabled=false 로 두고 OS 이미지에 드라이버를 구워 두는 조직이 많다. 컨테이너 안에서 드라이버를 빌드하는 방식은 커널이 올라갈 때마다 노드가 몇 분씩 GPU 없이 도는 구간을 만들고, 폐쇄망에서는 헤더 패키지를 받는 것부터 막힌다. 그러면 GPU Operator 가 하는 일은 실질적으로 "toolkit + device plugin + 지표" 세 가지로 줄어든다.
둘째, 버전 매트릭스가 진짜 제약이다. 드라이버 · CUDA · toolkit · 오퍼레이터 · 쿠버네티스가 서로 지원 범위를 갖는다. 오퍼레이터를 올리는 일은 그 다섯 개를 한꺼번에 움직이는 일이라, 다른 업그레이드와 같은 창에 넣으면 원인을 못 가른다.
셋째, 감사 관점에서 이 오퍼레이터는 특권 소프트웨어다. 노드의 파일시스템을 쓰고, 호스트 PID 네임스페이스를 보고, 커널 모듈을 적재한다. "쿠버네티스 위에 뜬 파드니까 격리돼 있다" 는 직관이 여기서는 통하지 않는다. 설치를 승인할 때 이 사실을 문서에 남겨 두지 않으면 나중에 반드시 문제가 된다.
이어지는 글에서 볼 것
바로 뒤 글에서는 ClusterPolicy 아래의 데몬셋들이 RuntimeClass 와 nvidia.com/gpu 자원으로 어떻게 이어지는지를 본다. 이 두 갈래는 전혀 다른 관문이고, 둘을 헷갈리면 "파드가 Pending 인데 원인을 못 찾는" 상태에 그대로 빠진다.