How can you enrich the kubectl top pod command with node information?
This function has helped me recently:
ktp() {
(
echo "$(kubectl top pod $# | head -1) NODE";
kubectl top pod $# --no-headers | head -10 \
| while read LINE
do
NODE=$(kubectl -n $(echo $LINE | awk '{print $1}') get pod $(echo $LINE | awk '{print $2}') -o=jsonpath='{.spec.nodeName}')
echo "$LINE $NODE";
done;
) | column -t;
}
or as a long one-liner
ktp() { ( echo "$(kubectl top pod $# | head -1) NODE"; kubectl top pod $# --no-headers | head -10 | while read LINE; do NODE=$(kubectl -n $(echo $LINE | awk '{print $1}') get pod $(echo $LINE | awk '{print $2}') -o=jsonpath='{.spec.nodeName}'); echo "$LINE $NODE"; done; ) | column -t; }
Then you need to replace kubectl top pod by ktp like in the following example:
ktp --all-namespaces --sort-by=memory
Output:
NAMESPACE NAME CPU(cores) MEMORY(bytes) NODE
kube-system kube-apiserver-master1 906m 1620Mi master1
nginx-ingress nginx-ingress-fvvmx 16m 1232Mi node1
nginx-ingress nginx-ingress-jv5tv 1m 1032Mi node2
get-desktop get-desktop-7768474668-7w8mf 3m 715Mi node1
kube-system kube-controller-manager-master1 170m 707Mi master1
kube-janitor kube-janitor-78df48c8d7-fj9w4 451m 674Mi node2
cert-manager cert-manager-b4d6fd99b-d6gb7 2m 202Mi node2
kube-system weave-net-l8zx8 3m 174Mi node2
kube-system etcd-master1 310m 164Mi master1
cert-manager cert-manager-cainjector-74bfccdfdf-c74dt 3m 137Mi node1
Drawbacks:
auto-completion does not work for ktp
performance is poor with n+1 API requests. That is, why I have limited the number of answers to 10. With that, the performance is bearable.
Maybe you will find a better solution?
Related
I'm trying to delete the evicted pods which are older than a month, I have the following statement but I have doubts about its validity, can you please check and advise back?
kubectl get pods --all-namespaces | awk -F "d" '{print $1}' $6 | grep -E Evicted >>output.data | while read line; do ns=$(echo $line | cut -d , -f 1); pod=$(echo $line | cut -d , -f 2); age=$(echo $line | cut -d, -f 6); if [[$age -gt 30]]; then kubectl delete pod --dry-run='server' -n $ns $pod; fi done
using awk in xargs construct: getting different output when am tyring to pull in awk inside xargs - -
step1
~/waste/dgx-users2.log | head -n2
node1
node2
step2
cat ~/waste/dgx-users2.log | head -n2 | xargs -l1 -- sh -c 'echo $1 && kubectl get pods --field-selector=spec.nodeName=$1,status.phase=Running --all-namespaces --no-headers' --
node1
node2
test-s test-s-pod 3/3 Running 0 6d1h
dummy-s test-s-pod 1/1 Running 0 5d9h
but i only want test-s in $1 to be listed so filter below
cat ~/waste/dgx-users2.log | head -n2 | xargs -l1 -- sh -c 'echo $1 && kubectl get pods --field-selector=spec.nodeName=$1,status.phase=Running --all-namespaces --no-headers' -- | awk '$1 ~ /test-*/ && /Running/ {print}'
test-s test-pod 3/3 Running 0 6d
Above is all good but is there a way I can pull the awk inside xargs — ? I tried below but its missing the last output line that shows in my expected output.
cat ~/waste/dgx-users2.log | head -n2 | xargs -l1 -- sh -c 'echo $1 && kubectl get pods --field-selector=spec.nodeName=$1,status.phase=Running --all-namespaces --no-headers | awk "$1 ~ /test-*/ && /Running/ {print}"' --
node1
node2
Am not getting the same output.. so need to adjust some syntax, i guess..
my expected output should be.
my goal is to print that node info along with output such that i know on what node that pod is running like below node1 has nothing and node2 has a pod it.
node1
node2
test-s test-pod 3/3 Running 0 6d
Because the $1 in the awk expression is being parsed in a double-quoted context by the internal copy of sh, it needs to be escaped. That is:
head -n2 <~/waste/dgx-users2.log | xargs -l1 -- sh -c '
echo "$1" &&
kubectl get pods --field-selector=spec.nodeName="$1",status.phase=Running \
--all-namespaces --no-headers |
awk "\$1 ~ /test-*/ && /Running/ {print}"
' --
I have a simple script that checks the process id of some process using ps. When I run it directly on command line, it works fine but does not when I run it in a script. What am I doing wrong?
This works fine:
ps auwx | grep elasticsearch | grep -v grep | grep user | awk '{print $2}' | tail -1
In script, it does not:
#!/bin/bash
#Setting ES Heap to 50GB
ES_HEAP_SIZE="50g"
#Finding dump file to be deleted
FILE_ID=$(ps auwx | grep elasticsearch | grep -v grep | grep user | awk '{print $2}' | tail -1)
FILE_NAME="java_pid$FILE_ID.hprof"
echo "Elasticsearch pid: $FILE_ID"
echo "Dump file name if it exists: $FILE_NAME. Checking now."
if [ -s $FILE_NAME ]
then
rm $FILE_NAME
kill -9 $FILE_ID
#Starting elasticsearch daemon
/data/elasticsearch-1.4.4/bin/elasticsearch -d
else
echo "All good. Dump file $FILE_NAME does not exist."
fi
Personal pet peeve: why do you have six executions in your pipeline when two will handle everything you need?
ps auwx | awk '/elasticsearch/ && /user/ { x=$2 } END{ print x; }'
As an aside, you wanted PID? Because it looks like you're reading PPID.
Hope that helps.
I have a bash script as follows:
if [[ "$1" == "stop" ]]; then
echo "[$(date +'%d/%m/%Y %H:%M:%S:%s')]: Killing all active watchers" >> $LOG
kill -9 $(ps -ef | grep "processname1" | grep -v "grep" | grep -v "$$" | awk
'{print $2}' | xargs)
echo "[$(date +'%d/%m/%Y %H:%M:%S:%s')]: Killing all current processname2
processes" >> $LOG
kill -9 $(ps -ef | grep "processname2" | grep -v "grep" | awk '{print $2}' |
xargs)
exit 0
when i run 'x service stop', the following is outputted:
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill
-l [sigspec]
Killed
How do i stop the kill usage being displayed? It is successfully killing the process, however the fact that the usage is displayed is causing AWS CodeDeploy to fail.
Thanks!
Adam, please note that this is really just a comment with formatting. Don't take this as a real answer to your question. Please focus on the constructive comments to your question.
In my mis-spent youth, I wrote this bash function to do the ps -ef | grep .... madness:
# ps-grep
psg() {
local -a patterns=()
(( $# == 0 )) && set -- $USER
for arg do
patterns+=("-e" "[${arg:0:1}]${arg:1}")
done
ps -ef | grep "${patterns[#]}"
}
using the knowledge that the pattern [p]rocessname will not match the string [p]rocessname
From a file I'm retrieving the last line using the following cmd;
tail -n 1 build.log
The output looks like this:
1477101542,,ui,say,--> amazon-ebs: AMIs were created:\n\nus-east-1: ami-63237174\nus-west-1: ami-21236841\nus-west-2: ami-27872347
I'm trying to fetch the string after us-east-1:, us-west-1: & us-west-2 using the following grep commands:
echo | tail -n 1 build.log | egrep -m1 -oe 'us-east-1: ami-.{8}' | egrep -m1 -oe 'ami-.{8}'
I run this cmd three times for each condition. Is there a better way to do this?
If the order in which the regions appear is fixed, you can simply do:
$ echo | tail -n 1 build.log | egrep -o 'ami-.{8}'
ami-63237174
ami-21236841
ami-27872347
If you want to extract the region names and you have GNU grep, try:
$ echo | tail -n 1 build.log | grep -Po 'us-[^:]+(?=: ami-.{8})'
us-east-1
us-west-1
us-west-2
To get both region names and associated values:
$ echo | tail -n 1 build.log | egrep -o 'us-[^:]+: ami-.{8}'
us-east-1: ami-63237174
us-west-1: ami-21236841
us-west-2: ami-27872347