Kubernetes 클러스터에서 실제 사용 가능한 vcore 가용량을 확인하는 방법들을 정리해드리겠습니다.
총 CPU 용량 (Capacity)
├── 시스템 예약 (System Reserved)
└── 할당 가능 (Allocatable)
├── 현재 요청됨 (Requested)
└── 가용량 (Available) ← 우리가 찾는 값!
가용량 = 할당 가능한 CPU - 현재 요청된 CPU
# 노드별 상세 리소스 정보
kubectl describe nodes
# 출력에서 중요한 부분:
# Capacity:
# cpu: 4
# Allocatable:
# cpu: 3800m
# Allocated resources:
# (Total limits may be over 100 percent, i.e., overcommitted.)
# Resource Requests Limits
# -------- -------- ------
# cpu 1200m (31%) 2400m (63%)
# memory 2Gi (26%) 4Gi (52%)
#
# 가용량 = 3800m - 1200m = 2600m (2.6 cores)
# 특정 노드의 가용량 확인
NODE_NAME="worker-node-1"
kubectl describe node $NODE_NAME | grep -A 5 "Allocated resources:"
#!/bin/bash
# k8s_available_cpu.sh
echo "=========================================="
echo "Kubernetes 클러스터 CPU 가용량 분석"
echo "=========================================="
echo
# 임시 파일 생성
TEMP_FILE=$(mktemp)
# 노드별 정보 수집
echo "노드별 CPU 가용량:"
printf "%-20s %-12s %-12s %-12s %-12s\n" "NODE" "CAPACITY" "ALLOCATABLE" "REQUESTED" "AVAILABLE"
printf "%-20s %-12s %-12s %-12s %-12s\n" "----" "--------" "-----------" "---------" "---------"
total_capacity=0
total_allocatable=0
total_requested=0
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
# 노드 정보 가져오기
node_info=$(kubectl describe node $node)
# 용량 정보 추출
capacity=$(echo "$node_info" | grep "cpu:" | head -1 | awk '{print $2}')
allocatable=$(echo "$node_info" | grep "cpu:" | tail -1 | awk '{print $2}')
# 요청된 CPU 추출 (밀리코어 단위)
requested=$(echo "$node_info" | grep -A 3 "Allocated resources:" | grep "cpu" | awk '{print $2}' | sed 's/m.*//' | sed 's/(.*//')
# 단위 변환 (allocatable이 밀리코어인 경우)
if [[ $allocatable == *"m" ]]; then
allocatable_num=$(echo $allocatable | sed 's/m//')
else
allocatable_num=$((allocatable * 1000))
fi
# 기본값 설정
requested=${requested:-0}
# 가용량 계산
available=$((allocatable_num - requested))
# 코어 단위로 변환
capacity_cores=$capacity
allocatable_cores=$(echo "scale=1; $allocatable_num / 1000" | bc)
requested_cores=$(echo "scale=1; $requested / 1000" | bc)
available_cores=$(echo "scale=1; $available / 1000" | bc)
printf "%-20s %-12s %-12s %-12s %-12s\n" "$node" "${capacity_cores}c" "${allocatable_cores}c" "${requested_cores}c" "${available_cores}c"
# 총계 누적
total_capacity=$((total_capacity + capacity))
total_allocatable=$((total_allocatable + allocatable_num))
total_requested=$((total_requested + requested))
done
total_available=$((total_allocatable - total_requested))
echo
printf "%-20s %-12s %-12s %-12s %-12s\n" "TOTAL" "${total_capacity}c" "$(echo "scale=1; $total_allocatable / 1000" | bc)c" "$(echo "scale=1; $total_requested / 1000" | bc)c" "$(echo "scale=1; $total_available / 1000" | bc)c"
# 사용률 계산
utilization=$(echo "scale=1; $total_requested / $total_allocatable * 100" | bc)
available_percentage=$(echo "scale=1; $total_available / $total_allocatable * 100" | bc)
echo
echo "클러스터 CPU 요약:"
echo " 총 가용 CPU: $(echo "scale=1; $total_available / 1000" | bc) cores"
echo " 사용률: ${utilization}%"
echo " 가용률: ${available_percentage}%"
# 경고 메시지
if (( $(echo "$utilization > 80" | bc -l) )); then
echo " ⚠️ 경고: CPU 사용률이 80%를 초과했습니다!"
elif (( $(echo "$utilization > 60" | bc -l) )); then
echo " ⚡ 주의: CPU 사용률이 60%를 초과했습니다."
else
echo " ✅ CPU 사용률이 적정 수준입니다."
fi
rm -f $TEMP_FILE
# 전체 클러스터 가용 CPU (밀리코어)
kubectl describe nodes | grep -A 3 "Allocated resources:" | grep cpu | awk '{requested+=$2; allocatable+=$4} END {print "Available:", allocatable-requested "m"}'
# JSON으로 정확한 계산
kubectl get nodes -o json | jq -r '.items[] | [.metadata.name, .status.allocatable.cpu, (.status.allocatable.cpu | if test("m$") then (. | rtrimstr("m") | tonumber) else (. | tonumber * 1000) end)] | @tsv' > /tmp/allocatable.txt
# 각 노드별 요청된 CPU 계산 후 가용량 산출
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
echo -n "$node: "
kubectl describe node $node | grep -A 3 "Allocated resources:" | grep cpu | awk '{print $4-$2"m available"}'
done
# 노드별 실시간 CPU 사용량과 가용량
kubectl top nodes
# 출력 예시 해석:
# NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
# node1 982m 25% 3910Mi 49%
# node2 1843m 23% 7901Mi 50%
#
# 가용량 계산:
# node1: 4 cores * (100-25)% = 3 cores available
# node2: 8 cores * (100-23)% = 6.16 cores available
#!/bin/bash
# realtime_available_cpu.sh
echo "실시간 CPU 가용량 (메트릭 서버 기반):"
printf "%-20s %-12s %-12s %-15s\n" "NODE" "USED" "CAPACITY" "AVAILABLE"
printf "%-20s %-12s %-12s %-15s\n" "----" "----" "--------" "---------"
# kubectl top nodes의 출력을 파싱
kubectl top nodes --no-headers | while read node used_cpu used_pct used_mem mem_pct; do
# 전체 용량 계산 (사용량 / 사용률 * 100)
used_cores=$(echo $used_cpu | sed 's/m//')
used_percent=$(echo $used_pct | sed 's/%//')
if [ $used_percent -gt 0 ]; then
total_millis=$((used_cores * 100 / used_percent))
available_millis=$((total_millis - used_cores))
total_cores=$(echo "scale=1; $total_millis / 1000" | bc)
available_cores=$(echo "scale=1; $available_millis / 1000" | bc)
printf "%-20s %-12s %-12s %-15s\n" "$node" "$used_cpu" "${total_cores}c" "${available_cores}c"
else
printf "%-20s %-12s %-12s %-15s\n" "$node" "$used_cpu" "N/A" "N/A"
fi
done
#!/bin/bash
# namespace_available_cpu.sh
echo "네임스페이스별 CPU 가용량 분석:"
printf "%-20s %-12s %-12s %-15s\n" "NAMESPACE" "QUOTA_LIMIT" "USED" "AVAILABLE"
printf "%-20s %-12s %-12s %-15s\n" "---------" "-----------" "----" "---------"
# 리소스 쿼터가 있는 네임스페이스들 확인
kubectl get resourcequota --all-namespaces -o json | jq -r '.items[] | select(.spec.hard."requests.cpu") | [.metadata.namespace, .spec.hard."requests.cpu", .status.used."requests.cpu"] | @tsv' | while read ns quota used; do
if [[ $quota == *"m" ]]; then
quota_millis=$(echo $quota | sed 's/m//')
else
quota_millis=$(($(echo $quota | sed 's/[^0-9]//g') * 1000))
fi
if [[ $used == *"m" ]]; then
used_millis=$(echo $used | sed 's/m//')
else
used_millis=$(($(echo $used | sed 's/[^0-9]//g') * 1000))
fi
available_millis=$((quota_millis - used_millis))
available_cores=$(echo "scale=1; $available_millis / 1000" | bc)
printf "%-20s %-12s %-12s %-15s\n" "$ns" "$quota" "$used" "${available_cores}c"
done
# 쿼터가 없는 네임스페이스는 클러스터 전체 가용량 공유
echo
echo "리소스 쿼터가 없는 네임스페이스들은 클러스터 전체 가용량을 공유합니다."
#!/bin/bash
# capacity_planning.sh
# 현재 가용량 확인
current_available=$(kubectl describe nodes | grep -A 3 "Allocated resources:" | grep cpu | awk '{allocatable+=$4; requested+=$2} END {print allocatable-requested}' | sed 's/m//')
echo "현재 가용 CPU: $(echo "scale=1; $current_available / 1000" | bc) cores"
# 새 워크로드 시뮬레이션
echo
echo "새 워크로드 배치 시뮬레이션:"
echo "추가하려는 CPU 요청량을 입력하세요 (cores): "
read new_workload_cores
new_workload_millis=$(($(echo $new_workload_cores | sed 's/\..*//') * 1000))
remaining_available=$((current_available - new_workload_millis))
if [ $remaining_available -gt 0 ]; then
echo "✅ 배치 가능! 배치 후 남은 가용량: $(echo "scale=1; $remaining_available / 1000" | bc) cores"
else
echo "❌ 용량 부족! 부족한 CPU: $(echo "scale=1; $((new_workload_millis - current_available)) / 1000" | bc) cores"
echo "클러스터 확장이 필요합니다."
fi
#!/bin/bash
# cpu_availability_monitor.sh
watch -n 10 '
echo "=== Kubernetes CPU 가용량 대시보드 ==="
echo "업데이트 시간: $(date)"
echo
# 노드별 요약
echo "노드별 상태:"
kubectl get nodes -o custom-columns="NAME:.metadata.name,STATUS:.status.conditions[-1].type,CPU_CAPACITY:.status.capacity.cpu,CPU_ALLOCATABLE:.status.allocatable.cpu"
echo
echo "실시간 사용량:"
kubectl top nodes 2>/dev/null || echo "메트릭 서버를 사용할 수 없습니다."
echo
echo "가용량 요약:"
total_allocatable=0
total_requested=0
for node in $(kubectl get nodes -o jsonpath="{.items[*].metadata.name}"); do
allocatable=$(kubectl get node $node -o jsonpath="{.status.allocatable.cpu}" | sed "s/m//")
if [[ ! $allocatable =~ ^[0-9]+$ ]]; then
allocatable=$(($(echo $allocatable | sed "s/[^0-9]//g") * 1000))
fi
requested=$(kubectl describe node $node | grep -A 3 "Allocated resources:" | grep cpu | awk "{print \$2}" | sed "s/m.*//" | sed "s/(.*//" || echo "0")
requested=${requested:-0}
total_allocatable=$((total_allocatable + allocatable))
total_requested=$((total_requested + requested))
done
total_available=$((total_allocatable - total_requested))
utilization=$(echo "scale=1; $total_requested / $total_allocatable * 100" | bc)
echo "전체 할당가능: $(echo "scale=1; $total_allocatable / 1000" | bc) cores"
echo "현재 요청량: $(echo "scale=1; $total_requested / 1000" | bc) cores"
echo "남은 가용량: $(echo "scale=1; $total_available / 1000" | bc) cores"
echo "사용률: ${utilization}%"
if (( $(echo "$utilization > 80" | bc -l) )); then
echo "🔴 경고: 높은 사용률!"
elif (( $(echo "$utilization > 60" | bc -l) )); then
echo "🟡 주의: 보통 사용률"
else
echo "🟢 양호: 낮은 사용률"
fi
'
# 클러스터 총 가용 CPU
sum(kube_node_status_allocatable{resource="cpu"}) - sum(kube_pod_container_resource_requests{resource="cpu"})
# 노드별 가용 CPU
kube_node_status_allocatable{resource="cpu"} - on(node) group_left() sum by(node) (kube_pod_container_resource_requests{resource="cpu"})
# 가용률 (%)
(sum(kube_node_status_allocatable{resource="cpu"}) - sum(kube_pod_container_resource_requests{resource="cpu"})) / sum(kube_node_status_allocatable{resource="cpu"}) * 100
요약:
kubectl describe nodes: 가장 정확한 정보kubectl top nodes + 계산가용량이 20% 미만이면 클러스터 확장을 고려해야 합니다!