k8s-resource-check-v1.5.sh

진웅·2025년 7월 28일

K8S Basics

목록 보기
25/40

#!/bin/bash

================================================================

Kubernetes 노드 리소스 분석 스크립트 v1.5

================================================================

🎯 주요 기능:

• 노드별 CPU/메모리 할당 vs 요청량 vs 실제사용량 비교 분석

• 점유율(Request 기준)과 사용률(실제 사용량) 구분 표시

• 리소스 상태를 색상으로 시각화 (정상/주의/위험)

• CPU는 기가코어(G), 메모리는 기가바이트(Gi) 단위로 통일

• 테이블 형태로 깔끔한 정보 제공

• Pod별 리소스 소비량 상세 분석

• 스케줄링 실패 Pod 및 원인 파악

• kubectl top 기반 실제 사용률 통합 분석

🔍 사용 목적:

kubectl describe node로는 여유가 있어 보이지만 실제로는

Pod들의 resource request로 인해 스케줄링이 안 되는 문제 진단

+ 실제 CPU/메모리 사용률과의 비교 분석

📋 사용법:

chmod +x k8s-resource-check.sh

./k8s-resource-check.sh

📅 작성일: 2025-07-28

👤 버전: v1.5 - 점유율/사용률 구분 및 kubectl top 통합

================================================================

set -e

색상 정의 (더 다양하고 명확한 색상)

RED='\033[1;31m' # 빨간색 (굵게)
GREEN='\033[1;32m' # 초록색 (굵게)
YELLOW='\033[1;33m' # 노란색 (굵게)
BLUE='\033[1;34m' # 파란색 (굵게)
PURPLE='\033[1;35m' # 보라색 (굵게)
CYAN='\033[1;36m' # 시안색 (굵게)
WHITE='\033[1;37m' # 흰색 (굵게)
GRAY='\033[0;37m' # 회색
BOLD='\033[1m' # 굵게
NC='\033[0m' # 색상 초기화

헤더 출력 함수

print_header() {
local title="1"locallength=1" local length={#title}
local border=$(printf "%*s" $((length + 10)) | tr ' ' '=')

echo
echo -e "${CYAN}$border${NC}"
echo -e "${CYAN}     $title${NC}"
echo -e "${CYAN}$border${NC}"
echo

}

확장된 테이블 헤더 출력 함수

print_extended_table_header() {
echo -e "BOLD─────────────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────{BOLD}┌─────────────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┐{NC}"
echo -e "BOLD│노드명│CPU할당│CPU요청│CPU점유율│CPU사용률│메모리할당│메모리요청│메모리점유율│메모리사용률│{BOLD}│ 노드명 │ CPU 할당 │ CPU 요청 │ CPU 점유율│ CPU 사용률│ 메모리할당│ 메모리요청│메모리점유율│메모리사용률│{NC}"
echo -e "BOLD││(G)(G)({BOLD}│ │ (G) │ (G) │ (%) │ (%) │ (Gi) │ (Gi) │ (%) │ (%) │{NC}"
echo -e "BOLD├─────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤{BOLD}├─────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤{NC}"
}

확장된 테이블 행 출력 함수

