Skip to content

Instantly share code, notes, and snippets.

@sequix
Last active June 13, 2025 03:41
Show Gist options
  • Save sequix/2399597340521140bd21f322f4ce820c to your computer and use it in GitHub Desktop.
Save sequix/2399597340521140bd21f322f4ce820c to your computer and use it in GitHub Desktop.
K8S resource allocations details.
#!/usr/bin/env bash
#:set expandtab tabstop=4 shiftwidth=4 autoindent
# Prerequisites:
# brew install coreutils # for numfmt
# brew install jq
# brew install bash
set -euo pipefail
to1() {
local n=${1:-0}
if [[ "$n" == *m ]]; then
<<<"scale=3; ${n::-1} / 1000" bc
else
<<<"$n" numfmt --from=auto
fi
}
to1_sum() {
local n
local s=0
while IFS= read -r n; do
s=$(<<<"scale=3; $s + $(to1 $n)" bc)
done
echo -n "$s"
}
toh() {
<<<"${1:-0}" numfmt --to=iec-i
}
node_all_resources() {
local node="$1"
local key val
local pods_json node_json remained
declare -A capacity allocatable requests
node_json=$(kubectl get no -ojson "$node")
pods_json=$(kubectl get po --all-namespaces --field-selector spec.nodeName="$node" -ojson)
requests[pods]=$(kubectl get po --all-namespaces --field-selector spec.nodeName="$node" --no-headers | wc -l)
while read -r key val; do
capacity[$key]=$(to1 "$val")
done < <(<<<"$node_json" jq '.status.capacity' | sed '1d;$d;s/[,:"]//g')
while read -r key val; do
allocatable[$key]=$(to1 "$val")
[[ "$key" == "pods" ]] && continue
requests[$key]=$(<<<"$pods_json" jq -r ".items[].spec.containers[].resources.requests.\"$key\" | values" | to1_sum)
done < <(<<<"$node_json" jq '.status.allocatable' | sed '1d;$d;s/[,:"]//g')
{
echo "Node Capacity Allocatable Requested Remained"
for key in "${!allocatable[@]}"; do
remained=$((${allocatable[$key]} - ${requests[$key]}))
case "$key" in
"cpu" | "pods")
echo "$key ${capacity[$key]} ${allocatable[$key]} ${requests[$key]} $remained"
;;
*)
echo "$key $(toh ${capacity[$key]}) $(toh ${allocatable[$key]}) $(toh ${requests[$key]}) $(toh $remained)"
;;
esac
done
} | column -t | { read -r;echo "$REPLY";sort; }
}
node_single_resource() {
local node="$1"
local resource="$2"
local requests_total=0
local key val remained
local namespace pod container capacity allocatable
declare -A requests
while read -r namespace pod container val; do
[[ "$val" == "null" || "$val" == 0 ]] && continue
requests["$namespace $pod $container"]="$val"
requests_total=$((requests_total + $(to1 "$val")))
done < <(kubectl get po --all-namespaces --field-selector spec.nodeName="$node" -ojson \
| jq -c ".items[] as \$p | \$p.spec.containers[] as \$c
| [\$p.metadata.namespace,\$p.metadata.name,\$c.name,\$c.resources.requests.\"$resource\"]" \
| sed 's/[]["]//g;s/,/ /g')
{
echo "Namespace Pod Container Requests"
for key in "${!requests[@]}"; do
echo "$key ${requests[$key]}"
done
} | column -t | { read -r; echo "$REPLY"; sort -k4hr,4 -k1,1 -k2,2 -k3,3; }
read -r capacity allocatable < <(kubectl get no "$node" -ojson \
| jq -rc "[.status.capacity.\"$resource\",.status.allocatable.\"$resource\"]" \
| sed 's/[]["]//g;s/,/ /g')
remained=$(to1 "$allocatable")
remained=$((remained - requests_total))
remained=$(toh "$remained")
requests_total=$(toh "$requests_total")
echo
echo "Capacity:$capacity Allocatable:$allocatable Requested:$requests_total Remained:$remained"
}
all_node_single_resource() {
local cnt=0
local resource="$1"
local val node remained cap alloc
declare -A capacity allocatable requests
local f_pipe=$(mktemp -u)
mkfifo -m 600 "$f_pipe"
exec 3<>"$f_pipe"
rm -f "$f_pipe"
while read -r node cap alloc; do
[[ "$cap" == "null" ]] && continue
capacity[$node]=$(to1 "$cap")
allocatable[$node]=$(to1 "$alloc")
{
echo $node $(kubectl get po --all-namespaces --field-selector spec.nodeName="$node" -ojson \
| jq -r ".items[].spec.containers[].resources.requests.\"$resource\" | values" \
| to1_sum)
} >&3 &
cnt=$((cnt+1))
done < <(kubectl get no -ojson \
| jq -c ".items[]|[.metadata.name,.status.capacity.\"$resource\",.status.allocatable.\"$resource\"]" \
| sed 's/[]["]//g;s/,/ /g')
while [[ "$cnt" -gt 0 ]]; do
read -ru3 node val
requests[$node]="$val"
cnt=$((cnt-1))
done
exec 3<&- 3>&-
{
echo "Node Capacity Allocatable Requested Remained"
for node in "${!requests[@]}"; do
if [[ "${capacity[$node]}" -eq 0 && "${requests[$node]:-0}" -eq 0 ]]; then
continue
fi
remained=$((${allocatable[$node]} - ${requests[$node]:-0}))
case "$resource" in
"cpu" | "pods")
echo "$node ${capacity[$node]} ${allocatable[$node]} ${requests[$node]} $remained"
;;
*)
echo "$node $(toh ${capacity[$node]}) $(toh ${allocatable[$node]}) $(toh ${requests[$node]}) $(toh $remained)"
;;
esac
done
} | column -t | { read -r;echo "$REPLY"; sort -k5hr,5 -k1,1; }
}
main() {
local opt node resource
while getopts "n:r:" opt; do
case $opt in
"n")
node="$OPTARG"
;;
"r")
resource="$OPTARG"
;;
esac
done
if [[ "${node-}" ]]; then
if [[ "${resource-}" ]]; then
node_single_resource "$node" "$resource"
else
node_all_resources "$node"
fi
elif [[ "${resource-}" ]]; then
all_node_single_resource "$resource"
else
echo "Usage: $0 -n <node> -r <resource> # show all containers requesting <resource> on <node>"
echo "Usage: $0 -r <resource> # show <resource> on all nodes"
echo "Usage: $0 -n <node> # show all types of resources <node>"
exit 1
fi
}
main "$@"
@ahmetb
Copy link

ahmetb commented May 9, 2025

krew plugin submission when?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment