Skip to content

CPU Memory Stat

Node Stat

bash
#!/bin/bash

echo -e "NODE\t\t\tCPU Requests\tCPU Limits\tMemory Requests\tMemory Limits"

for node in $(kubectl get nodes -o name | cut -d'/' -f2); do
  kubectl describe node "$node" |
  awk -v node="$node" '
    BEGIN {
      cpu_req = cpu_lim = mem_req = mem_lim = "";
      in_alloc = 0;
    }

    /^Allocated resources:/ { in_alloc = 1; next }
    in_alloc && /^  [a-z]/ {
      resource = $1;
      if (resource == "cpu") {
        cpu_req = $2 " " $3;
        cpu_lim = $4 " " $5;
      }
      if (resource == "memory") {
        mem_req = $2 " " $3;
        mem_lim = $4 " " $5;
      }
    }
    in_alloc && NF == 0 { in_alloc = 0 }

    END {
      printf "%-20s\t%-12s\t%-12s\t%-16s\t%-16s\n", node, cpu_req, cpu_lim, mem_req, mem_lim;
    }
  '
done

Pod Stat

bash
#!/bin/bash

NODE_NAME="$1"

if [ -z "$NODE_NAME" ]; then
  echo "用法: $0 <node-name>"
  exit 1
fi

{
  echo -e "NAMESPACE\tPOD\tCPU(m)\tMemory(Mi)"

  kubectl get pods --all-namespaces --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.resources.requests.cpu}{"\t"}{.resources.requests.memory}{"\t"}{end}{"\n"}{end}' |
  awk '
  function toMillicpu(v) {
    if (v ~ /m$/) return substr(v, 1, length(v)-1)
    else if (v ~ /^[0-9.]+$/) return v * 1000
    return 0
  }
  function toMi(v) {
    if (v ~ /Mi$/) return substr(v, 1, length(v)-2)
    else if (v ~ /Gi$/) return substr(v, 1, length(v)-2) * 1024
    return 0
  }
  {
    ns=$1
    pod=$2
    cpu_sum=0
    mem_sum=0
    for (i=3; i<=NF; i+=2) {
      cpu_sum += toMillicpu($i)
      mem_sum += toMi($(i+1))
    }
    printf "%s\t%s\t%d\t%d\n", ns, pod, cpu_sum, mem_sum
  }' | sort -k3 -nr | head -n 20
} | column -t

Magic

bash
#!/bin/bash

NODE_NAME="$1"

if [ -z "$NODE_NAME" ]; then
  echo "用法: $0 <node-name>"
  exit 1
fi

## 收集实际使用
declare -A METRICS

while read -r ns pod cpu mem; do
  key="${ns}/${pod}"
  cpu_val=$(echo "$cpu" | sed 's/m//')
  mem_val=$(echo "$mem" | sed 's/Mi//')
  METRICS["$key"]="$cpu_val $mem_val"
done < <(kubectl top pod --no-headers --all-namespaces | awk '$0=$1 FS $2 FS $3 FS $4')

## 输出 + 排序
{
  echo -e "NAMESPACE\tPOD\tCPU_REQ(m)\tMEM_REQ(Mi)\tCPU_USED(m)\tMEM_USED(Mi)"

  kubectl get pods --all-namespaces --field-selector spec.nodeName="$NODE_NAME" -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.resources.requests.cpu}{"\t"}{.resources.requests.memory}{"\t"}{end}{"\n"}{end}' |
  awk '
  function toMillicpu(v) {
    if (v ~ /m$/) return substr(v, 1, length(v)-1)
    else if (v ~ /^[0-9.]+$/) return v * 1000
    return 0
  }
  function toMi(v) {
    if (v ~ /Mi$/) return substr(v, 1, length(v)-2)
    else if (v ~ /Gi$/) return substr(v, 1, length(v)-2) * 1024
    return 0
  }
  {
    ns=$1
    pod=$2
    cpu_sum=0
    mem_sum=0
    for (i=3; i<=NF; i+=2) {
      cpu_sum += toMillicpu($i)
      mem_sum += toMi($(i+1))
    }
    printf "%s\t%s\t%d\t%d\n", ns, pod, cpu_sum, mem_sum
  }' |
  sort -k3 -nr | head -n 20 |
  while IFS=$'\t' read -r ns pod cpu_req mem_req; do
    key="${ns}/${pod}"
    usage="${METRICS[$key]}"
    if [ -z "$usage" ]; then
      cpu_used="N/A"
      mem_used="N/A"
    else
      cpu_used=$(echo "$usage" | awk '{print $1}')
      mem_used=$(echo "$usage" | awk '{print $2}')
    fi
    echo -e "${ns}\t${pod}\t${cpu_req}\t${mem_req}\t${cpu_used}\t${mem_used}"
  done
} | column -t