print_extended_table_row() {
local node="$1"
local cpu_alloc="$2"
local cpu_req="$3"
local cpu_occupy="$4"
local cpu_usage="$5"
local mem_alloc="$6"
local mem_req="$7"
local mem_occupy="$8"
local mem_usage="$9"

# 점유율에 따른 색상 결정 (Request 기준)
local cpu_occupy_color="${GREEN}"
local mem_occupy_color="${GREEN}"

if [[ $(compare_numbers $cpu_occupy "> 80") -eq 1 ]]; then
    cpu_occupy_color="${RED}"
elif [[ $(compare_numbers $cpu_occupy "> 60") -eq 1 ]]; then
    cpu_occupy_color="${YELLOW}"
fi

if [[ $(compare_numbers $mem_occupy "> 80") -eq 1 ]]; then
    mem_occupy_color="${RED}"
elif [[ $(compare_numbers $mem_occupy "> 60") -eq 1 ]]; then
    mem_occupy_color="${YELLOW}"
fi

# 실제 사용률에 따른 색상 결정
local cpu_usage_color="${GREEN}"
local mem_usage_color="${GREEN}"

if [[ "$cpu_usage" != "N/A" ]]; then
    if [[ $(compare_numbers $cpu_usage "> 80") -eq 1 ]]; then
        cpu_usage_color="${RED}"
    elif [[ $(compare_numbers $cpu_usage "> 60") -eq 1 ]]; then
        cpu_usage_color="${YELLOW}"
    fi
else
    cpu_usage_color="${GRAY}"
fi

if [[ "$mem_usage" != "N/A" ]]; then
    if [[ $(compare_numbers $mem_usage "> 80") -eq 1 ]]; then
        mem_usage_color="${RED}"
    elif [[ $(compare_numbers $mem_usage "> 60") -eq 1 ]]; then
        mem_usage_color="${YELLOW}"
    fi
else
    mem_usage_color="${GRAY}"
fi

printf "│ %-15s │ %9s │ %9s │ ${cpu_occupy_color}%8s%%${NC} │ ${cpu_usage_color}%8s%%${NC} │ %9s │ %9s │ ${mem_occupy_color}%8s%%${NC} │ ${mem_usage_color}%8s%%${NC} │\n" \
    "$node" "$cpu_alloc" "$cpu_req" "$cpu_occupy" "$cpu_usage" "$mem_alloc" "$mem_req" "$mem_occupy" "$mem_usage"

}

확장된 테이블 푸터 출력 함수

print_extended_table_footer() {
echo -e "BOLD─────────────────┴───────────┴───────────┴───────────┴───────────┴───────────┴───────────┴───────────┴───────────{BOLD}└─────────────────┴───────────┴───────────┴───────────┴───────────┴───────────┴───────────┴───────────┴───────────┘{NC}"
}

함수: CPU 단위를 기가코어로 정규화 (m -> G 변환)

normalize_cpu_to_giga() {
local cpu=$1

# 빈 값이나 null 체크
if [[ -z "$cpu" ]] || [[ "$cpu" == "null" ]]; then
    echo "0.000"
    return
fi

# 정규표현식으로 안전하게 파싱하고 기가코어로 변환
if [[ $cpu =~ ^([0-9]+)m$ ]]; then
    # 밀리코어를 기가코어로 변환 (1000m = 1G)
    local milli=${BASH_REMATCH[1]}
    awk "BEGIN {printf \"%.3f\", $milli / 1000}"
elif [[ $cpu =~ ^([0-9]+)$ ]]; then
    # 정수형 CPU (1 = 1G)
    echo ${BASH_REMATCH[1]}.000
elif [[ $cpu =~ ^([0-9]*\.?[0-9]+)$ ]]; then
    # 소수점이 있는 경우 (예: 0.5 = 0.5G)
    local cpu_float=${BASH_REMATCH[1]}
    awk "BEGIN {printf \"%.3f\", $cpu_float}"
else
    echo "0.000"
fi

}

함수: 메모리 단위를 기가바이트로 정규화

normalize_memory_to_giga() {
local mem=$1

# 빈 값이나 null 체크
if [[ -z "$mem" ]] || [[ "$mem" == "null" ]]; then
    echo "0.00"
    return
fi

# 정규표현식으로 안전하게 파싱하고 기가바이트로 변환
if [[ $mem =~ ^([0-9]+)Ki$ ]]; then
    local ki=${BASH_REMATCH[1]}
    awk "BEGIN {printf \"%.2f\", $ki / 1024 / 1024}"
elif [[ $mem =~ ^([0-9]+)Mi$ ]]; then
    local mi=${BASH_REMATCH[1]}
    awk "BEGIN {printf \"%.2f\", $mi / 1024}"
elif [[ $mem =~ ^([0-9]+)Gi$ ]]; then
    echo ${BASH_REMATCH[1]}.00
elif [[ $mem =~ ^([0-9]+)Ti$ ]]; then
    local ti=${BASH_REMATCH[1]}
    awk "BEGIN {printf \"%.2f\", $ti * 1024}"
elif [[ $mem =~ ^([0-9]+)$ ]]; then
    # 단위 없으면 바이트로 가정하고 Gi로 변환
    local bytes=$mem
    awk "BEGIN {printf \"%.2f\", $bytes / 1024 / 1024 / 1024}"
else
    echo "0.00"
fi

}

함수: kubectl top에서 실제 사용률 추출

