-
Notifications
You must be signed in to change notification settings - Fork 821
Az webservers tutorial #5133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Az webservers tutorial #5133
Changes from 4 commits
b098710
75b2350
e2b24af
316e370
786680d
6a92b2d
7d8b797
5db138d
39188da
cb07e3f
12f6976
de05fe9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,195 @@ | ||||||||||||
| (tutorial-availability-zones)= | ||||||||||||
| # Multipass availability zones with a load-balanced web service | ||||||||||||
|
|
||||||||||||
| In this tutorial, we will use Multipass availability zones to build a simple, highly available web service. We will deploy three Nginx web servers, one in each availability zone, and a fourth instance acting as a load balancer to distribute traffic between them. | ||||||||||||
|
geoffreynyaga marked this conversation as resolved.
|
||||||||||||
|
|
||||||||||||
| To complete this tutorial, you need Multipass 1.17 or later installed on your host. | ||||||||||||
|
|
||||||||||||
| ## Check the available zones | ||||||||||||
|
|
||||||||||||
| Multipass ships with a fixed set of availability zones. List them, along with their status, before you start: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass zones | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| Sample output: | ||||||||||||
|
|
||||||||||||
| ```text | ||||||||||||
| Name State | ||||||||||||
| zone1 Available | ||||||||||||
| zone2 Available | ||||||||||||
| zone3 Available | ||||||||||||
|
geoffreynyaga marked this conversation as resolved.
Outdated
|
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add something about why the subnets are relevant here? It probably needs some editing, but something like this: "You can see how each zone has its own subnet to simulate the different networks belonging to each real-world zone." Or is that getting too detailed for this tutorial?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||
| We will spread our web servers across `zone1`, `zone2` and `zone3`. | ||||||||||||
|
|
||||||||||||
| ## Launch the web servers | ||||||||||||
|
|
||||||||||||
| First, let's launch one web server in each availability zone. We will customize their landing pages so we can easily see which zone is responding. | ||||||||||||
|
|
||||||||||||
| ### Launch and configure the first server (zone1) | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass launch --name web-a --zone zone1 | ||||||||||||
| multipass exec web-a -- sudo apt-get update | ||||||||||||
| multipass exec web-a -- sudo apt-get install -y nginx | ||||||||||||
| multipass exec web-a -- bash -c 'echo "<h1>Welcome to web-a in zone1</h1>" | sudo tee /var/www/html/index.html' | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### Launch and configure the second server (zone2) | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass launch --name web-b --zone zone2 | ||||||||||||
| multipass exec web-b -- sudo apt-get update | ||||||||||||
| multipass exec web-b -- sudo apt-get install -y nginx | ||||||||||||
| multipass exec web-b -- bash -c 'echo "<h1>Welcome to web-b in zone2</h1>" | sudo tee /var/www/html/index.html' | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### Launch and configure the third server (zone3) | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass launch --name web-c --zone zone3 | ||||||||||||
| multipass exec web-c -- sudo apt-get update | ||||||||||||
| multipass exec web-c -- sudo apt-get install -y nginx | ||||||||||||
| multipass exec web-c -- bash -c 'echo "<h1>Welcome to web-c in zone3</h1>" | sudo tee /var/www/html/index.html' | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ## Launch the load balancer | ||||||||||||
|
|
||||||||||||
| Now we will launch a fourth instance to act as a load balancer. We will place it explicitly in `zone3` so we know exactly where it lives, and use HAProxy, a popular open-source load balancer, to distribute traffic across all three zones. | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass launch --name load-balancer --zone zone3 | ||||||||||||
| multipass exec load-balancer -- sudo apt-get update | ||||||||||||
| multipass exec load-balancer -- sudo apt-get install -y haproxy | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### Configure HAProxy | ||||||||||||
|
|
||||||||||||
| The load balancer needs the IP address of each web server so it can send incoming requests to them. Get these addresses: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| WEB_A_IP=$(multipass info web-a --format csv | awk -F, 'NR>1 {print $5}') | ||||||||||||
| WEB_B_IP=$(multipass info web-b --format csv | awk -F, 'NR>1 {print $5}') | ||||||||||||
| WEB_C_IP=$(multipass info web-c --format csv | awk -F, 'NR>1 {print $5}') | ||||||||||||
| ``` | ||||||||||||
|
Comment on lines
+78
to
+82
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we include a Windows variant of these commands? |
||||||||||||
|
|
||||||||||||
| Create a configuration file locally and transfer it to the load balancer: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| cat << EOF > haproxy.cfg | ||||||||||||
|
|
||||||||||||
| frontend http_front | ||||||||||||
| bind *:80 | ||||||||||||
| default_backend http_back | ||||||||||||
|
|
||||||||||||
| backend http_back | ||||||||||||
| balance roundrobin | ||||||||||||
| server web-a $WEB_A_IP:80 check | ||||||||||||
| server web-b $WEB_B_IP:80 check | ||||||||||||
| server web-c $WEB_C_IP:80 check | ||||||||||||
| EOF | ||||||||||||
|
Comment on lines
+86
to
+98
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto here. |
||||||||||||
|
|
||||||||||||
| multipass transfer haproxy.cfg load-balancer: | ||||||||||||
| multipass exec load-balancer -- sudo mv /home/ubuntu/haproxy.cfg /etc/haproxy/haproxy.cfg | ||||||||||||
| multipass exec load-balancer -- sudo systemctl restart haproxy | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ## Test the high availability | ||||||||||||
|
|
||||||||||||
| Find the IP address of your load balancer: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| LB_IP=$(multipass info load-balancer --format csv | awk -F, 'NR>1 {print $5}') | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And here. |
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| From now on, send requests only to the load balancer. It decides which healthy backend server responds. Query it once: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| curl http://$LB_IP | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And here (as well as the same snippets below). |
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| *Expected output:* | ||||||||||||
|
|
||||||||||||
| ```text | ||||||||||||
| <h1>Welcome to web-a in zone1</h1> | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| Run the command again: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| curl http://$LB_IP | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| This time, the response comes from the next web server in another availability zone: | ||||||||||||
|
|
||||||||||||
| ```text | ||||||||||||
| <h1>Welcome to web-b in zone2</h1> | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### Simulate a zone failure | ||||||||||||
|
|
||||||||||||
| To simulate an outage of an entire availability zone, disable `zone1`. Multipass forcefully switches off every instance in that zone and keeps them off until the zone is re-enabled, mirroring a real cloud provider losing a zone: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass disable-zones zone1 | ||||||||||||
|
geoffreynyaga marked this conversation as resolved.
|
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| After a few moments, query the same load balancer address twice. HAProxy detects that `web-a` is unavailable and sends the requests to the surviving web servers: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| curl http://$LB_IP | ||||||||||||
| curl http://$LB_IP | ||||||||||||
|
Comment on lines
+148
to
+149
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To really demonstrate what happens, we'd probably want to make an additional request so that we loop around and skip zone1:
Suggested change
|
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| *Expected output (the order may vary):* | ||||||||||||
|
|
||||||||||||
| ```text | ||||||||||||
| <h1>Welcome to web-b in zone2</h1> | ||||||||||||
| <h1>Welcome to web-c in zone3</h1> | ||||||||||||
|
Comment on lines
+155
to
+156
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise here:
Suggested change
|
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| Notice that neither response comes from `web-a` in `zone1`. | ||||||||||||
|
geoffreynyaga marked this conversation as resolved.
Outdated
|
||||||||||||
|
|
||||||||||||
| ### Take down a second zone | ||||||||||||
|
|
||||||||||||
| Now disable `zone2` as well, leaving only `zone3` healthy: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass disable-zones zone2 | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| Query the load balancer once more. With two zones down, every request can only come from `web-c` in `zone3`: | ||||||||||||
|
geoffreynyaga marked this conversation as resolved.
Outdated
|
||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| curl http://$LB_IP | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| *Expected output:* | ||||||||||||
|
|
||||||||||||
| ```text | ||||||||||||
| <h1>Welcome to web-c in zone3</h1> | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ## Tear down the environment | ||||||||||||
|
|
||||||||||||
| ### Restore the zones | ||||||||||||
|
|
||||||||||||
| Bring both zones back online. Instances that were running when the zones were disabled are started again automatically: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass enable-zones zone1 zone2 | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| After a few moments, `web-a` and `web-b` rejoin the rotation and the load balancer serves all three zones once more. | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we show this with an example? |
||||||||||||
|
|
||||||||||||
| Let's now delete the instances and free their resources on our host machine: | ||||||||||||
|
|
||||||||||||
| ```bash | ||||||||||||
| multipass delete --purge web-a web-b web-c load-balancer | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ## Summary | ||||||||||||
|
|
||||||||||||
| You have built a highly available web service that spans all three availability zones. Even when an entire zone goes offline, your users can still access the application through the healthy zones, demonstrating the power of infrastructure redundancy with Multipass. | ||||||||||||
Uh oh!
There was an error while loading. Please reload this page.