-
-
Save redmcg/60cfff7bca6f32969188008ad4a44c9a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
NODESAPI=/api/v1/nodes | |
function getNodes() { | |
kubectl get --raw $NODESAPI | jq -r '.items[].metadata.name' | |
} | |
function getPVCs() { | |
jq -s '[flatten | .[].pods[].volume[]? | select(has("pvcRef")) | '\ | |
'{name: .pvcRef.name, capacityBytes, usedBytes, availableBytes, '\ | |
'percentageUsed: (.usedBytes / .capacityBytes * 100)}] | sort_by(.name)' | |
} | |
function column() { | |
awk '{ for (i = 1; i <= NF; i++) { d[NR, i] = $i; w[i] = length($i) > w[i] ? length($i) : w[i] } } '\ | |
'END { for (i = 1; i <= NR; i++) { printf("%-*s", w[1], d[i, 1]); for (j = 2; j <= NF; j++ ) { printf("%*s", w[j] + 1, d[i, j]) } print "" } }' | |
} | |
function defaultFormat() { | |
awk 'BEGIN { print "PVC 1K-blocks Used Available Use%" } '\ | |
'{$2 = $2/1024; $3 = $3/1024; $4 = $4/1024; $5 = sprintf("%.0f%%",$5); print $0}' | |
} | |
function humanFormat() { | |
awk 'BEGIN { print "PVC Size Used Avail Use%" } '\ | |
'{$5 = sprintf("%.0f%%",$5); printf("%s ", $1); system(sprintf("numfmt --to=iec %s %s %s | sed '\''N;N;s/\\n/ /g'\'' | tr -d \\\\n", $2, $3, $4)); print " " $5 }' | |
} | |
function format() { | |
jq -r '.[] | "\(.name) \(.capacityBytes) \(.usedBytes) \(.availableBytes) \(.percentageUsed)"' | | |
$format | column | |
} | |
if [ "$1" == "-h" ]; then | |
format=humanFormat | |
else | |
format=defaultFormat | |
fi | |
for node in $(getNodes); do | |
kubectl get --raw $NODESAPI/$node/proxy/stats/summary | |
done | getPVCs | format |
kubectl
has support for plugins, which can be managed via krew (a kubectl
plugin itself). It looks like a plugin that could be used in place of this script has already been created:
https://github.com/yashbhutwala/kubectl-df-pv
That's neat. That plugin's README says it's only compatible with GKE right now though. This script's approach is just pure Kubernetes, right?
Yeah, I'm using the kubernates rest api. But I took a quick look at the code for kubectl-df-pv
, and it looks like it's using the same approach. I couldn't see anything that suggested this script would provide a greater level of support; but testing would confirm.
@redmcg
I have managed to add namespace column to your existing code
kubectl get --raw $NODESAPI/$node/proxy/stats/summary|jq -s '[flatten | .[].pods[].volume[]? | select(has("pvcRef")) | ''{namespace: .pvcRef.namespace, name: .pvcRef.name, capacityBytes, usedBytes, availableBytes, ''percentageUsed: (.usedBytes / .capacityBytes * 100)}] | sort_by(.namespace)'|jq -r '.[] | "(.namespace) (.name) (.capacityBytes) (.usedBytes) (.availableBytes) (.percentageUsed)"'|awk '{$3 = $3/(102410241024); $4 = $4/(10241024); $5= $5/(10241024*1024); $6 = sprintf("%.0f%%",$6); print $0}'
Namsespace PVC Capacity Used Available Used%
Thank you @redmcg
Good work @vsadanala ! And thanks for sharing.
nice ! thanks
I would had this > 50% usage
bash kubedf -h |tr -d '%' |awk '$NF > 50' | sed -e 's/$/%/'
Hi,
I just added an option to list the pvc information filtered with a namespace based on the script above:
#!/usr/bin/env bash
function getNodes() {
kubectl get --raw=/api/v1/nodes | jq -r '.items[].metadata.name'
}
function getPVCs() {
jq -s '[flatten | .[].pods[].volume[]? | select(has("pvcRef")) | '
'{namespace: .pvcRef.namespace, name: .pvcRef.name, capacityBytes, usedBytes, availableBytes, '
'percentageUsed: (.usedBytes / .capacityBytes * 100)}] | sort_by(.namespace)'
}
function column() {
awk '{ for (i = 1; i <= NF; i++) { d[NR, i] = $i; w[i] = length($i) > w[i] ? length($i) : w[i] } } '
'END { for (i = 1; i <= NR; i++) { printf("%-*s", w[1], d[i, 1]); for (j = 2; j <= NF; j++ ) { printf("%*s", w[j] + 1, d[i, j]) } print "" } }'
}
function defaultFormat() {
awk 'BEGIN { print "Namespace PVC 1K-blocks Used Available Use%" } '
'{$3 = $3/1024; $4 = $4/1024; $5 = $5/1024; $6 = sprintf("%.0f%%",$6); print $0}'
}
function humanFormat() {
awk 'BEGIN { print "Namespace PVC Size Used Avail Use%" } '
'{$6 = sprintf("%.0f%%",$6); printf("%s ", $1); printf("%s ", $2); system(sprintf("numfmt --to=iec %s %s %s | sed '''N;N;s/\n/ /g''' | tr -d \\n", $3, $4, $5)); print " " $6 }'
}
function format() {
jq '.[] | "(.namespace) (.name) (.capacityBytes) (.usedBytes) (.availableBytes) (.percentageUsed)"' |
sed 's/^"|"$//g' |
$format | column
}
function get_pvc_info(){
local _format=${1:-h} && shift
local namespace=${1:-""}
format=humanFormat
[[ "${_format,,}" != "h" ]] && format=defaultFormat
table=$(for node in $(getNodes); do
kubectl get --raw=/api/v1/nodes/${node}/proxy/stats/summary
done | getPVCs | format)
header=$(echo -e "${table}" | head -1)
echo -e "${header}"
[[ -n "${namespace}" ]] && echo -e "${table}" | grep -w "^${namespace} " || echo -e "${table}"
}
get_pvc_info "$@"
I wonder if it's a good idea to take this script and use it as the beginning of a new open source CLI tool (or, use it as inspiration for adding a feature to an existing CLI tool if one exists). This use case seems so popular. People like to be able to scan through all the data they've stored in their clusters' disks and learn more about the disks.