k8s resource 계산

진웅·2025년 6월 9일

K8S Basics

목록 보기
9/40

Kubernetes 클러스터에서 실제 사용 가능한 vcore 가용량을 확인하는 방법들을 정리해드리겠습니다.

1. 핵심 개념 이해

총 CPU 용량 (Capacity)
├── 시스템 예약 (System Reserved)
└── 할당 가능 (Allocatable)
    ├── 현재 요청됨 (Requested) 
    └── 가용량 (Available) ← 우리가 찾는 값!

가용량 = 할당 가능한 CPU - 현재 요청된 CPU

2. 기본 확인 명령어

노드별 가용량 확인

# 노드별 상세 리소스 정보
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:"

3. 스크립트로 전체 클러스터 가용량 계산

완전한 가용량 분석 스크립트

#!/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

4. 원라이너 명령어들

빠른 가용량 확인

# 전체 클러스터 가용 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

5. kubectl top을 활용한 실시간 가용량

메트릭 서버 기반 확인

# 노드별 실시간 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

6. 네임스페이스별 가용량 분석

리소스 쿼터 고려한 가용량

#!/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 "리소스 쿼터가 없는 네임스페이스들은 클러스터 전체 가용량을 공유합니다."

7. 용량 계획 및 예측

워크로드 추가 시 예측

#!/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

8. 모니터링 대시보드 스크립트

실시간 가용량 모니터링

#!/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
'

9. Prometheus 쿼리 (메트릭 수집 환경)

프로메테우스 쿼리 예시

# 클러스터 총 가용 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% 미만이면 클러스터 확장을 고려해야 합니다!

profile
bytebliss

0개의 댓글