get_actual_usage() {
local node=$1
local resource_type=$2 # "cpu" or "memory"

# kubectl top nodes에서 해당 노드의 실제 사용량 추출
local top_output=$(kubectl top nodes --no-headers 2>/dev/null | grep "^$node ")

if [[ -z "$top_output" ]]; then
    echo "N/A"
    return
fi

if [[ "$resource_type" == "cpu" ]]; then
    # CPU 사용량 추출 (예: 250m -> 0.25G, 15% -> 15.0)
    local cpu_usage=$(echo "$top_output" | awk '{print $2}')
    local cpu_percent=$(echo "$top_output" | awk '{print $3}' | tr -d '%')
    
    if [[ -n "$cpu_percent" ]] && [[ "$cpu_percent" != "0" ]]; then
        echo "$cpu_percent"
    else
        echo "N/A"
    fi
elif [[ "$resource_type" == "memory" ]]; then
    # 메모리 사용률 추출
    local mem_percent=$(echo "$top_output" | awk '{print $5}' | tr -d '%')
    
    if [[ -n "$mem_percent" ]] && [[ "$mem_percent" != "0" ]]; then
        echo "$mem_percent"
    else
        echo "N/A"
    fi
fi

}

함수: 안전한 비율 계산 (awk 사용)

safe_percentage() {
local numerator=$1
local denominator=$2

if [[ $(awk "BEGIN {print ($denominator <= 0)}") -eq 1 ]] || [[ $(awk "BEGIN {print ($numerator <= 0)}") -eq 1 ]]; then
    echo "0.0"
else
    awk "BEGIN {printf \"%.1f\", $numerator * 100 / $denominator}"
fi

}

함수: 숫자 비교 (awk 사용)

compare_numbers() {
local num1=1 local operator=$2 local num2=$3 awk "BEGIN {print (num1 $operator $num2)}"
}

print_header "🚀 KUBERNETES 노드 리소스 분석 v1.5"

Metrics Server 확인

echo -e "BLUE🔍MetricsServer상태확인...{BLUE}🔍 Metrics Server 상태 확인...{NC}"
if kubectl top nodes >/dev/null 2>&1; then
echo -e "GREENMetricsServer가정상작동중입니다(실제사용률제공가능){GREEN}✅ Metrics Server가 정상 작동 중입니다 (실제 사용률 제공 가능){NC}"
METRICS_AVAILABLE=true
else
echo -e "{YELLOW}⚠️ Metrics Server를 사용할 수 없습니다 (실제 사용률은 N/A로 표시됩니다){NC}"
echo -e "GRAY설치방법:kubectlapplyfhttps://github.com/kubernetessigs/metricsserver/releases/latest/download/components.yaml{GRAY} 설치 방법: kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml{NC}"
METRICS_AVAILABLE=false
fi

모든 노드 목록 가져오기

nodes=$(kubectl get nodes --no-headers -o custom-columns=":metadata.name")

print_header "📊 노드별 리소스 현황: 점유율 vs 실제 사용률"
echo -e "BOLD💡용어설명:{BOLD}💡 용어 설명:{NC}"
echo -e " CYAN점유율{CYAN}점유율{NC}: Pod Request 기준 리소스 예약 비율 (스케줄링에 영향)"
echo -e " CYAN사용률{CYAN}사용률{NC}: 실제 CPU/메모리 소비 비율 (성능에 영향)"
echo

print_extended_table_header

노드별 정보를 배열에 저장

declare -a node_data
for node in $nodes; do

# 노드 정보 가져오기
node_info=$(kubectl describe node $node)

# 노드 용량 추출
allocatable_cpu=$(echo "$node_info" | grep -A 20 "Allocatable:" | grep "cpu:" | awk '{print $2}')
allocatable_memory=$(echo "$node_info" | grep -A 20 "Allocatable:" | grep "memory:" | awk '{print $2}')

# 요청된 리소스 추출 (더 안전한 파싱)
requested_cpu_raw=$(echo "$node_info" | grep -A 10 "Allocated resources:" | grep "cpu" | awk '{print $2}' | tr -d '()')
requested_memory_raw=$(echo "$node_info" | grep -A 10 "Allocated resources:" | grep "memory" | awk '{print $2}' | tr -d '()')

# CPU/메모리를 기가 단위로 정규화
allocatable_cpu_g=$(normalize_cpu_to_giga "$allocatable_cpu")
allocatable_memory_gi=$(normalize_memory_to_giga "$allocatable_memory")

