1"use strict";(globalThis.webpackChunkmikes_dev_notebook=globalThis.webpackChunkmikes_dev_notebook||[]).push([[16554],{28280(e,n,a){a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"DevOps/Hashicorp/2021-08-06--hashicorp-consul-fabio-loadbalancing/index","title":"Hashicorp Consul Refresher - Loadbalancing with Fabio","description":"Tsim Sha Tsui, Hongkong","source":"@site/docs/DevOps/Hashicorp/2021-08-06--hashicorp-consul-fabio-loadbalancing/index.md","sourceDirName":"DevOps/Hashicorp/2021-08-06--hashicorp-consul-fabio-loadbalancing","slug":"/DevOps/Hashicorp/2021-08-06--hashicorp-consul-fabio-loadbalancing/2021-08-06","permalink":"/docs/DevOps/Hashicorp/2021-08-06--hashicorp-consul-fabio-loadbalancing/2021-08-06","draft":false,"unlisted":false,"editUrl":"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/DevOps/Hashicorp/2021-08-06--hashicorp-consul-fabio-loadbalancing/index.md","tags":[{"inline":true,"label":"Consul","permalink":"/docs/tags/consul"},{"inline":true,"label":"Nomad","permalink":"/docs/tags/nomad"},{"inline":true,"label":"Linux","permalink":"/docs/tags/linux"}],"version":"current","sidebarPosition":8050,"frontMatter":{"sidebar_position":8050,"slug":"2021-08-06","title":"Hashicorp Consul Refresher - Loadbalancing with Fabio","authors":"mpolinowski","tags":["Consul","Nomad","Linux"]},"sidebar":"tutorialSidebar","previous":{"title":"Hashicorp Consul Refresher - Loadbalancing with Traefik","permalink":"/docs/DevOps/Hashicorp/2021-08-06--hashicorp-consul-traefik-loadbalancing/2021-08-06"},"next":{"title":"Hashicorp Consul Refresher - Service Discovery","permalink":"/docs/DevOps/Hashicorp/2021-08-05--hashicorp-consul-service-discovery/2021-08-05"}}');var o=a(474848),i=a(28453);const s={sidebar_position:8050,slug:"2021-08-06",title:"Hashicorp Consul Refresher - Loadbalancing with Fabio",authors:"mpolinowski",tags:["Consul","Nomad","Linux"]},t=void 0,c={},l=[{value:"Load Balancing with Fabio",id:"load-balancing-with-fabio",level:2},{value:"Create the Web Service",id:"create-the-web-service",level:3},{value:"Create and run a Fabio job",id:"create-and-run-a-fabio-job",level:3}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"Tsim Sha Tsui, Hongkong",src:a(215653).A+"",width:"1500",height:"461"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#load-balancing-with-fabio",children:"Load Balancing with Fabio"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"#create-the-web-service",children:"Create the Web Service"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"#create-and-run-a-fabio-job",children:"Create and run a Fabio job"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"load-balancing-with-fabio",children:"Load Balancing with Fabio"}),"\n",(0,o.jsxs)(n.p,{children:["The main use case for ",(0,o.jsx)(n.a,{href:"https://fabiolb.net/",children:"Fabio"})," in this scenario is to distribute incoming HTTP(S) and TCP requests from the Internet to front-end services that can handle these requests. ",(0,o.jsx)(n.a,{href:"https://learn.hashicorp.com/tutorials/nomad/load-balancing-fabio",children:"Fabio can natively integrate with Consul"})," using the ",(0,o.jsx)(n.a,{href:"https://docs.traefik.io/prov
1iders/consul-catalog/",children:"Consul Catalog Provider"})," and can use tags to route traffic."]}),"\n",(0,o.jsx)(n.h3,{id:"create-the-web-service",children:"Create the Web Service"}),"\n",(0,o.jsxs)(n.p,{children:["I am going to modify the ",(0,o.jsx)(n.a,{href:"/docs/DevOps/Hashicorp/2021-08-05--hashicorp-consul-service-discovery/2021-08-05",children:"HTTP Echo service I created earlier"})," to be load balanced by Fabio:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'job "http-echo-gui" {\r\n datacenters = ["instaryun"]\r\n\r\n group "echo" {\r\n \r\n network {\r\n port "heartbeat" {\r\n static = 8080\r\n }\r\n }\r\n\r\n count = 1\r\n task "server" {\r\n driver = "docker" \r\n config {\r\n image = "hashicorp/http-echo:latest"\r\n ports = ["heartbeat"]\r\n args = [\r\n "-listen", ":${NOMAD_PORT_heartbeat}",\r\n "-text", "${attr.os.name}: server running on ${NOMAD_IP_heartbeat} with port ${NOMAD_PORT_heartbeat}",\r\n ]\r\n }\r\n service {\r\n name = "http-echo"\r\n port = "heartbeat"\r\n \r\n tags = [\r\n "heartbeat",\r\n "urlprefix-/http-echo",\r\n ]\r\n\r\n check {\r\n type = "http"\r\n path = "/health"\r\n interval = "2s"\r\n timeout = "2s"\r\n }\r\n }\r\n }\r\n }\r\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:'Note that this job only deploys 1 instance of the Echo web application which I will "load balance" with Fabio in the next few steps. Obviously, you should increase this count to have this make sense... but I only have two LINUX PCs running at the moment and so my "Datacenter" consists of a single minion server.'}),"\n",(0,o.jsx)(n.h3,{id:"create-and-run-a-fabio-job",children:"Create and run a Fabio job"}),"\n",(0,o.jsx)(n.p,{children:"Create a job named:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"nano ~/nomad_jobs/fabio.nomad\n"})}),"\n",(0,o.jsx)(n.p,{children:"This job starts an instance of Fabio and configures it to discover its configuration from Consul. This Fabio instance provides routing and load balancing to the sample web application."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'job "fabio" {\r\n datacenters = ["instaryun"]\r\n type = "system"\r\n\r\n group "fabio" {\r\n network {\r\n port "lb" {\r\n static = 9999\r\n }\r\n port "ui" {\r\n static = 9998\r\n }\r\n }\r\n task "fabio" {\r\n driver = "docker"\r\n config {\r\n image = "fabiolb/fabio"\r\n network_mode = "host"\r\n ports = ["lb","ui"]\r\n args = ["-proxy.strategy=rr"]\r\n }\r\n\r\n resources {\r\n cpu = 200\r\n memory = 128\r\n }\r\n }\r\n }\r\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Fabio can be run without any additional parameters and will use a pseudo-random strategy for load balancing between multiple instances of the same application. In our job file, an additional argument of ",(0,o.jsx)(n.code,{children:"-proxy.strategy=rr"})," is passed to the Fabio command to use a ",(0,o.jsx)(n.a,{href:"https://fabiolb.net/ref/proxy.strategy/",children:"round-robin strategy"})," instead."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'nomad plan ~/nomad_jobs/fabio.nomad\r\n+ Job: "fabio"\r\n+ Task Group: "fabio" (1 create)\r\n + Task: "fabio" (forces create)\r\n\r\nScheduler dry-run:\r\n- All tasks successfully allocated.\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Run Fabio and it will automatically use the ",(0,o.jsx)(n.a,{href:"https://fabiolb.net/quickstart/",children:"tags"})," that were provided to Consul when the job was registered, to automatically configure itself with the instances running on the various dynamic ports."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'nomad job run -check-index 0 ~/nomad_jobs/fabio.nomad\r\n\r\n==> 2021-09-04T17:48:20+08:00: Evaluation "4ccd671f" finished with status "complete"\n'})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"Hashicorp Consul Fabio",src:a(807417).A+"",width:"1277",height:"590"})}),"\n",(0,o.jsxs)(n.p,{children:["The tag urlprefix-/http-echo tells Fabio to add the instance to the route /http-echo. The instances of the application are then available by visiting ",(0,o.jsx)(n.code,{children:"/http-echo"})," on port ",(0,o.jsx)(n.code,{children:"9999"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl 192.168.2.111:9999/http-echo\r\n\r\ndebian: server running on 192.168.2.111 with port 8080\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The response shows that the service is still running on port 8080 but is now proxied through Fabio and - ",(0,o.jsx)(n.strong,{children:"in theory"})," - it would be loadbalanced. Refreshing the page would show you that you will reach all your instances of ",(0,o.jsx)(n.code,{children:"http-echo"}),". You can visit the ",(0,o.jsx)(n.strong,{children:"Fabio UI"})," on port ",(0,o.jsx)(n.code,{children:"9998"})," to verify that all your nodes were picked up successfully:"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"Hashicorp Consul Fabio",src:a(824482).A+"",width:"981",height:"385"})})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},807417(e,n,a){const r=a.p+"assets/images/Hashicorp_Consul_Fabio_01-7ff80874cd28e444d5a04ea68434458d.png";a.d(n,["A",0,r])},824482(e,n,a){const r=a.p+"assets/images/Hashicorp_Consul_Fabio_02-69915edc19eaa6efa7b3300ef3163ec7.png";a.d(n,["A",0,r])},215653(e,n,a){const r=a.p+"assets/images/photo-kt443t6d_64hdh43hfh6dgjdfhg4_d-11f46a2aa16d04d5dd9b5dc1c7c256c1.jpg";a.d(n,["A",0,r])},28453(e,n,a){a.d(n,{R:()=>s,x:()=>t});var r=a(296540);const o={},i=r.createContext(o);function s(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.