Skip to content

Instantly share code, notes, and snippets.

@76creates
Created August 19, 2024 13:48
Show Gist options
  • Save 76creates/3e1cebb14f2ede1ea19822b48dfeddb3 to your computer and use it in GitHub Desktop.
Save 76creates/3e1cebb14f2ede1ea19822b48dfeddb3 to your computer and use it in GitHub Desktop.
Kubernetes Skew calculator
### This script attempts to calculate the skew of the population of pods across the nodes in a Kubernetes cluster.
### It takes taints into account, but does not consider pod labels.
NAMESPACE="app"
_all_nodes=$(kubectl get nodes | wc -l)
_all_nodes=$(( _all_nodes - 1 ))
for deployment_name in $(kubectl get -n ${NAMESPACE} deployment --template='{{range.items}}{{.metadata.name}}{{"\n"}}{{end}}'); do
_deployment=$(kubectl get -n app -o json deployment ${deployment_name} | jq -c '.')
_nodeTaintsPolicy=$(echo "${_deployment}" | jq -r '.spec.template.spec.topologySpreadConstraints[0].nodeAffinityPolicy')
if [ "${_nodeTaintsPolicy}" == "Honor" ]; then
_compatible_nodes=""
for deployment_toleration in $(echo "${_deployment}" | jq -c '.spec.template.spec.tolerations[]')
do
_filter=""
_key=$(echo "${deployment_toleration}" | jq -r 'if(.key == null) then empty else .key end')
[ "${_key}" != "" ] && _filter=".key == \"${_key}\" and"
_operator=$(echo "${deployment_toleration}" | jq -r 'if(.operator == null) then empty else .operator end')
if [ "${_operator}" == "Exists" ]; then
_value=""
else
_value=$(echo "${deployment_toleration}" | jq -r 'if(.value == null) then empty else .value end')
fi
[ "${_value}" != "" ] && _filter="${_filter} .value == \"${_value}\" and"
_effect=$(echo "${deployment_toleration}" | jq -r 'if(.effect == null) then empty else .effect end')
[ "${_effect}" != "" ] && _filter="${_filter} .effect == \"${_effect}\" and"
_filter=$(echo "${_filter}" | sed 's/ and$//')
_new_nodes=$(kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | select(.spec.taints[] | '"${_filter}"') | .metadata.name')
_compatible_nodes=$(echo ${_compatible_nodes}" "${_new_nodes})
done
_number_of_compatible_nodes=$(echo "${_compatible_nodes}" | sort -u | tr ' ' '\n' | wc -l)
else
_number_of_compatible_nodes=$(kubectl get nodes | wc -l)
fi
_population=$(kubectl get pods -n app -l app.kubernetes.io/name=${deployment_name} --template='{{range .items}}{{.spec.nodeName}}{{"\n"}}{{end}}' | sort | uniq -c | awk '{print $1}' | sort -n)
_population_size=$(echo "${_population}" | wc -l)
_max_population=$(echo "${_population}" | tail -n 1)
_replicas=$(echo "${_deployment}" | jq -r '.spec.replicas')
if [[ "${_replicas}" > "${_all_nodes}" ]] && [[ "${_population_size}" != "${_all_nodes}" ]]; then
_min_population="0"
else
_min_population=$(echo "${_population}" | head -n 1)
fi
_skew="$((_max_population-_min_population))"
echo "${deployment_name} skew: $_skew"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment