-
Notifications
You must be signed in to change notification settings - Fork 617
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
Static / Manual routes management via API #396
Comments
The idea of the config language approach is that the routing table has a human readable text format where multiple fragments are just concatenated and parsed into a runtime representation. Right now, one fragment is generated from the service tags in consul and the other fragment comes from Another reason there is no real fabio API for this is that consul already provides an API and a client to manage all this. The idea of the API is from the time when I wanted to support multiple backends besides consul. Given external constraints that doesn't seem to be happening any time soon. My suggestion is to write a script that generates the routing table and store that under This could be as simple as
Depending on the size of the routing table there may be some space and/or performance issues. See #343. A single consul KV entry can hold only 512KB and it takes some time to parse lots of them. The first problem can be addressed by supporting multiple nodes or treat The routing syntax is
See: https://github.com/fabiolb/fabio/wiki/Routing#config-language Please let me know if that helps and whether the consul space constraint is an issue for you. |
To find out on which ip addresses and ports
|
Depending on how you implement this you could use the consul watches for this: |
Thanks @magiconair! The current design certainly makes sense and I like the suggestion of regenerating the routing table with a script in consul. Will try that. Using multiple consul kv nodes under However, having to watch/manage the dst ( It sounds like this is not supported today because the dst needs to be a URL and I am trying to use the service name (for dynamic IP:PORT lookup from consul):
Would this be possible?:
It says send requests to |
Now I get it. fabio could allow you to provide a template which fills in the |
@magiconair Yup, I think so! I was just trying to replicate what we do in consul service tags with |
Incremental route updatesThe issue with incremental route updates is that they are unbounded. So just fabio uses Consul for service discovery and coordination so pushing an Consul has a 512KB limit on KV store nodes which translates into 4-5k targets Depending on the size of your routing table this may also require fixing #343. Generating route targetsIf you generate an external routing table but still want to refer to services I can see several approaches:
I think the last option is the last invasive but the second option looks like the cleanest solution. |
This patch extends the behavior of the registry.consul.kvpath and treats it as a prefix instead of a single key. fabio will now list the key and all available subkeys in alphabetical order and combine them for the routing table. Each subsection will get header which contains key name. Todo: the ui needs to handle that as well
This patch extends the behavior of the registry.consul.kvpath and treats it as a prefix instead of a single key. fabio will now list the key and all available subkeys in alphabetical order and combine them for the routing table. Each subsection will get header which contains key name. Todo: the ui needs to handle that as well
@magiconair #417 looks good to get around the consul 512KB limitation. Option 2 above ("Services are defined separately as part of the routing table") looks interesting. This would allow a service to be targeted for routing even if it was not in the consul service catalog, right? If
Would "tags" mentioned as part of route add be included as part of the service definition then?
Is some kind of a marker needed for the parser to target?
Option 1 above (registry/consul) seems really interesting even in light of tighter coupling to consul. This could be a competitive and usability advantage (vs something like nginx+, etc.) if I understand what you are proposing. Stepping back for just a minute... We have access to really good tooling ( If Fabio gave us the ability to define all routes in consul and also use consul services by name, I would try to use it in lieu of the Here is a real-world example of an service {
name = "api"
port = "http"
tags = [
"http",
"urlprefix-api.example.com/",
"urlprefix-api.us1.example.com/",
"urlprefix-api.eu1.example.com/",
"urlprefix-api.example-dev.com/",
"urlprefix-api.us1.example-dev.com/",
]
} I'm not sure how other users are handling this. Maybe they are templating the job file on submit to nomad, or outside of nomad, have some business logic that provides the appropriate routes as tags for the region and environment. I'm just registering everything for convenience, but it adds weight to the routing table and feels a bit clunky. I also might want the developer of the service to not have to worry about the routing if another team is handling it. As we discussed earlier in this issue, the urlprefix routes shown are just the static ones that are always present. Subdomain and CNAME routes can be added, changed, or removed for one of our applications dynamically and that's where idea of having Fabio route to healthy members of a service by service name comes in. Ideally, these route commands (all stored in
These route commands omit the As I understand it, the remaining piece is how to use consul service entries when I prefer the lack of a
|
The goal of the config language is to provide a textual representation of the routing table so that humans and machines can read it. Otherwise, manual changes would require a different syntax. The
becomes
When I've developed fabio, nomad didn't really exist and we've deployed self-registering services. The idea was that services know which routes they can handle and by deploying them you make them routable. This way you never have to store a routing table in a separate system (e.g. Puppet) and coordinate deployment of the routing table with the deployment of the service. (routing table before services or after? How to handle roll-back?) You can just forget about this part altogether. However, different setups require different solutions and if you want to decouple service discovery from defining the routes then having the config language being able to express that would help. This is why I think option 2 is the cleanest solution since it decouples the two concepts which also means that you can update the service list without knowing about the routing and vice versa.
becomes
Now you can easily integrate different service discovery mechanisms or update the routing or do both. However, when you update the routing manually you have to coordinate this again for every deployment. I don't think that there would need to be marker to the service name itself but it may be helpful to indicate the origin of the service definition, e.g.
|
This patch extends the behavior of the registry.consul.kvpath and treats it as a prefix instead of a single key. fabio will now list the key and all available subkeys in alphabetical order and combine them for the routing table. Each subsection will get header which contains key name. Todo: the ui needs to handle that as well
Issue #396: treat registry.consul.kvpath as prefix
Ah, I think I've closed that one prematurely since this refers to multiple issues. #417 only addresses the 512kb limit. @stevenscg shall we pick the discussion up again if this is still relevant? |
I have a use-case where a large number of hostnames (or subdomains) (dozens to a few hundreds) need to be set for a particular consul service. While the number of hostnames is a problem and unwieldy to put into the job file, the hostnames can be added and remove programmatically as customers are provisioned.
I couldn't find any documentation on how to do this via the API, but figured out GET/PUT to
/api/manual
on the fabio UI port works for this.I have a request similar to #364 (comment) where more control over adding and removing routes for a given service would be ideal. I looked for a DELETE operation on the API to use when a hostname is added or removed programmatically, but one does not exist.
I also need to provide a route between a host (
foo.example.com
) and the service (app
) when hostnames are added or removed programmatically. Is this supported?Is this the correct syntax?
The text was updated successfully, but these errors were encountered: