Skip to content

Instantly share code, notes, and snippets.

@simonhjoerg
Created March 9, 2016 09:26
Show Gist options
  • Select an option

  • Save simonhjoerg/1bd66b31a8d3dfe7a999 to your computer and use it in GitHub Desktop.

Select an option

Save simonhjoerg/1bd66b31a8d3dfe7a999 to your computer and use it in GitHub Desktop.
Serf event handler for nginx loadbalancing with multiple apps
#!/usr/bin/env bash
#This script will get executed each time a event happens
#on the serf cluster
if [ ${SERF_EVENT} = "member-join" ]; then
#We will go over each line that is returned to us from serf
while read line; do
#Lets assign some variables
#First we shall get the nodename
nodename=`echo $line | awk '{print \$1 }'`
#Next the IP
ip=`echo $line | awk '{print \$2 }'`
#Then the tag1
tag1=`echo $line | awk '{print \$4 }' |cut -d "," -f "1"`
#Tag2
tag2=`echo $line | awk '{print \$4 }' |cut -d "," -f "2"`
# I'll assign this as a dict, so that i can reference it directly (serf doesnt give the tags in same order each time)
declare -A tags
tags=( [`echo $tag1 |cut -d "=" -f 1`]=`echo $tag1 |cut -d "=" -f 2` [`echo $tag2 |cut -d "=" -f 1`]=`echo $tag2 |cut -d "=" -f 2` )
#If its a new LB that joined (This is if its nginx that are joining itself into the cluster)
#The reason behind having this, is that if the docker container crashed
#We want to be able to spawn a new one in its place, which will find the nodes already active and bring them up
if [ ${tags[role]} = "lb" ]; then
#Executing the serf members to find the active members
serf members |grep webserver |grep alive | while read line; do
#Getting the IP
ip=`echo $line |cut -d " " -f 2 |cut -d ":" -f 1`
#Getting tags and setting as dict
tag1=`echo $line | awk '{print \$4 }' |cut -d "," -f "1"`
tag2=`echo $line | awk '{print \$4 }' |cut -d "," -f "2"`
declare -A tags
tags=( [`echo $tag1 |cut -d "=" -f 1`]=`echo $tag1 |cut -d "=" -f 2` [`echo $tag2 |cut -d "=" -f 1`]=`echo $tag2 |cut -d "=" -f 2` )
#At this point if its a app1 server we add it to app1
if [ ${tags[app]} = "app1" ]; then
sed -i 's/upstream app1 {/upstream app1 {\n \t\tserver '$ip';/' /etc/nginx/nginx.conf
/etc/init.d/nginx reload
fi
#At this point if its a app1 server we add it to app2
if [ ${tags[app]} = "app2" ]; then
echo "updating conf" >> log.txt
sed -i 's/upstream app2 {/upstream app2 {\n \t\tserver '$ip';/' /etc/nginx/nginx.conf
/etc/init.d/nginx reload
fi
done
fi
#If its a new webserver that joined
if [ ${tags[role]} = "webserver" ]; then
if [ ${tags[app]} = "app1" ]; then
sed -i 's/upstream app1 {/upstream app1 {\n \t\tserver '$ip';/' /etc/nginx/nginx.conf
/etc/init.d/nginx reload
fi
if [ ${tags[app]} = "app2" ]; then
echo "updating conf" >> log.txt
sed -i 's/upstream app2 {/upstream app2 {\n \t\tserver '$ip';/' /etc/nginx/nginx.conf
/etc/init.d/nginx reload
fi
fi
done
#Update procedure
#This is used as a failsafe, if for some reason a member isnt joined correctly first time
#We can trigger this custom event at a random basis, which will ensure that we manually refresh based on membership status
elif [ ${SERF_EVENT} = "user" ]; then
if [ ${SERF_USER_EVENT} = "refreshConfig" ]; then
serf members |grep webserver |grep alive | while read line; do
#Getting the IP
ip=`echo $line |cut -d " " -f 2 |cut -d ":" -f 1`
#First ill remove IP
sed -i '/server '$ip';/d' /etc/nginx/nginx.conf
#Getting tags and setting as dict
tag1=`echo $line | awk '{print \$4 }' |cut -d "," -f "1"`
tag2=`echo $line | awk '{print \$4 }' |cut -d "," -f "2"`
declare -A tags
tags=( [`echo $tag1 |cut -d "=" -f 1`]=`echo $tag1 |cut -d "=" -f 2` [`echo $tag2 |cut -d "=" -f 1`]=`echo $tag2 |cut -d "=" -f 2` )
#At this point if its a app1 server we add it to app1
if [ ${tags[app]} = "app1" ]; then
sed -i 's/upstream app1 {/upstream app1 {\n \t\tserver '$ip';/' /etc/nginx/nginx.conf
fi
#At this point if its a app1 server we add it to app2
if [ ${tags[app]} = "app2" ]; then
echo "updating conf" >> log.txt
sed -i 's/upstream app2 {/upstream app2 {\n \t\tserver '$ip';/' /etc/nginx/nginx.conf
fi
done
/etc/init.d/nginx reload
fi
#if a member leaves gracefully
elif [ ${SERF_EVENT} = "member-leave" ]; then
while read line; do
#Lets assign some variables
nodename=`echo $line | awk '{print \$1 }'`
ip=`echo $line | awk '{print \$2 }'`
tag1=`echo $line | awk '{print \$4 }' |cut -d "," -f "1"`
tag2=`echo $line | awk '{print \$4 }' |cut -d "," -f "2"`
declare -A tags
tags=( [`echo $tag1 |cut -d "=" -f 1`]=`echo $tag1 |cut -d "=" -f 2` [`echo $tag2 |cut -d "=" -f 1`]=`echo $tag2 |cut -d "=" -f 2` )
sed -i '/server '$ip';/d' /etc/nginx/nginx.conf
/etc/init.d/nginx reload
done
#if a member leaves by failing (eg crashing, network issue and so on)
elif [ ${SERF_EVENT} = "member-failed" ]; then
while read line; do
#Lets assign some variables
nodename=`echo $line | awk '{print \$1 }'`
ip=`echo $line | awk '{print \$2 }'`
tag1=`echo $line | awk '{print \$4 }' |cut -d "," -f "1"`
tag2=`echo $line | awk '{print \$4 }' |cut -d "," -f "2"`
declare -A tags
tags=( [`echo $tag1 |cut -d "=" -f 1`]=`echo $tag1 |cut -d "=" -f 2` [`echo $tag2 |cut -d "=" -f 1`]=`echo $tag2 |cut -d "=" -f 2` )
sed -i '/server '$ip';/d' /etc/nginx/nginx.conf
/etc/init.d/nginx reload
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment