GPU Operator 와 타임슬라이싱 · 런타임 등록이 조용히 실패하는 자리 · 실습
런타임 관문 — 검증되지 않는 문자열과 로드된 것의 대조
목표
런타임 관문의 양쪽을 함께 다룹니다. 클러스터 쪽에서는 RuntimeClass 가 무엇을
고르고 무엇을 검증하지 않는지 보고, 노드 쪽에서는 설정이 조용히 무시되는 두 가지
경우를 만들어 봅니다. 마지막에는 그 둘을 대조하는 점검기를 직접 만듭니다.
왜 중요한가
파드가 노드에는 붙었는데 컨테이너 생성에서 죽는다면 그것은 런타임 쪽입니다.RuntimeClass 의 handler 는 그냥 문자열이고 **apiserver 는 그것을 검증하지
않습니다.** 노드마다 containerd 설정이 다를 수 있어 검증할 주체가 애초에
없기 때문입니다. 그래서 오타는 적용도 되고 스케줄도 되고, 그 노드가 컨테이너를
만드는 순간에만 드러납니다.
노드 쪽에는 조용한 실패가 둘 더 있습니다. imports 글롭이 파일 이름과 어긋나면
containerd 는 아무 말 없이 지나가고, 설정 버전이 3 으로 올라가면 플러그인 이름
자체가 바뀌어 옛 이름으로 적은 설정이 통째로 무시됩니다. 두 경우 모두 **파일에는
원하는 내용이 그대로 적혀 있습니다.** 그래서 점검은 파일이 아니라 로드된 설정을
봐야 하고, 그 판정을 클러스터의 RuntimeClass 목록과 맞춰 봐야 비로소 쓸모가
있습니다. 이 실습의 마지막 산출물이 그 점검기입니다.
환경
이 파드에는 진짜 containerd 가 없습니다. 그래서 설정은 TOML 파서로 다루고,
점검기는 dump 를 인자로 받을 수 있게 만들어 채점기가 두 가지 dump 로 실제로
돌려 봅니다. 클러스터 쪽은 kwok 이 띄운 진짜 apiserver 와 스케줄러라
RuntimeClass 등록도 오버헤드 계산도 진짜입니다. 작업 디렉터리는 /root/gpurt
이고 그 아래 k8s/·etc/·bin/·fixtures/·out/ 을 씁니다.
단계
1. gpu-rt 네임스페이스와 RuntimeClass 두 개를 만듭니다.
2. 오타 난 handler 로도 파드가 스케줄되는 것을 보고 out/unvalidated.txt 에 적습니다.
3. cpu 1짜리 노드 두 대를 만들고 RuntimeClass 오버헤드로 결과가 갈리는 것을 봅니다.
4. 드롭인을 못 잡는 imports 글롭을 만들고 out/imports.txt 에 적습니다.
5. 같은 설정을 버전 3 형식으로 etc/config-v3.toml 에 다시 씁니다.
6. bin/rc-crosscheck.sh 로 클러스터와 dump 를 대조하는 점검기를 만듭니다.
7. 기본 런타임을 바꾸는 드롭인을 만들고 out/blast.txt 에 폭발 반경을 적습니다.
8. 일부만 로드된 dump 를 본떠 점검기를 물리고 out/crosscheck.txt 에 저장합니다.
참고
- TOML 은 들여쓰기가 아니라 테이블 이름으로 계층을 만듭니다. 눈으로는 멀쩡해
- 6단계의 점검기가
/etc/containerd/config.toml을 읽으면 채점기가 거절합니다. - 3단계에서 두 노드를 따로 두는 이유가 있습니다. 한 노드에 두면 먼저 들어간
보여도 엉뚱한 곳에 붙는 일이 잦으니 파서로 한 번 읽어 확인하세요.
이 사고는 파일과 로드된 것이 갈라지는 자리에서 나기 때문입니다.
파드가 자리를 먹어 오버헤드의 효과가 가려집니다.
단계 8개
- 핸들러를 고르는 오브젝트를 만든다
- 오타 난 핸들러도 apiserver 를 통과한다
- RuntimeClass 의 오버헤드가 스케줄링을 바꾼다
- imports 글롭이 어긋나면 조용히 지나간다
- containerd 2.x 의 설정 버전 3 으로 다시 쓴다
- 클러스터가 요구하는 핸들러와 로드된 것을 대조한다
- 기본 런타임을 바꾸면 폭발 반경이 달라진다
- 만든 점검기를 실제 dump 에 물려 본다