forked from onfido/k8s-rabbit-pod-autoscaler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
autoscale.sh
118 lines (96 loc) · 4.18 KB
/
autoscale.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/bin/bash
namespace=""
deployment=""
function getCurrentPods() {
# Retry up to 5 times if kubectl fails
for i in $(seq 5); do
current=$(kubectl -n $namespace describe deploy $deployment | \
grep desired | awk '{print $2}' | head -n1)
if [[ $current != "" ]]; then
echo $current
return 0
fi
sleep 3
done
echo ""
}
function notifySlack() {
if [ -z "$SLACK_HOOK" ]; then
return 0
fi
curl -s --retry 3 --retry-delay 3 -X POST --data-urlencode 'payload={"text": "'"$1"'"}' $SLACK_HOOK > /dev/null
}
autoscalingNoWS=$(echo "$AUTOSCALING" | tr -d "[:space:]")
IFS=';' read -ra autoscalingArr <<< "$autoscalingNoWS"
while true; do
for autoscaler in "${autoscalingArr[@]}"; do
IFS='|' read minPods maxPods mesgPerPod namespace deployment queueName <<< "$autoscaler"
queueMessagesJson=$(curl -s -S --retry 3 --retry-delay 3 -u "$RABBIT_USER:$RABBIT_PASS" \
$RABBIT_HOST:15672/api/queues/%2f/$queueName)
if [[ $? -eq 0 ]]; then
queueMessages=$(echo $queueMessagesJson | jq '.messages')
requiredPods=$(echo "$queueMessages/$mesgPerPod" | bc 2> /dev/null)
if [[ $requiredPods != "" ]]; then
currentPods=$(getCurrentPods)
if [[ $currentPods != "" ]]; then
if [[ $requiredPods -ne $currentPods ]]; then
desiredPods=""
# Flag used to prevent scaling down or up if currentPods are already min or max respectively.
scale=0
if [[ $requiredPods -le $minPods ]]; then
desiredPods=$minPods
# If currentPods are already at min, do not scale down
if [[ $currentPods -eq $minPods ]]; then
scale=1
fi
elif [[ $requiredPods -ge $maxPods ]]; then
desiredPods=$maxPods
# If currentPods are already at max, do not scale up
if [[ $currentPods -eq $maxPods ]]; then
scale=1
fi
else
desiredPods=$requiredPods
fi
if [[ $scale -eq 0 ]]; then
# To slow down the scale-down policy, scale down in steps (reduce 10% on every iteration)
if [[ $desiredPods -lt $currentPods ]]; then
desiredPods=$(awk "BEGIN { print int( ($currentPods - $desiredPods) * 0.9 + $desiredPods ) }")
fi
kubectl scale -n $namespace --replicas=$desiredPods deployment/$deployment 1> /dev/null
if [[ $? -eq 0 ]]; then
# Adjust logging and Slack notifications based on LOGS env and desiredPods number
log=false
avgPods=$(awk "BEGIN { print int( ($minPods + $maxPods) / 2 ) }")
if [[ $LOGS == "HIGH" ]]; then
log=true
elif [[ $LOGS == "MEDIUM" && ($desiredPods -eq $minPods || $desiredPods -eq $avgPods || $desiredPods -eq $maxPods) ]]; then
log=true
elif [[ $LOGS == "LOW" && ($desiredPods -eq $minPods || $desiredPods -eq $maxPods) ]]; then
log=true
fi
if $log ; then
echo "$(date) -- Scaled $namespace: $deployment to $desiredPods pods ($queueMessages msg in RabbitMQ)"
notifySlack "Scaled $namespace: $deployment to $desiredPods pods ($queueMessages msg in RabbitMQ)"
fi
else
echo "$(date) -- Failed to scale $namespace: $deployment pods."
notifySlack "Failed to scale $namespace: $deployment pods."
fi
fi
fi
else
echo "$(date) -- Failed to get current pods number for $namespace: $deployment."
notifySlack "Failed to get current pods number for $namespace: $deployment."
fi
else
echo "$(date) -- Failed to calculate required pods for $namespace: $deployment."
notifySlack "Failed to calculate required pods for $namespace: $deployment."
fi
else
echo "$(date) -- Failed to get queue messages from $RABBIT_HOST for $namespace: $deployment."
notifySlack "Failed to get queue messages from $RABBIT_HOST for $namespace: $deployment."
fi
done
sleep $INTERVAL
done