GPU Operator 와 타임슬라이싱 · GPU 를 클러스터에 붙인다는 것 · 실습
자원 관문 — 광고·요청 규칙·테인트로 갈리는 Pending
목표
GPU 파드가 통과해야 하는 두 관문 중 자원 쪽을 끝까지 밟아 봅니다. 노드가
자원을 광고하게 만들고, 확장 자원의 요청 규칙 두 가지가 실제로 막는 것을 보고,
같은 Pending 이라도 원인이 테인트인지 자원인지 갈라 읽는 데까지 갑니다.
왜 중요한가
"GPU 파드가 안 뜬다" 는 신고에서 첫 3분에 갈래를 정하지 못하면 몇 시간을
잘못된 곳에서 씁니다. 파드가 노드에 배정조차 안 됐다면 그것은 스케줄러 단계이고,
스케줄러가 보는 것은 장치가 아니라 노드 status 에 적힌 숫자입니다. 그 숫자를
적어 주는 것이 device plugin 이고, 그 숫자가 없으면 장치가 멀쩡히 꽂혀 있어도
파드는 영영 대기합니다.
확장 자원에는 규칙이 둘 더 있습니다. requests 와 limits 가 같아야 하고 값이
정수여야 합니다. 오버커밋이 불가능하고 장치를 쪼갤 수 없기 때문입니다. 두 규칙
모두 apiserver 가 검사하므로 어기면 파드가 아예 만들어지지 않습니다. 마지막으로
GPU 노드에는 대개 테인트가 붙어 있어서, 자원이 남아돌아도 톨러레이션이 없으면
스케줄되지 않습니다. 이 셋이 자원 관문의 전부입니다.
환경
이 파드에는 GPU 도 device plugin 도 없습니다. 대신 kwok 이 띄운 **진짜
컨트롤 플레인**이 있어서, 노드 status 에 숫자를 적으면 진짜 스케줄러가 그것을
보고 판정합니다. 확장 자원의 검증도 진짜 apiserver 가 합니다. 작업 디렉터리는/root/gpuwhy 이고, 매니페스트는 k8s/ 에 산출물은 out/ 에 둡니다.
단계
1. gpu-why 네임스페이스를 만들고 lab-node-0 에 발견 라벨 넷을 붙입니다.
2. 그 노드의 status 에 nvidia.com/gpu: 2 를 광고하고 out/advertised.txt 에 저장합니다.
3. 규칙을 어긴 매니페스트 둘을 만들어 거절 메시지를 out/rejected.txt 에 저장합니다.
4. trainer 파드를 조건 없이 만들어 자원만으로 노드가 정해지는 것을 봅니다.
5. 노드에 테인트를 걸고 cpu-only 가 대기하는 이유를 out/tainted.txt 에 저장합니다.
6. 톨러레이션을 붙인 trainer2 로 두 관문을 함께 통과합니다.
7. trainer3 로 자리를 넘겨 대기 이유가 자원으로 바뀌는 것을 out/exhausted.txt 에 저장합니다.
8. out/gate-report.txt 에 일곱 줄로 정리합니다.
참고
- status 는 하위 리소스입니다.
kubectl patch node <이름> --subresource=status를 capacity만 적고allocatable을 빠뜨리면 스케줄러가 쓸 자리가 생기지 않습니다.- 5단계와 7단계는 둘 다 Pending 입니다. 두 파일을 나란히 놓고 메시지가 어떻게
- 테인트를 지워서 통과시키지 마세요. GPU 노드를 예약해 둔 이유가 사라집니다.
쓰고, JSON 포인터에서 슬래시는 ~1 로 이스케이프합니다.
흔한 실수라 3단계 뒤에도 파드가 계속 대기하면 여기를 먼저 보세요.
다른지 비교해 보세요. 그 차이가 곧 다음에 볼 곳을 정합니다.
단계 8개
- GPU 노드에 발견 라벨을 붙인다
- 노드 status 에 확장 자원을 광고한다
- 확장 자원의 두 규칙이 막는 것을 확인한다
- 조건을 주지 않아도 자원이 노드를 정한다
- 자원이 남아도 테인트가 막는다
- 톨러레이션을 붙여 두 관문을 함께 통과한다
- 자리가 다 차면 같은 파드도 대기한다
- 관문을 숫자와 한 단어로 정리한다