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