多租户资源与事故响应
한국어 원문으로 표시합니다.
목표
세 테넌트를 만들어 쿼터와 LimitRange 로 자원을 나누고, 오버커밋 비율을 직접 계산해 기록하고, 스케줄링 사고를 재현해 숫자로 분류한 뒤 요구사항을 지우지 않고 복구하고, 플랫폼 자신의 기록 규칙과 알림을 만들어 클러스터에 올립니다.
왜 중요한가
여기서 연습하는 것은 도구 조작뿐 아니라 증거에 따른 판단입니다. 사고가 났을 때 무엇부터 세는지, 그 값을 어디에 적는지, 그리고 무엇을 복구라고 부를 것인지가 그 순서입니다.
특히 마지막 항목이 중요합니다. 제약을 지워서 파드를 뜨게 하는 것과 제약을 만족시켜 뜨게 하는 것은 화면에서 구별되지 않습니다. 둘 다 Running 이고 둘 다 알림이 꺼집니다. 구별하는 것은 사람이고, 그 판단을 손에 익히는 것이 이 실습의 목적입니다.
이 클러스터의 노드는 세 대이고 각각 8 코어입니다. 그래서 클러스터 전체의 allocatable CPU 는 24 코어입니다. 쿼터 합계를 이 값으로 나눈 것이 오버커밋 비율입니다.
이 환경은 실제 API 서버·스케줄러와 KWOK 가상 노드를 사용합니다. Running은 스케줄링 상태를 배우기 위한 것이며 GPU나 ledger 프로세스가 실제 실행됐다는 증거는 아닙니다. Prometheus Operator·Alertmanager는 실행하지 않습니다. 마지막 두 단계의 PromQL은 이미지에 포함된 promtool 3.0.1로 실제 평가하고, CR은 API 저장 내용까지 검증합니다.
작업 디렉터리는 /root/cnpe-ops 입니다. 시계열 시험은 가상 시간을 사용하므로 실제로 25분 기다리지 않습니다. 각 채점은 45초 내 검사하며 학생 파일이나 API 객체를 수정하지 않습니다.
단계
- 네임스페이스
tenant-red,tenant-green,tenant-gold를 만들고 각각에platform.labhub.io/tenant라벨을 붙입니다. 값은 이름에서tenant-를 뗀 것입니다. 그다음/root/cnpe-ops/inventory.txt에tenants와tenant_list두 줄을 적습니다. 목록은 이름순으로 쉼표만 넣어 잇습니다. /root/cnpe-ops/quotas.yaml에 세 테넌트의 ResourceQuota 를 씁니다. 이름은 각각tenant-red-quota처럼 네임스페이스 이름에-quota를 붙인 것이고,requests.cpu를 반드시 넣습니다. 세 쿼터의requests.cpu합계를 24 로 나눈 값이 1.00 초과 1.25 이하가 되게 하고, 어느 테넌트도 6 코어 아래로 내리지 않습니다. 그다음/root/cnpe-ops/capacity.txt에quota_cpu,allocatable_cpu,overcommit세 줄을 적습니다./root/cnpe-ops/limitranges.yaml에 세 테넌트의 LimitRange 를 씁니다. 이름은tenant-red-limits처럼 짓습니다.defaultRequest와default를 모두 두되defaultRequest의 CPU 가default의 CPU 보다 낮아야 하고,max로 컨테이너 한 개가 CPU 4 코어를 요구하지 못하게 막습니다./root/cnpe-ops/ledger.yaml에 Deploymentledger를 써서tenant-red에 적용합니다. replicas 는 3, 파드 라벨은app=ledger,nodeSelector는platform.labhub.io/pool=gpu하나이며, 컨테이너 요청은 CPU 500m 과 메모리 512Mi 이고 이미지는 다이제스트로 고정합니다. 이 시점에 파드는 뜨지 못합니다./root/cnpe-ops/triage.txt에selector_key,selector_value,replicas,required_cpu네 줄을 적습니다.required_cpu는 컨테이너 요청에 레플리카 수를 곱한 값을 밀리코어로 적습니다.- 노드 한 대에만
platform.labhub.io/pool=gpu라벨을 붙여 복구합니다. Deployment 의nodeSelector와 replicas 는 그대로 두어야 합니다. 파드 세 개가 모두 Running 이 될 때까지 확인합니다. /root/cnpe-ops/platform-rules.yaml에 그룹platform-slo와interval: 1m을 둡니다. 기록 규칙platform:provision_success:ratio5m은 최근 5분의 성공 요청 rate 합 / 전체 요청 rate 합입니다. 계열별 rate 후 합산하고, 실패 계열만 있으면 0%, 성공 계열만 있으면 100%, 무트래픽·관측 없음에는 비율 계열을 내지 않습니다.PlatformProvisionFailing은 이 비율이 95% 미만인 상태가 10분 지속될 때 발화하며 회복하면 해제합니다.severity: critical, 의미 있는summary,runbook_url을 둡니다. 문법 검사 후python3 /opt/fixtures/cnpe_slo_contract.py rules로 13개 시계열 사건을 통과시키세요. 95%는 이 실습의 임계값이지 운영 권장 SLO가 아닙니다.- 네임스페이스
monitoring을 만들고/root/cnpe-ops/platform-rules-cr.yaml에 PrometheusRuleplatform-slo를 써서 적용합니다. 규칙 파일·매니페스트의 spec.groups·API의 spec.groups 전체가 일치해야 합니다./root/cnpe-ops/ops-report.txt에 중복 없이tenants,pool_nodes,ledger_running,alert_rules네 줄을 조회한 정수로 기록합니다. 이 실습의 목표는 각각 3, 1, 3, 실제 알림 규칙 수입니다.python3 /opt/fixtures/cnpe_slo_contract.py deploy로 확인하세요. API 저장 성공은 운영 Prometheus의 규칙 로드나 알림 전달 성공을 뜻하지 않습니다.
참고
- 라벨로 센 값이 곧 플랫폼이 스스로 아는 값입니다.
kubectl get ns -l platform.labhub.io/tenant로 세십시오. - 노드의 allocatable 은
kubectl get nodes -o json | jq '[.items[].status.allocatable.cpu | tonumber] | add'로 다시 셀 수 있습니다. - LimitRange 가 실제로 무엇을 채우는지 보려면 요청을 비운 파드를
--dry-run=server로 넣어 보고 결과를 읽는 것이 가장 확실합니다. - 라벨을 붙인 뒤에는 스케줄러가 한 바퀴 돌 시간을 주십시오. 즉시 확인하고 판단하면 옳은 조치를 되돌리게 됩니다.
- 흔한 실수 하나는 파드를 뜨게 하려고
nodeSelector를 지우는 것입니다. 그것은 복구가 아니라 요구사항 삭제입니다. - 또 하나는 검증한 규칙 파일과 다른 내용을 PrometheusRule 로 올리는 것입니다. 그러면 promtool 통과가 아무것도 보장하지 않게 됩니다.
- Prometheus 규칙 단위 시험과 알림 규칙을 읽으세요. 문법과 발화 동작은 별개입니다.
- runbook.example.invalid는 형식 설명용 주소입니다. 운영에서는 실제 담당자·진단·복구 절차가 있는 문서로 바꾸어야 합니다.
테넌트를 기계가 셀 수 있게 만들기
네임스페이스 tenant-red, tenant-green, tenant-gold 를 만들고 각각에 platform.labhub.io/tenant 라벨을 붙입니다. 값은 이름에서 tenant- 를 뗀 것입니다. 그다음 /root/cnpe-ops/inventory.txt 에 tenants 와 tenant_list 두 줄을 적습니다. 목록은 이름순으로 쉼표만 넣어 잇습니다.
이름 규칙만 있고 라벨이 없으면 테넌트 목록은 사람의 기억 속에만 있습니다. 라벨을 붙인 뒤 라벨 선택자로 다시 세어 보고, 그 결과를 적으십시오.
약속한 양과 실제로 가진 양을 나눠 보기
/root/cnpe-ops/quotas.yaml 에 세 테넌트의 ResourceQuota 를 씁니다. 이름은 각각 tenant-red-quota 처럼 네임스페이스 이름에 -quota 를 붙인 것이고, requests.cpu 를 반드시 넣습니다. 세 쿼터의 requests.cpu 합계를 24 로 나눈 값이 1.00 초과 1.25 이하가 되게 하고, 어느 테넌트도 6 코어 아래로 내리지 않습니다. 그다음 /root/cnpe-ops/capacity.txt 에 quota_cpu, allocatable_cpu, overcommit 세 줄을 적습니다.
쿼터는 네임스페이스마다 독립적으로 걸리고 클러스터 용량을 참조하지 않습니다. 그래서 합계를 사람이 따로 세어야 합니다. 노드 세 대가 각각 8 코어이니 분모는 24 입니다.
안 적은 사람에게 채워 줄 값 정하기
/root/cnpe-ops/limitranges.yaml 에 세 테넌트의 LimitRange 를 씁니다. 이름은 tenant-red-limits 처럼 짓습니다. defaultRequest 와 default 를 모두 두되 defaultRequest 의 CPU 가 default 의 CPU 보다 낮아야 하고, max 로 컨테이너 한 개가 CPU 4 코어를 요구하지 못하게 막습니다.
default는 limit, defaultRequest는 request의 기본값입니다. 이미 선언한 request를 기본값으로 덮지 않습니다. 이 과제에서는 CPU 기본 request를 limit보다 작게 두어 예약량을 구분합니다. Guaranteed 여부는 모든 컨테이너의 CPU·메모리 조건을 함께 확인해야 합니다. max는 컨테이너별 상한입니다.
사고를 재현해 두기
/root/cnpe-ops/ledger.yaml 에 Deployment ledger 를 써서 tenant-red 에 적용합니다. replicas 는 3, 파드 라벨은 app=ledger, nodeSelector 는 platform.labhub.io/pool=gpu 하나이며, 컨테이너 요청은 CPU 500m 과 메모리 512Mi 이고 이미지는 다이제스트로 고정합니다. 이 시점에 파드는 뜨지 못합니다.
지금 이 노드들에는 풀 라벨이 없습니다. 그래서 이 워크로드는 뜨지 못합니다. 그 상태가 이 단계의 정상입니다. 파드의 현재 상태가 아니라 무엇을 요구하는 워크로드인지가 채점 대상입니다.
분류의 결과를 숫자로 적기
/root/cnpe-ops/triage.txt 에 selector_key, selector_value, replicas, required_cpu 네 줄을 적습니다. required_cpu 는 컨테이너 요청에 레플리카 수를 곱한 값을 밀리코어로 적습니다.
느낌이 아니라 네 개의 숫자를 적습니다. 필요한 총 CPU 는 컨테이너 요청에 레플리카 수를 곱한 값이고 밀리코어로 적습니다. 값은 클러스터에서 직접 읽어 오십시오.
제약을 지우지 않고 복구하기
노드 한 대에만 platform.labhub.io/pool=gpu 라벨을 붙여 복구합니다. Deployment 의 nodeSelector 와 replicas 는 그대로 두어야 합니다. 파드 세 개가 모두 Running 이 될 때까지 확인합니다.
선택자를 지우면 즉시 뜨지만 그것은 복구가 아니라 요구사항 삭제입니다. 노드 쪽을 고쳐 제약을 만족시키십시오. 그리고 필요한 만큼만 넣습니다. 두 대에 붙이면 그 풀의 뜻이 흐려집니다.
플랫폼 자신의 기록 규칙과 알림 쓰기
/root/cnpe-ops/platform-rules.yaml에 그룹 platform-slo와 interval: 1m을 둡니다. 기록 규칙 platform:provision_success:ratio5m은 최근 5분의 성공 요청 rate 합 / 전체 요청 rate 합입니다. 계열별 rate 후 합산하고, 실패 계열만 있으면 0%, 성공 계열만 있으면 100%, 무트래픽·관측 없음에는 비율 계열을 내지 않습니다. PlatformProvisionFailing은 이 비율이 95% 미만인 상태가 10분 지속될 때 발화하며 회복하면 해제합니다. severity: critical, 의미 있는 summary, runbook_url을 둡니다. 문법 검사 후 python3 /opt/fixtures/cnpe_slo_contract.py rules로 13개 시계열 사건을 통과시키세요. 95%는 이 실습의 임계값이지 운영 권장 SLO가 아닙니다.
값 0인 벡터도 알림을 활성화합니다. bool 비교를 알림에 바로 쓰면 정상 시에도 계열이 남습니다. 실패만 있는 경우의 빈 분자와, 전체 트래픽이 없는 분모를 구별하세요. 실패 메시지의 가상 사건·시점을 먼저 읽고 수식과 for를 점검합니다.
검증한 규칙을 올리고 현재 상태를 기록하기
네임스페이스 monitoring을 만들고 /root/cnpe-ops/platform-rules-cr.yaml에 PrometheusRule platform-slo를 써서 적용합니다. 규칙 파일·매니페스트의 spec.groups·API의 spec.groups 전체가 일치해야 합니다. /root/cnpe-ops/ops-report.txt에 중복 없이 tenants, pool_nodes, ledger_running, alert_rules 네 줄을 조회한 정수로 기록합니다. 이 실습의 목표는 각각 3, 1, 3, 실제 알림 규칙 수입니다. python3 /opt/fixtures/cnpe_slo_contract.py deploy로 확인하세요. API 저장 성공은 운영 Prometheus의 규칙 로드나 알림 전달 성공을 뜻하지 않습니다.
그룹 이름만 같고 식·임계값·for가 다르면 같은 규칙이 아닙니다. 검증 파일을 그대로 CR로 감싼 뒤 API의 spec.groups 전체를 비교하세요. 조회 실패를 0으로 기록하지 않고 먼저 API 오류를 해결합니다.