github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/website/source/guides/load-balancing/fabio.html.md (about) 1 --- 2 layout: "guides" 3 page_title: "Load Balancing with Nomad" 4 sidebar_current: "guides-load-balancing" 5 description: |- 6 There are multiple approaches to load balancing within a Nomad cluster. 7 One approach involves using [fabio][fabio]. Fabio integrates natively 8 with Consul and provides rich features with an optional Web UI. 9 --- 10 11 # Load Balancing with Fabio 12 13 [Fabio][fabio] integrates natively with Consul and provides an optional Web UI 14 to visualize routing. 15 16 The main use case for fabio is to distribute incoming HTTP(S) and TCP requests 17 from the internet to frontend services that can handle these requests. This 18 guide will show you one such example using [Apache][apache] web server. 19 20 ## Reference Material 21 22 - [Fabio](https://github.com/fabiolb/fabio) on GitHub 23 - [Load Balancing Strategies for Consul](https://www.hashicorp.com/blog/load-balancing-strategies-for-consul) 24 - [Elastic Load Balancing][elb] 25 26 ## Estimated Time to Complete 27 28 20 minutes 29 30 ## Challenge 31 32 Think of a scenario where a Nomad operator needs to configure an environment to 33 make Apache web server highly available behind an endpoint and distribute 34 incoming traffic evenly. 35 36 ## Solution 37 38 Deploy fabio as a 39 [system][system] 40 scheduler so that it can route incoming traffic evenly to the Apache web server 41 group regardless of which client nodes Apache is running on. Place all client nodes 42 behind an [AWS load balancer][elb] to 43 provide the end user with a single endpoint for access. 44 45 ## Prerequisites 46 47 To perform the tasks described in this guide, you need to have a Nomad 48 environment with Consul installed. You can use this 49 [repo](https://github.com/hashicorp/nomad/tree/master/terraform#provision-a-nomad-cluster-in-the-cloud) 50 to easily provision a sandbox environment. This guide will assume a cluster with 51 one server node and three client nodes. 52 53 -> **Please Note:** This guide is for demo purposes and is only using a single server 54 node. In a production cluster, 3 or 5 server nodes are recommended. 55 56 ## Steps 57 58 ### Step 1: Create a Job for Fabio 59 60 Create a job for Fabio and name it `fabio.nomad` 61 62 ```hcl 63 job "fabio" { 64 datacenters = ["dc1"] 65 type = "system" 66 67 group "fabio" { 68 task "fabio" { 69 driver = "docker" 70 config { 71 image = "fabiolb/fabio" 72 network_mode = "host" 73 } 74 75 resources { 76 cpu = 200 77 memory = 128 78 network { 79 mbits = 20 80 port "lb" { 81 static = 9999 82 } 83 port "ui" { 84 static = 9998 85 } 86 } 87 } 88 } 89 } 90 } 91 ``` 92 93 Setting `type` to [system][system] will ensure that fabio is run on all clients. 94 Please note that the `network_mode` option is set to `host` so that fabio can 95 communicate with Consul which is also running on the client nodes. 96 97 ### Step 2: Run the Fabio Job 98 99 We can now register our fabio job: 100 101 ```shell 102 $ nomad job run fabio.nomad 103 ==> Monitoring evaluation "fba4f04a" 104 Evaluation triggered by job "fabio" 105 Allocation "6e6367d4" created: node "f3739267", group "fabio" 106 Allocation "d17573b4" created: node "28d7f859", group "fabio" 107 Allocation "f3ad9b16" created: node "510898b6", group "fabio" 108 Evaluation status changed: "pending" -> "complete" 109 ==> Evaluation "fba4f04a" finished with status "complete" 110 ``` 111 At this point, you should be able to visit any one of your client nodes at port 112 `9998` and see the web interface for fabio. The routing table will be empty 113 since we have not yet deployed anything that fabio can route to. 114 Accordingly, if you visit any of the client nodes at port `9999` at this 115 point, you will get a `404` HTTP response. That will change soon. 116 117 ### Step 3: Create a Job for Apache Web Server 118 119 Create a job for Apache and name it `webserver.nomad` 120 121 ```hcl 122 job "webserver" { 123 datacenters = ["dc1"] 124 type = "service" 125 126 group "webserver" { 127 count = 3 128 restart { 129 attempts = 2 130 interval = "30m" 131 delay = "15s" 132 mode = "fail" 133 } 134 ephemeral_disk { 135 size = 300 136 } 137 138 task "apache" { 139 driver = "docker" 140 config { 141 image = "httpd:latest" 142 port_map { 143 http = 80 144 } 145 } 146 147 resources { 148 network { 149 mbits = 10 150 port "http" {} 151 } 152 } 153 154 service { 155 name = "apache-webserver" 156 tags = ["urlprefix-/"] 157 port = "http" 158 check { 159 name = "alive" 160 type = "http" 161 path = "/" 162 interval = "10s" 163 timeout = "2s" 164 } 165 } 166 } 167 } 168 } 169 ``` 170 171 Notice the tag in the service stanza begins with `urlprefix-`. This is how a 172 path is registered with fabio. In this case, we are registering the path '/' 173 with fabio (which will route us to the default page for Apache web server). 174 175 ### Step 4: Run the Job for Apache Web Server 176 177 We can now register our job for Apache: 178 179 ```shell 180 $ nomad job run webserver.nomad 181 ==> Monitoring evaluation "c7bcaf40" 182 Evaluation triggered by job "webserver" 183 Evaluation within deployment: "e3603b50" 184 Allocation "20951ad4" created: node "510898b6", group "webserver" 185 Allocation "43807686" created: node "28d7f859", group "webserver" 186 Allocation "7b60eb24" created: node "f3739267", group "webserver" 187 Evaluation status changed: "pending" -> "complete" 188 ==> Evaluation "c7bcaf40" finished with status "complete" 189 ``` 190 You have now deployed and registered your web servers with fabio! At this point, 191 you should be able to visit any of the Nomad clients at port `9999` and 192 see the default web page for Apache web server. If you visit fabio's web 193 interface by going to any of the client nodes at port `9998`, you will see that 194 the routing table has been populated as shown below (**Note:** your destination IP 195 addresses will be different). 196 197 [![Routing Table][routing-table]][routing-table] 198 199 Feel free to reduce the `count` in `webserver.nomad` for testing purposes. You 200 will see that you still get routed to the Apache home page by accessing 201 any client node on port `9999`. Accordingly, the routing table 202 in the web interface on port `9999` will reflect the changes. 203 204 ### Step 5: Place Nomad Client Nodes Behind AWS Load Balancer 205 206 At this point, you are ready to place your Nomad client nodes behind an AWS load 207 balancer. Your Nomad client nodes may change over time, and it is important 208 to provide your end users with a single endpoint to access your services. This guide will use the [Classic Load Balancer][classic-lb]. 209 210 The AWS [documentation][classic-lb-doc] provides instruction on how to create a 211 load balancer. The basic steps involve creating a load balancer, registering 212 instances behind the load balancer (in our case these will be the Nomad client 213 nodes), creating listeners, and configuring health checks. 214 215 Once you are done 216 with this, you should be able to hit the DNS name of your load balancer at port 217 80 (or whichever port you configured in your listener) and see the home page of 218 Apache web server. If you configured your listener to also forward traffic to 219 the web interface at port `9998`, you should be able to access that as well. 220 221 [![Home Page][lb-homepage]][lb-homepage] 222 223 [![Routing Table][lb-routing-table]][lb-routing-table] 224 225 [apache]: https://httpd.apache.org/ 226 [classic-lb]: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/introduction.html 227 [classic-lb-doc]: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-getting-started.html 228 [elb]: https://aws.amazon.com/elasticloadbalancing/ 229 [fabio]: https://fabiolb.net/ 230 [lb-homepage]: /assets/images/lb-homepage.png 231 [lb-routing-table]: /assets/images/lb-routing-table.png 232 [routing-table]: /assets/images/routing-table.png 233 [system]: /docs/schedulers.html#system