• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..24-Jan-2016-

user_data/H24-Jan-2016-4723

README.mdH A D24-Jan-20165.2 KiB140104

cloudformation.jsonH A D24-Jan-20168.7 KiB248224

setup_load_balancer.shH A D24-Jan-2016939 4829

setup_serf.shH A D24-Jan-20163 KiB12180

setup_web_server.shH A D24-Jan-2016503 198

README.md

1# Serf Demo: Web Servers + Load Balancer
2
3In this demo, Serf is used to coordinate web servers entering a load
4balancer. The nodes in this example can come up in any order and they'll
5eventually converge to a running cluster. When visiting the load balancer,
6you'll see each of the nodes visited in round-robin.
7
8After telling the cluster to launch, no further human interaction is
9required. The cluster will launch and orchestrate itself into a load
10balanced web server setup.
11
12The nodes are launched on AWS using CloudFormation and therefore will
13incur a real cost. You can control this cost based on how many nodes
14you decide to launch.
15
16## Running the Demo
17
18To run the demo, log into your AWS console, go to the CloudFormation
19tab, and create a new stack using the "cloudformation.json" file in this
20directory.
21
22Configure how many web nodes you'd like to launch then create the stack.
23When the stack is finished creating, the load balancer IP will be in
24the "outputs" tab of that stack.
25
26Visit `http://IP:9999/` to see the HAProxy stats page and list of
27configured backends. Or visit the IP directly in your browser to see
28it round robin between the web nodes.
29
30It will take some time for the load balancer and web servers to install
31their software and configure themselves. If the load balancer stats page
32is not up yet, give it a few seconds and try again. Once it is up, it
33will automatically refresh so you can watch as nodes eventually come
34online.
35
36## How it Works
37
38### Node Setup
39
40All the nodes (webs and load balancer) come up at the same time, with no
41explicit ordering defined. If there is an order, it doesn't actually matter
42for the function of the demo. The web servers can all come up before the load
43balancer, the load balancer can come up in the middle of some web servers, etc.
44
45Each of the nodes does an initial setup using a shell script. In a real
46environment, this initial setup would probably be done with a real
47configuration management system. For the purposes of this demo, we use
48shell scripts for ease of understanding.
49
50The load balancer runs `setup_load_balancer.sh` which installs HAProxy.
51HAProxy is configured with no backend servers. Serf will handle this later.
52
53The web server runs `setup_web_server.sh` which installs Apache and
54sets up an index.html to just say what host it is.
55
56At this stage, the load balancer is running HAProxy, and the web servers
57are running Apache, but they're not aware of each other in any way.
58
59Next, all nodes run `setup_serf.sh` which installs Serf and configures it
60to run. This script also starts the Serf agent. For web servers, it also
61starts a task that continuosly tries to join the Serf cluster at address
62`10.0.0.5`, which happens to be the static IP assigned to the load balancer.
63Note that Serf can join _any_ node in the cluster. We just set a static IP
64on the load balancer for ease of automation, but in a real production
65environment you can use any existing node, potentially just using DNS.
66
67Web server roles also make use of a "serf-query" upstart task to dynamically
68update the index page they serve. By using a "load" query, each node asks
69the rest of the cluster for their current load. This information is used
70to dynamically generate the index page.
71
72### Serf Configuration
73
74The Serf configuration is very simple. Each node runs a Serf agent. The
75web servers run the agent with a role of "web" and the load balancer runs
76the agent with a role of "lb".
77
78#### Event: member-join
79
80On member-join, the following shell script is run. We'll talk about the
81function of the shell script after the code sample.
82
83```sh
84if [ "x${SERF_TAG_ROLE}" != "xlb" ]; then
85    echo "Not an lb. Ignoring member join."
86    exit 0
87fi
88
89while read line; do
90    ROLE=`echo $line | awk '{print \$3 }'`
91    if [ "x${ROLE}" != "xweb" ]; then
92        continue
93    fi
94
95    echo $line | \
96        awk '{ printf "    server %s %s check\n", $1, $2 }' >>/etc/haproxy/haproxy.cfg
97done
98
99/etc/init.d/haproxy reload
100```
101
102The script first checks if this node is a load balancer. If it isn't a load
103balancer, we don't do anything on the "member-join" event. Web servers simply
104don't care about other members.
105
106Otherwise, if this is a load balancer, then it handles the "member-join" event
107and reads the event data and updates the configuration of HAProxy. In a
108production environment, you might use something like a template processor to do
109this rather than appending to the configuration. For the purposes of this demo,
110this works as well.
111
112Finally, HAProxy is reloaded so the configuration is read.
113
114The result of this is that as members join, they're automatically added into
115rotation on the load balancer.
116
117#### Event: member-leave, member-failed
118
119On member-leave and member-failed evets, the following shell script is run.
120This demo doesn't differentiate between the two events, treating both
121the same way and simply removing the node from the HAProxy configuration.
122
123```sh
124if [ "x${SERF_TAG_ROLE}" != "xlb" ]; then
125    echo "Not an lb. Ignoring member leave"
126    exit 0
127fi
128
129while read line; do
130    NAME=`echo $line | awk '{print \$1 }'`
131    sed -i'' "/${NAME} /d" /etc/haproxy/haproxy.cfg
132done
133
134/etc/init.d/haproxy reload
135```
136
137This script also does nothing if this node is not a load balanacer. Otherwise,
138it uses `sed` to remove each of the nodes from the HAProxy configuration and
139reloads it.
140