26S03b

Young-Kyoo Kim·3일 전

Kubernetes 리소스 단위(코어 m, 메모리 Gi/Mi/Ki)를 정규화한 뒤, (Request / Limit) * 100을 계산하여 반올림한 비율별로 카운트하는 스크립트입니다.

Bash와 Python(추천, 부동소수점 및 단위 변환 처리가 안정적) 중 환경에 맞는 방식을 선택해 실행할 수 있습니다.


Python 인라인 스크립트 (가장 정확하고 편리한 방식)

kubectl 출력을 받아 밀리코어(m) 단위로 자동 정규화한 뒤, 반올림된 비율(50%, 40%, 30%, 기타)을 집계합니다.

kubectl get pods -A -o json | python3 -c '
import sys, json

KEYWORD = "YOUR_POD_NAME_KEYWORD"  # 필터링할 Pod 이름 키워드

def parse_cpu(val):
    if not val:
        return 0.0
    val = str(val).strip()
    if val.endswith("m"):
        return float(val[:-1])
    return float(val) * 1000.0

counts = {
    "50% (round=50)": 0,
    "40% (round=40)": 0,
    "30% (round=30)": 0,
    "Others": 0
}

data = json.load(sys.stdin)
for pod in data.get("items", []):
    pod_name = pod.get("metadata", {}).get("name", "")
    if KEYWORD not in pod_name:
        continue
    
    for c in pod.get("spec", {}).get("containers", []):
        res = c.get("resources", {})
        req_cpu = parse_cpu(res.get("requests", {}).get("cpu"))
        lim_cpu = parse_cpu(res.get("limits", {}).get("cpu"))
        
        if lim_cpu > 0:
            ratio = (req_cpu / lim_cpu) * 100
            rounded = round(ratio)
            
            if rounded == 50:
                counts["50% (round=50)"] += 1
            elif rounded == 40:
                counts["40% (round=40)"] += 1
            elif rounded == 30:
                counts["30% (round=30)"] += 1
            else:
                counts["Others"] += 1

print(json.dumps(counts, indent=2))
'

jq 기반 스크립트 (외부 런타임 없이 bash/jq만 사용할 때)

순수 jq로만 처리하려면 아래 명령어를 사용합니다.

kubectl get pods -A -o json | jq -r --arg kw "YOUR_POD_NAME_KEYWORD" '
  def parse_cpu:
    if . == null or . == "" then 0
    elif endswith("m") then (.[0:-1] | tonumber)
    else ((. | tonumber) * 1000)
    end;

  [
    .items[]
    | select(.metadata.name | contains($kw))
    | .spec.containers[]
    | {
        req: (.resources.requests.cpu | parse_cpu),
        lim: (.resources.limits.cpu | parse_cpu)
      }
    | select(.lim > 0)
    | ((.req / .lim) * 100 | round)
  ]
  | {
      "50% (round=50)": (map(select(. == 50)) | length),
      "40% (round=40)": (map(select(. == 40)) | length),
      "30% (round=30)": (map(select(. == 30)) | length),
      "Others": (map(select(. != 50 and . != 40 and . != 30)) | length)
    }
'

동작 세부 내용

  • 반올림 기준: round((req / lim) * 100)을 적용하므로 예를 들어 40%는 35.0% ~ 44.9% 범위, 30%는 25.0% ~ 34.9% 범위가 매칭됩니다. (3/8 = 37.5%는 38%이므로 Others로 빠지며, 3/8을 40%로 보고 싶다면 반올림 자리수 조정이 필요합니다.)
  • 메모리 집계로 변경 시: parse_cpu 함수 대신 Mi/Gi 단위를 바이트 단위로 환산하는 로직으로 변경하여 동일하게 적용할 수 있습니다.

0개의 댓글