requested_cpu_g=$(normalize_cpu_to_giga "$requested_cpu_raw")
requested_memory_gi=$(normalize_memory_to_giga "$requested_memory_raw")

# 점유율 계산 (Request 기준)
cpu_occupy_percent=$(safe_percentage $requested_cpu_g $allocatable_cpu_g)
memory_occupy_percent=$(safe_percentage $requested_memory_gi $allocatable_memory_gi)

# 실제 사용률 가져오기 (kubectl top 기반)
if [[ "$METRICS_AVAILABLE" == true ]]; then
    cpu_usage_percent=$(get_actual_usage "$node" "cpu")
    memory_usage_percent=$(get_actual_usage "$node" "memory")
else
    cpu_usage_percent="N/A"
    memory_usage_percent="N/A"
fi

# 테이블 행 출력
print_extended_table_row "$node" "${allocatable_cpu_g}G" "${requested_cpu_g}G" "$cpu_occupy_percent" "$cpu_usage_percent" "${allocatable_memory_gi}Gi" "${requested_memory_gi}Gi" "$memory_occupy_percent" "$memory_usage_percent"

# 노드 데이터 저장 (나중에 상세 분석용)
node_data+=("$node|$cpu_occupy_percent|$memory_occupy_percent|$cpu_usage_percent|$memory_usage_percent")

done

print_extended_table_footer

경고 및 알림 섹션

echo
echo -e "BOLD🚨상태알림:{BOLD}🚨 상태 알림:{NC}"
high_occupy_nodes=()
high_usage_nodes=()

for data in "nodedata[@]";doIFS=readrnodecpuoccupymemoccupycpuusagememusage<<<"{node_data[@]}"; do IFS='|' read -r node cpu_occupy mem_occupy cpu_usage mem_usage <<< "data"

# 점유율 기준 경고
if [[ $(compare_numbers $cpu_occupy "> 80") -eq 1 ]] || [[ $(compare_numbers $mem_occupy "> 80") -eq 1 ]]; then
    high_occupy_nodes+=("$node")
    echo -e "   ${RED}⚠️  $node: 높은 리소스 점유율 (CPU: ${cpu_occupy}%, Memory: ${mem_occupy}%) - 스케줄링 어려움${NC}"
fi

# 실제 사용률 기준 경고
if [[ "$cpu_usage" != "N/A" ]] && [[ "$mem_usage" != "N/A" ]]; then
    if [[ $(compare_numbers $cpu_usage "> 80") -eq 1 ]] || [[ $(compare_numbers $mem_usage "> 80") -eq 1 ]]; then
        high_usage_nodes+=("$node")
        echo -e "   ${YELLOW}🔥 $node: 높은 실제 사용률 (CPU: ${cpu_usage}%, Memory: ${mem_usage}%) - 성능 저하 우려${NC}"
    fi
fi

done

