Created
March 9, 2016 09:26
-
-
Save simonhjoerg/1bd66b31a8d3dfe7a999 to your computer and use it in GitHub Desktop.
Serf event handler for nginx loadbalancing with multiple apps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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