Technical Documentation: fabiolb/fabio
โน๏ธ Provenance: Hybrid Fusion:
fabiolb/fabio(README + 10 In-Tree Chapters) ยท CodeWiki Reference ยท Recency: Active (< 180 days)
1. Project Overview & Quickstart (fabiolb/fabio)
Notes
From release 1.6.1 onward, the minimum golang version supported is 1.16.
From release 1.6.0 onward, metrics backend statsd is no longer supported. statsd_raw
works similarly, though it actually resets counters appropriately. If you are using datadog,
you should consider using the new dogstatsd backend, which has support for tags now. Graphite
histogram functionality has changed slightly since switching to gokit framework, so something to be aware of.
Prometheus functionality is now supported natively.From release 1.5.15 onward, fabio changes the default GOGC from 800 back to
the golang default of 100. Apparently this made some sense back in the golang 1.5 days, but with
changes introduced with golang 1.12 and others, this is probably no longer a very good default.
This is still configurable, as always, but the new default should make the most sense for most users.From release 1.5.14, release hashes are signed with a new PGP key.
See details here.From release 1.5.14 onward, fabio binary releases are compiled with golang 1.15+.
This means that the fabio will no longer validate upstream https certificates that do
not have SAN extensions matching the server name. This may be a concern if fabio is
communicating with https backends with misconfigured certificates. If this is a problem,
you can specifytlsskipverify=trueon the route.
fabio is a fast, modern, zero-conf load balancing HTTP(S) and TCP router
for deploying applications managed by consul.
Register your services in consul, provide a health check and fabio will start
routing traffic to them. No configuration required. Deployment, upgrading and
refactoring has never been easier.
fabio is developed and maintained by The Fabio Authors.
It powers some of the largest websites in
Australia (gumtree.com.au).
It delivers 23.000 req/sec every day since Sep 2015 without problems.
It integrates with
Consul,
Vault,
Amazon ELB,
Amazon API Gateway
and more.
It supports (Full feature list)
- TLS termination with dynamic certificate stores
- Raw TCP proxy
- TCP+SNI proxy for full end-to-end TLS without decryption
- HTTPS+TCP+SNI proxy for TCP+SNI with HTTPS fallback
- TCP dynamic proxy
- HTTPS upstream support
- Websockets and
- SSE
- Dynamic reloading without restart
- Traffic shaping for "blue/green" deployments,
- Prometheus,
- Circonus,
- Graphite,
- StatsD,
- DataDog for metrics,
- WebUI and
- Advertising BGP anycast addresses on non-windows platforms.
Watch
Kelsey Hightower demo Consul, Nomad, Vault and fabio at HashiConf EU 2016.
The full documentation is on fabiolb.net
Getting started
Install from source, binary,
Docker or Homebrew.shell# go 1.15 or higher is required go install github.com/fabiolb/fabio@latest (>= go1.15) brew install fabio (OSX/macOS stable) brew install --devel fabio (OSX/macOS devel) docker pull fabiolb/fabio (Docker) https://github.com/fabiolb/fabio/releases (pre-built binaries)Register your service in consul.
Make sure that each instance registers with a unique ServiceID and a service name without spaces.
Register a health check in consul as described here.
By default fabio only watches services which have a passing health check, unless overridden with registry.consul.service.status.
Register one
urlprefix-tag perhost/pathprefix it serves, e.g.:
# HTTP/S examples
urlprefix-/css # path route
urlprefix-i.com/static # host specific path route
urlprefix-mysite.com/ # host specific catch all route
urlprefix-/foo/bar strip=/foo # path stripping (forward '/bar' to upstream)
urlprefix-/foo/bar proto=https # HTTPS upstream
urlprefix-/foo/bar proto=https tlsskipverify=true # HTTPS upstream and self-signed cert
# TCP examples
urlprefix-:3306 proto=tcp # route external port 3306 Make sure the prefix for HTTP routes contains at least one slash (/).
See the full list of options in the Documentation.
Start fabio without a config file (assuming a running consul agent on
localhost:8500)
Watch the log output how fabio picks up the route to your service.
Try starting/stopping your service to see how the routing table changes instantly.Send all your HTTP traffic to fabio on port
9999.
For TCP proxying see TCP proxy.Done
Author and Founder
- Frank Schroeder @magiconair
Maintainers
Contributors
This project exists thanks to all the people who contribute. [Contribute].
License
Contributions up to 14 Apr 2017 before 38f73da
MIT Licensed
Copyright (c) 2017 eBay Software Foundation. All rights reserved.Contributions after 14 Apr 2017 starting with 38f73da
MIT Licensed
Copyright (c) 2017-2019 Frank Schroeder. All rights reserved.Contributions after 22 Jan 2020 starting with 9da7b1b
MIT Licensed
Copyright (c) 2020 Education Networks of America. All rights reserved.
See LICENSE for details.
2. In-Tree Documentation Chapters (fabiolb/fabio)
File: README.md
Notes
From release 1.6.1 onward, the minimum golang version supported is 1.16.
From release 1.6.0 onward, metrics backend statsd is no longer supported. statsd_raw
works similarly, though it actually resets counters appropriately. If you are using datadog,
you should consider using the new dogstatsd backend, which has support for tags now. Graphite
histogram functionality has changed slightly since switching to gokit framework, so something to be aware of.
Prometheus functionality is now supported natively.From release 1.5.15 onward, fabio changes the default GOGC from 800 back to
the golang default of 100. Apparently this made some sense back in the golang 1.5 days, but with
changes introduced with golang 1.12 and others, this is probably no longer a very good default.
This is still configurable, as always, but the new default should make the most sense for most users.From release 1.5.14, release hashes are signed with a new PGP key.
See details here.From release 1.5.14 onward, fabio binary releases are compiled with golang 1.15+.
This means that the fabio will no longer validate upstream https certificates that do
not have SAN extensions matching the server name. This may be a concern if fabio is
communicating with https backends with misconfigured certificates. If this is a problem,
you can specifytlsskipverify=trueon the route.
fabio is a fast, modern, zero-conf load balancing HTTP(S) and TCP router
for deploying applications managed by consul.
Register your services in consul, provide a health check and fabio will start
routing traffic to them. No configuration required. Deployment, upgrading and
refactoring has never been easier.
fabio is developed and maintained by The Fabio Authors.
It powers some of the largest websites in
Australia (gumtree.com.au).
It delivers 23.000 req/sec every day since Sep 2015 without problems.
It integrates with
Consul,
Vault,
Amazon ELB,
Amazon API Gateway
and more.
It supports (Full feature list)
- TLS termination with dynamic certificate stores
- Raw TCP proxy
- TCP+SNI proxy for full end-to-end TLS without decryption
- HTTPS+TCP+SNI proxy for TCP+SNI with HTTPS fallback
- TCP dynamic proxy
- HTTPS upstream support
- Websockets and
- SSE
- Dynamic reloading without restart
- Traffic shaping for "blue/green" deployments,
- Prometheus,
- Circonus,
- Graphite,
- StatsD,
- DataDog for metrics,
- WebUI and
- Advertising BGP anycast addresses on non-windows platforms.
Watch
Kelsey Hightower demo Consul, Nomad, Vault and fabio at HashiConf EU 2016.
The full documentation is on fabiolb.net
Getting started
Install from source, binary,
Docker or Homebrew.shell# go 1.15 or higher is required go install github.com/fabiolb/fabio@latest (>= go1.15) brew install fabio (OSX/macOS stable) brew install --devel fabio (OSX/macOS devel) docker pull fabiolb/fabio (Docker) https://github.com/fabiolb/fabio/releases (pre-built binaries)Register your service in consul.
Make sure that each instance registers with a unique ServiceID and a service name without spaces.
Register a health check in consul as described here.
By default fabio only watches services which have a passing health check, unless overridden with registry.consul.service.status.
Register one
urlprefix-tag perhost/pathprefix it serves, e.g.:
# HTTP/S examples
urlprefix-/css # path route
urlprefix-i.com/static # host specific path route
urlprefix-mysite.com/ # host specific catch all route
urlprefix-/foo/bar strip=/foo # path stripping (forward '/bar' to upstream)
urlprefix-/foo/bar proto=https # HTTPS upstream
urlprefix-/foo/bar proto=https tlsskipverify=true # HTTPS upstream and self-signed cert
# TCP examples
urlprefix-:3306 proto=tcp # route external port 3306 Make sure the prefix for HTTP routes contains at least one slash (/).
See the full list of options in the Documentation.
Start fabio without a config file (assuming a running consul agent on
localhost:8500)
Watch the log output how fabio picks up the route to your service.
Try starting/stopping your service to see how the routing table changes instantly.Send all your HTTP traffic to fabio on port
9999.
For TCP proxying see TCP proxy.Done
Author and Founder
- Frank Schroeder @magiconair
Maintainers
Contributors
This project exists thanks to all the people who contribute. [Contribute].
License
Contributions up to 14 Apr 2017 before 38f73da
MIT Licensed
Copyright (c) 2017 eBay Software Foundation. All rights reserved.Contributions after 14 Apr 2017 starting with 38f73da
MIT Licensed
Copyright (c) 2017-2019 Frank Schroeder. All rights reserved.Contributions after 22 Jan 2020 starting with 9da7b1b
MIT Licensed
Copyright (c) 2020 Education Networks of America. All rights reserved.
See LICENSE for details.
File: docs/archetypes/default.md
title: "{{ replace .TranslationBaseName "-" " " | title }}" date: {{ .Date }} draft: true
File: docs/content/cfg/_index.md
title: "Config Language" weight: 550
The routing table is configured with commands in the language specified below.
Rules are automatically generated by the configured backend. Additional rules
can be stored in the Consul KV store configured byregistry.consul.kvpath which by default is/fabio/config.
As of fabio 1.5.7 the path is interpreted as a prefix and the values of all sub
keys are appended in alphabetical order. When thelog.routes.format is set to all then the routing
table contains comments on the source of the fragment.
Comments
Blank lines and lines starting with # or // are ignored.
`route add`
Add a route for a service svc for the src (e.g. /path or :port) to a dst (e.g. URL or host:port).
route add <svc> <src> <dst>[ weight <w>][ tags "<t1>,<t2>,..."][ opts "k1=v1 k2=v2 ..."]
| Option | Description |
|---|---|
allow=ip:10.0.0.0/8,ip:fe80::/10 |
Restrict access to source addresses within the 10.0.0.0/8 or fe80::/10 CIDR mask. All other requests will be denied. |
deny=ip:10.0.0.0/8,ip:fe80::1234 |
Deny requests that source from the 10.0.0.0/8 CIDR mask or fe80::1234. All other requests will be allowed. |
strip=/path |
Forward /path/to/file as /to/file |
prepend=/prefix |
Forward /path/to/file as /prefix/path/to/file |
proto=tcp |
Upstream service is TCP, dst must be :port |
pxyproto=true |
Enables PROXY protocol on outbount TCP connection |
proto=https |
Upstream service is HTTPS |
tlsskipverify=true |
Disable TLS cert validation for HTTPS upstream |
host=name |
Set the Host header to name. If name == 'dst' then the Host header will be set to the registered upstream host name |
register=name |
Register fabio as new service name. Useful for registering hostnames for host specific routes. |
auth=name |
Specify an auth scheme to use (must be registered with the fabio server using proxy.auth) |
Example
# route traffic for product-svc to 1.2.3.4:8000 and :9000
route add product-svc /product http://1.2.3.4:8000
route add product-svc /product http://1.2.3.4:9000`route del`
Remove one or more routes which match the given criteria.
route del <svc>[ <src>[ <dst>]]
route del <svc> tags "<t1>,<t2>,..."
route del tags "<t1>,<t2>,..."Example
# remove all routes for 'product-svc'
route del product-svc
# remove all routes for 'product-svc' and /path
route del product-svc /path
# remove single route
route del product-svc /path http://1.2.3.4:8000
# remove all routes for 'product-svc' matching a tag
route del product-svc tags "green"
# remove all routes matching a tag
route del tags "yesterday"`route weight`
Directs a certain amount of traffic to instances matching certain criteria.
The weight w is expressed as follows:
wis a float > 0 describing a percentage, e.g. 0.5 == 50%w <= 0: means no fixed weighting. Traffic is evenly distributedw > 0: route will receive n% of traffic. If sum(w) > 1 then w is normalized.sum(w) >= 1: only matching services will receive traffic
Note that the total sum of traffic sent to all matching routes is w%.
The order of commands matters but routes are always ordered from most to least
specific by prefix length.
route weight <svc> <src> weight <w> tags "<t1>,<t2>,..."
route weight <src> weight <w> tags "<t1>,<t2>,..."
route weight <svc> <src> weight <w>
route weight service host/path weight w tags "tag1,tag2"Example
# Route 5% of the traffic to product-svc:/path with tags "green"
route weight product-svc /path weight .05 tags "green"
# Route 5% of the traffic to '/path' to the Go implementation.
# Route the rest (95%) to the other implementation
route weight /path weight .05 tags "lang=go"
# Route 5% of the traffice to '/path' on the product-svc-go
route weight product-svc-go /path weight .05Routing rules
The routing table contains first all routes with a host sorted by prefix
length in descending order and then all routes without a host again sorted by
prefix length in descending order.
For each incoming request the routing table is searched top to bottom for a
matching route. A route matches if either host/path or - if there was no
match - just /path matches.
The matching route determines the target URL depending on the configured
strategy. rnd and rr are available with rnd being the default.
Example
The auto-generated routing table is
route add service-a www.mp.dev/accounts/ http://host-a:11050/ tags "a,b"
route add service-a www.kjca.dev/accounts/ http://host-a:11050/ tags "a,b"
route add service-a www.dba.dev/accounts/ http://host-a:11050/ tags "a,b"
route add service-b www.mp.dev/auth/ http://host-b:11080/ tags "a,b"
route add service-b www.kjca.dev/auth/ http://host-b:11080/ tags "a,b"
route add service-b www.dba.dev/auth/ http://host-b:11080/ tags "a,b"The manual configuration under /fabio/config is
route del service-b www.dba.dev/auth/
route add service-c www.somedomain.com/ http://host-z:12345/The complete routing table then is
route add service-a www.mp.dev/accounts/ http://host-a:11050/ tags "a,b"
route add service-a www.kjca.dev/accounts/ http://host-a:11050/ tags "a,b"
route add service-a www.dba.dev/accounts/ http://host-a:11050/ tags "a,b"
route add service-b www.mp.dev/auth/ http://host-b:11080/ tags "a,b"
route add service-b www.kjca.dev/auth/ http://host-b:11080/ tags "a,b"
route add service-c www.somedomain.com/ http://host-z:12345/File: docs/content/code-of-conduct/_index.md
title: "Code of Conduct" weight: 1000
Be nice and treat others with respect.
Please contact a project owner if you need mediation with a dispute.
File: docs/content/contact/_index.md
title: "Contact" weight: 2000
Please create a GitHub issue for all feature requests, bugs and general
questions about the project. You may also contact any project owner for other concerns.
File: docs/content/contrib/_index.md
title: "Contributing" weight: 900
Contributions to fabio of any kind are welcome including documentation, examples,
feature requests, bug reports, discussions, helping with issues, etc.
If you have a question on how or what to contribute just open an issue and
indicate that it is a question.
File: docs/content/contrib/development.md
title: "Development" weight: 200
For newcomers to Go, you can't just git clone your forked repo and work from
there, due to how Go's GOPATH works. You can follow the steps below to get started:
- Fork this repository to your own account (named
myforkbelow) - Make sure you have Consul and Vault installed in your
$PATH go get github.com/fabiolb/fabio, change to the directory where the code was cloned
($GOPATH/src/github.com/fabiolb/fabio) and add your fork as remote:git remote add myfork [email protected]:myfork/fabio.git- Hack away!
go fmtandmake testyour code- Commit your changes and push to your own fork:
git push myfork - Create a pull-request
File: docs/content/contrib/guidelines.md
title: "Guidelines" weight: 100
Your contribution is welcome!
To make merging code as seamless as possible
we ask for the following:
- For small changes and bug fixes go ahead, fork the project, make your changes
and send a pull request. Check out the Development
page for some useful tips. - Larger changes should start with a proposal in an issue. This should ensure
that the requested change is in line with the project and similar work is not
already underway. - Only add libraries if they provide significant value. Consider copying the code
(attribution) or writing it yourself. - Manage dependencies with
go modand rungo mod vendorafterwards to
sync thevendorfolder for backwards compatibility.
Once you are ready to send in a pull request, be sure to:
- Sign the CLA
- Provide test cases for the critical code which test correctness. If your code
is in a performance critical path make sure you have performed some real world
measurements to ensure that performance is not degregated. go fmtandmake testyour code- Squash your change into a single commit with the exception of additional libraries.
- Write a good commit message.
File: docs/content/deploy/_index.md
title: "Deployment" weight: 300
The main use-case for fabio is to distribute incoming HTTP(S) and TCP requests
from the internet to frontend (FE) services which can handle these requests.
In this scenario the FE services then use the service discovery feature in
Consul to find backend (BE) services they need in order
to serve the request.
That means that fabio is currently not used as an FE-BE or BE-BE router to
route traffic among the services themselves since the service discovery of
Consul already solves that problem. Having said that,
there is nothing that inherently prevents fabio from being used that way.
It just means that we are not doing it.
File: docs/content/deploy/amazon-api-gw.md
title: "Amazon API Gateway" weight: 500
You can deploy fabio as the target of an Amazon API Gateway.
internet -- HTTP/HTTPS --> API GW -+- HTTP -> fabio -+-> service-b (host-b)
or behind an ELB with PROXY protocol support:
+- HTTP w/PROXY -> fabio -+-> service-a (host-a)
| |internet -- HTTP/HTTPS --> API GW --> ELB -+- HTTP w/PROXY -> fabio -+-> service-b (host-b)
| |
+- HTTP w/PROXY -> fabio -+-> service-c (host-c)
You can authenticate calls from the API Gateway with a client certificate. This requires that you
configure an HTTPS listener on fabio with a valid certificate.
internet -- HTTPS --> API GW -+- HTTPS w/client cert -> fabio -+-> service
To enable fabio to validate the Amazon
generated certificate you need to configure the aws.apigw.cert.cn as follows:
proxy.addr = 1.2.3.4:9999;your/cert.pem;your/key.pem;api-gw-cert.pem
aws.apigw.cert.cn = ApiGatewayapi-gw-cert.pem is the certificate generated in the AWS Management Console. your/cert.pem and your/key.pem
is the certificate/key pair for the HTTPS certificate. Since the Amazon API Gateway certificates don't have the CA flag set fabio needs to trust them for the client certificate authentication to work. Otherwise, you will get an TLS handshake error: failed to verify client's certificate. See Issue 108 for details.
Note: The aws.apigw.cert.cn parameter will not be supported in version 1.2 and later which support dynamic certificate stores. You will have to add the caupgcn=ApiGateway parameter to the certificate source configuration instead. See Certificate Stores for more detail.
--- METRICS ---
- Files Extracted: 11
- Estimated Token Budget: ~6636 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/fabiolb/fabio