if [ {#high_occupy_nodes[@]} -eq 0 ] && [ ${#high_usage_nodes[@]} -eq 0 ]; then echo -e " ${GREEN}✅ 모든 노드의 리소스 점유율과 사용률이 정상 범위입니다{NC}"
fi

print_header "🔍 노드별 상위 리소스 소비 POD"

for node in nodes;doechoe"nodes; do echo -e "{PURPLE}📍 노드: BOLD{BOLD}nodeNC"echoe"{NC}" echo -e "{BOLD}┌─────────┬─────────────┬──────────────────────────────────────────────────────────────┐NC"echoe"{NC}" echo -e "{BOLD}│ CPU(G) │ Memory(Gi) │ Pod Name │NC"echoe"{NC}" echo -e "{BOLD}├─────────┼─────────────┼──────────────────────────────────────────────────────────────┤${NC}"

# 노드의 모든 Pod 리소스 요청 상세 정보
kubectl get pods --all-namespaces --field-selector spec.nodeName=$node -o json | \
jq -r '.items[] | 
{
    name: .metadata.name,
    namespace: .metadata.namespace,
    containers: .spec.containers[]
} | 
select(.containers.resources.requests != null) |
[
    (.containers.resources.requests.cpu // "0" | if test("m$") then (rtrimstr("m") | tonumber / 1000) else tonumber end),
    (.containers.resources.requests.memory // "0" | if test("Mi$") then (rtrimstr("Mi") | tonumber / 1024) elif test("Gi$") then (rtrimstr("Gi") | tonumber) elif test("Ki$") then (rtrimstr("Ki") | tonumber / 1024 / 1024) else 0 end),
    (.namespace + "/" + .name)
] | 
@tsv' | \
sort -nr | \
head -10 | \
while IFS=$'\t' read -r cpu_g memory_gi pod; do
    # 50자 이내로 Pod 이름 제한
    if [ ${#pod} -gt 60 ]; then
        pod_display="${pod:0:57}..."
    else
        pod_display="$pod"
    fi
    
    # CPU와 메모리 값 포맷팅
    cpu_formatted=$(awk "BEGIN {printf \"%.3f\", $cpu_g}")
    memory_formatted=$(awk "BEGIN {printf \"%.2f\", $memory_gi}")
    
    if [[ $(awk "BEGIN {print ($cpu_g > 0.5)}") -eq 1 ]] || [[ $(awk "BEGIN {print ($memory_gi > 0.5)}") -eq 1 ]]; then
        printf "│ ${RED}%7s${NC} │ ${RED}%11s${NC} │ %-60s │\n" "$cpu_formatted" "$memory_formatted" "$pod_display"
    elif [[ $(awk "BEGIN {print ($cpu_g > 0.2)}") -eq 1 ]] || [[ $(awk "BEGIN {print ($memory_gi > 0.25)}") -eq 1 ]]; then
        printf "│ ${YELLOW}%7s${NC} │ ${YELLOW}%11s${NC} │ %-60s │\n" "$cpu_formatted" "$memory_formatted" "$pod_display"
    else
        printf "│ ${GREEN}%7s${NC} │ ${GREEN}%11s${NC} │ %-60s │\n" "$cpu_formatted" "$memory_formatted" "$pod_display"
    fi
done

echo -e "${BOLD}└─────────┴─────────────┴──────────────────────────────────────────────────────────────┘${NC}"
echo

done

print_header "📋 클러스터 전체 상황 요약"

스케줄링 실패한 Pod 확인

echo -e "RED🚫스케줄링실패한Pod목록:{RED}🚫 스케줄링 실패한 Pod 목록:{NC}"
echo -e "BOLD─────────────────────────┬─────────────────────────────────────┬──────────────────{BOLD}┌─────────────────────────┬─────────────────────────────────────┬──────────────────┐{NC}"
echo -e "BOLDNamespacePodNameStatus{BOLD}│ Namespace │ Pod Name │ Status │{NC}"
echo -e "BOLD├─────────────────────────┼─────────────────────────────────────┼──────────────────┤{BOLD}├─────────────────────────┼─────────────────────────────────────┼──────────────────┤{NC}"

pending_pods=(kubectlgetpodsallnamespacesfieldselectorstatus.phase=Pendingnoheaders2>/dev/null)if[[n"(kubectl get pods --all-namespaces --field-selector status.phase=Pending --no-headers 2>/dev/null) if [[ -n "pending_pods" ]]; then
echo "pendingpods"whilereadrnamespacenamereadystatusrestartsage;doprintf"pending_pods" | while read -r namespace name ready status restarts age; do printf "│ %-23s │ %-35s │ ${RED}%-16s{NC} │\n" "namespace""namespace" "name" "status" done else printf "│ ${GREEN}%-23s{NC} │ GREEN{GREEN}%-35s{NC} │ GREEN{GREEN}%-16s{NC} │\n" "없음" "모든 Pod가 정상 스케줄됨" "✅ 정상"
fi

echo -e "BOLD─────────────────────────┴─────────────────────────────────────┴──────────────────{BOLD}└─────────────────────────┴─────────────────────────────────────┴──────────────────┘{NC}"

echo
echo -e "YELLOW🔥높은리소스요청Pod(CPU>0.5G또는Memory>0.5Gi):{YELLOW}🔥 높은 리소스 요청 Pod (CPU > 0.5G 또는 Memory > 0.5Gi):{NC}"
echo -e "BOLD─────────┬─────────────┬─────────────────────┬──────────────────────────────────────{BOLD}┌─────────┬─────────────┬─────────────────────┬──────────────────────────────────────┐{NC}"
echo -e "BOLDCPU(G)Memory(Gi)NodePodName{BOLD}│ CPU(G) │ Memory(Gi) │ Node │ Pod Name │{NC}"
echo -e "BOLD├─────────┼─────────────┼─────────────────────┼──────────────────────────────────────┤{BOLD}├─────────┼─────────────┼─────────────────────┼──────────────────────────────────────┤{NC}"

high_resource_pods=(kubectlgetpodsallnamespacesojson jqr.items[]select(.spec.containers[]?.resources.requests!=null)name:.metadata.name,namespace:.metadata.namespace,node:.spec.nodeName,requests:[.spec.containers[]?.resources.requests//]addselect((.requests.cpu//"0"iftest("m(kubectl get pods --all-namespaces -o json | \ jq -r '.items[] | select(.spec.containers[]?.resources.requests != null) | { name: .metadata.name, namespace: .metadata.namespace, node: .spec.nodeName, requests: [.spec.containers[]?.resources.requests // {}] | add } | select( (.requests.cpu // "0" | if test("m") then (rtrimstr("m") | tonumber / 1000) else tonumber end) > 0.5 or
(.requests.memory // "0" | if test("Mi")then(rtrimstr("Mi")tonumber/1024)eliftest("Gi") then (rtrimstr("Mi") | tonumber / 1024) elif test("Gi") then (rtrimstr("Gi") | tonumber) else 0 end) > 0.5
) |
[
(.requests.cpu // "0" | if test("m")then(rtrimstr("m")tonumber/1000)elsetonumberend),(.requests.memory//"0"iftest("Mi") then (rtrimstr("m") | tonumber / 1000) else tonumber end), (.requests.memory // "0" | if test("Mi") then (rtrimstr("Mi") | tonumber / 1024) elif test("Gi$") then (rtrimstr("Gi") | tonumber) else 0 end),
(.node // "Unscheduled"),
(.namespace + "/" + .name)
] | @tsv')

if [[ -n "$high_resource_pods" ]]; then
echo "highresourcepods"whileIFS=high_resource_pods" | while IFS='\t' read -r cpu_g memory_gi node pod; do
if [ ${#pod} -gt 36 ]; then
pod_display="pod:0:33..."elsepoddisplay="{pod:0:33}..." else pod_display="pod"
fi

    if [ ${#node} -gt 19 ]; then
        node_display="${node:0:16}..."
    else
        node_display="$node"
    fi
    
    cpu_formatted=$(awk "BEGIN {printf \"%.3f\", $cpu_g}")
    memory_formatted=$(awk "BEGIN {printf \"%.2f\", $memory_gi}")
    
    printf "│ ${RED}%7s${NC} │ ${RED}%11s${NC} │ %-19s │ %-36s │\n" "$cpu_formatted" "$memory_formatted" "$node_display" "$pod_display"
done

else
printf "│ GREEN{GREEN}%-7s{NC} │ GREEN{GREEN}%-11s{NC} │ GREEN{GREEN}%-19s{NC} │ GREEN{GREEN}%-36s{NC} │\n" "없음" "없음" "모든 노드" "높은 리소스 요청 Pod 없음"
fi

echo -e "BOLD─────────┴─────────────┴─────────────────────┴──────────────────────────────────────{BOLD}└─────────┴─────────────┴─────────────────────┴──────────────────────────────────────┘{NC}"

echo
echo -e "BLUE🔍최근스케줄링실패이벤트:{BLUE}🔍 최근 스케줄링 실패 이벤트:{NC}"
recent_events=(kubectlgeteventsallnamespacesfieldselectorreason=FailedSchedulingsortby=.lastTimestamp2>/dev/nulltail5)if[[n"(kubectl get events --all-namespaces --field-selector reason=FailedScheduling --sort-by='.lastTimestamp' 2>/dev/null | tail -5) if [[ -n "recent_events" ]]; then
echo "recentevents"elseechoe"recent_events" else echo -e "{GREEN}✅ 최근 스케줄링 실패 이벤트가 없습니다${NC}"
fi

print_header "💡 분석 가이드 및 권장사항 v1.5"

echo -e "BOLD🎯새로운이중지표시스템:{BOLD}🎯 새로운 이중 지표 시스템:{NC}"
echo -e " CYAN📊점유율(Request){CYAN}📊 점유율 (Request){NC}: 스케줄링을 위해 예약된 리소스 비율"
echo -e " CYAN🔥사용률(Actual){CYAN}🔥 사용률 (Actual){NC}: 실제로 소비되고 있는 리소스 비율"
echo -e " GRAY💡점유율이높으면새Pod스케줄링어려움,사용률이높으면성능저하{GRAY}💡 점유율이 높으면 새 Pod 스케줄링 어려움, 사용률이 높으면 성능 저하{NC}"

echo -e "BOLD🎯색상가이드:{BOLD}🎯 색상 가이드:{NC}"
echo -e " GREEN{GREEN}●{NC} 초록색: 정상 범위 (0-60%)"
echo -e " YELLOW{YELLOW}●{NC} 노란색: 주의 범위 (60-80%)"
echo -e " RED{RED}●{NC} 빨간색: 위험 범위 (80%+)"
echo -e " GRAY{GRAY}●{NC} 회색: 데이터 없음 (Metrics Server 필요)"

echo
echo -e "BOLD📊분석시나리오:{BOLD}📊 분석 시나리오:{NC}"
echo -e " CYAN1.{CYAN}1.{NC} 점유율 높음 + 사용률 낮음 → Request 과다 할당, 리소스 낭비"
echo -e " CYAN2.{CYAN}2.{NC} 점유율 낮음 + 사용률 높음 → Request 부족 설정, 성능 영향 가능"
echo -e " CYAN3.{CYAN}3.{NC} 점유율 높음 + 사용률 높음 → 실제 리소스 부족, 스케일업 필요"
echo -e " CYAN4.{CYAN}4.{NC} 점유율 낮음 + 사용률 낮음 → 정상 상태, 여유 리소스 있음"

echo
echo -e "{BOLD}🛠️ 권장 조치사항:{NC}"
echo -e " PURPLE{PURPLE}•{NC} 점유율 > 80%: 새로운 노드 추가 또는 Pod 재분배"
echo -e " PURPLE{PURPLE}•{NC} 사용률 > 80%: CPU/메모리 성능 최적화 또는 스케일업"
echo -e " PURPLE{PURPLE}•{NC} 점유율 >> 사용률: Pod Request 값 다운사이징"
echo -e " PURPLE{PURPLE}•{NC} 사용률 >> 점유율: Pod Request 값 업사이징 (안정성 확보)"
echo -e " PURPLE{PURPLE}•{NC} Metrics Server 설치로 실시간 모니터링 강화"

echo
echo -e "BOLD🔧상세분석명령어:{BOLD}🔧 상세 분석 명령어:{NC}"
echo -e " {GRAY}# 실시간 노드 사용률: kubectl top nodes{NC}"
echo -e " {GRAY}# 실시간 Pod 사용률: kubectl top pods --all-namespaces{NC}"
echo -e " {GRAY}# 특정 Pod 상세 정보: kubectl describe pod <pod-name> -n <namespace>{NC}"
echo -e " {GRAY}# 노드 상세 정보: kubectl describe node <node-name>{NC}"
echo -e " {GRAY}# HPA 상태 확인: kubectl get hpa --all-namespaces{NC}"

echo
echo -e "BOLD📈MetricsServer설치(사용률데이터필요시):{BOLD}📈 Metrics Server 설치 (사용률 데이터 필요시):{NC}"
echo -e " GRAYkubectlapplyfhttps://github.com/kubernetessigs/metricsserver/releases/latest/download/components.yaml{GRAY}kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml{NC}"

print_header "✅ 분석 완료 - K8s 리소스 진단 v1.5"
echo -e "GREEN점유율(Request)과사용률(Actual)을구분한통합분석이완료되었습니다!🎯{GREEN}점유율(Request)과 사용률(Actual)을 구분한 통합 분석이 완료되었습니다! 🎯{NC}"
echo -e "CYAN📊스케줄링문제는점유율을,성능문제는사용률을우선확인하세요.{CYAN}📊 스케줄링 문제는 점유율을, 성능 문제는 사용률을 우선 확인하세요.{NC}"
echo -e "GRAY💡추가문의사항이나개선사항이있으시면클러스터관리자에게문의하세요.{GRAY}💡 추가 문의사항이나 개선사항이 있으시면 클러스터 관리자에게 문의하세요.{NC}"

profile
bytebliss

0개의 댓글