8 ms·
Using HAProxy as an API Gateway, Part 1
- bedis9 8y agoHi, I did write this blog post. Feel free to ask if you have any questions.
- sombrerochapeau 8y agois the site down? edit: nevermind, my corporate firewall blocked it because it thinks it's a "proxy" website.
- PM_ME_YOUR_CAT 8y ago"If that weren’t enough, driving alone through such a place can seem like if you were to be buried, would anyone ever know?" Well this was...unexpectedly dark. Jokes aside, I love how, for a software that gets so much shit for being overly complicated, your config samples look clean as hell. Nice work dude!
- krn 8y agoAn honest question: why HAProxy should be prefered over EnvoyProxy[1] for building API Gateways? [1] https://www.envoyproxy.io/ https://www.envoyproxy.io/
- tyingq 8y agoHe works for Haproxy Technologies, so probably has not considered switching :) Edit: Probably also worth mentioning that some of the net functionality gap between the two has been closed. Haproxy added service discovery and h2 support some time after this was published: https://www.envoyproxy.io/docs/envoy/latest/intro/comparison https://www.envoyproxy.io/docs/envoy/latest/intro/comparison
- deleted 8y ago[deleted]
- tonyarkles 8y agoNot the OP, but a young greybeard with opinions :) I've set up a couple of API Gateways. One was a hand-rolled Go server; this could have probably been done using an existing off-the-shelf server, but there were some odd-ball requirements and it was pretty straightforward to just build the functionality. It did service discovery through Consul, applied some routing rules and the "special" logic, and that was about it. Every other time I've just use nginx. Why? Most of the API Gateway projects out in the wild are bloody complicated! I just looked at the docs for EnvoyProxy and the "Architecture Overview" pane is taller than my 1080p monitor! Yes, at massive scale with thousands of services, something like this is probably the right solution. When you've got a handful of services, an automated rolling deploy across a small cluster of nginx servers is A-OK. I've looked at a bunch of different packages, and every time my conclusion is that they introduce a massive amount of complexity that could be beneficial in the large, but will likely require a dedicated team to understand all of the intricacies of the whole system. KISS.
- rdli 8y agoEnvoy Proxy is pretty complex. It is really designed for machine configuration. This is one reason projects like Ambassador API Gateway (https://www.getambassador.io https://www.getambassador.io) exist -- it translates decentralized declarative Kube config into Envoy configuration (non-trivial exercise). That said, Envoy has some great features such as distributed tracing, a robust runtime API for dynamic configuration, gRPC load balancing, etc. Disclosure: I work on Ambassador.
- tnolet 8y agoThis is a great article and I love HAproxy. Even so much that I wrote a REST-like wrapper for it a couple of years ago to turn HAproxy into an API gateway. It touched many of the points in the article. Maybe useful for people in the field https://github.com/magneticio/vamp-router https://github.com/magneticio/vamp-router
- Natsu 8y agoAm I wrong, or is there still nothing that handles security in the API Gateway? For example, suppose you want to do OAuth in the gateway instead of building it into every API. I couldn't see anything to handle a use case like that. The best I see is that it can probably handle one-way SSL, but I'm not clear on how it would handle mutual authentication or verification of client certs (pinning, CRLs, or OCSP). It's a lot of work to build that into APIs separately and a lot of people who use API Gateways prefer to have the gateway itself handle security.
- bedis9 8y agoThis is part of part-2 of our blog post about api gateway with haproxy. It will feature token validation in Lua and much more fancy things..
- tnolet 8y agoCorrect, my old project did not include authentication.
- rzzzt 8y agoKong does handle security in that layer: https://docs.konghq.com/0.14.x/auth/ https://docs.konghq.com/0.14.x/auth/
- dannyfriar82 8y agoim not sure Kong supports mtls or cert pinning. https://github.com/Kong/kong/issues/2048 https://github.com/Kong/kong/issues/2048 i dont think it's able to hash your secret tokens either - rather stores them in plaintext. https://github.com/Kong/kong/issues/1237 https://github.com/Kong/kong/issues/1237 this kind of rules Kong out for any serious applications AFAIK - especially considering that an API Gateway is supposed to be a security product. istio, tyk, traefik support that out of box.
- Erwin 8y agoJust how pluggable is HAProxy, or is there anything else out there which allows higher async control over the routing? My need is some rather customized request routing, currently done by Python (fast enough to do thousands of RPS in just Python with PyPy) but it'd nice to use a standard product. For every incoming request, I want to decide where it gets routed on a per-request basis to but not necessarily immediately (so some callback / event based / out of process interface is needed) and I want to be notified when the request finishes or fails. Basically the request for /foo/bar may need to spawn a new foo-bar management process which can take a while to warm up, and appear at some unknown future destination. I had a look at e.g. Traefik, Kong, Envoy but they didn't seem like quite the right fit. Using e.g. Proxygen seems like overkill.
- sciurus 8y agoTake a look at OpenResty, which is nginx scriptable with lua. https://openresty.org/en/ https://openresty.org/en/ https://github.com/openresty/lua-nginx-module#access_by_lua https://github.com/openresty/lua-nginx-module#access_by_lua
- graphememes 8y agoJust a note, Kong is built on OpenResty and has a wide ecosystem of plugins already built in lua with it's own development kit to speed up development time of custom functionality. Cannot urge how many times it's saved my ass. Not to mention it's very easy to scale!
- sb8244 8y agoKong has ran well in production for us, but development can be slow due to the pure LUA scripting. I think some of the problems they have are fixed in an updated version, but there is no update path that doesn't involve re-writing every custom code we have. We're switching to openresty + LUA proxying to a co-located elixir server that will handle the access requests.
- 8y ago
- rubyn00bie 8y agoAnyone have any idea how using HAProxy compares to say Kong?
- graphememes 8y agoI had to muck around a lot more to get HAProxy (2-3 days) do what I could do with Kong out of the box (1-2 hours) and Kong was easier to scale for me (simple terraform scripts).
- jaequery 8y agoI’ve no experience with Kong but HAproxy is one of the simplest and sturdiest daemon server I have ever used. With just a couple tweaks to the config file, I know exactly what it will do and what it can’t do.
- baylisscg 8y agoTo be honest I'd sat Kong is slightly harder to set up as it wants a database (PostgeSQL or Cassandra) but offers more functionality out of the box. HAProxy is more focused on being … well a proxy for example it can handle straight TCP too. Its like the PostgreSQL vs ${NoSQL de jour}. HAProxy works fine to great as a default choice unless you've some requirement that makes Kong more attractive.
- abledon 8y agoWhy not just use Kong
- unixhero 8y agoCan the open source version of HAProxy also be used to achieve what is described in this tutorial?
- sf_barbary 8y agoI found it easier to create a centralized graphql server that stitches together all of my rest services with resolvers. I define all of the types, resolvers, and mutations for each of the services in the central graphql gateway and it clients don't need to know where they get data from. Why wouldn't you just use this approach?
- yellow 8y agoThe biggest problem with GraphQL in this regard is that it is a single endpoint. API gateways often define authorization rules, throttling rates, and caching times differently for each route. Consequently, you may need to write authorization, throttling, and caching logic in a separate layer or perhaps even in your microservices themselves.
- bedis9 8y agoGraphql seems to be limited because of its single endpoint design. So some features are applied globally while you may want them per route.
- fulafel 8y agoPiggybacking on this thread, what would currently be the most secure frontend proxy? Preferably something that is implemented in a memory-safe language, and has some credibile story about focus on security and being battle tested.
- rhymenoceros 8y agoTraefik[1] is written in Golang, which is technically a (depending on your viewpoint) memory-safe language. It has a pretty decent adoption rate, has a reasonable story for being built on battle-tested libraries, and has a pretty good reputation. Haskell has yesod[2] but I don't think there's a variant of that dedicated to nginx- or haproxy-esque reverse proxy duties. [1] https://github.com/containous/traefik https://github.com/containous/traefik [2] https://www.yesodweb.com/ https://www.yesodweb.com/
- bedis9 8y agoTraefik performance sucks... In my bench, it is like 6 times slower than haproxy on an AWS instance. It eats up a huge amount of memory and burns all the cups.... As well, traefik configuration is not flexible enough to match haproxy power... But this is not the purpose of the thread.
- jively 8y ago[Caveat emptor: I’m the CEO of Tyk] Tyk is an open source API gateway written in Go, it’s been battle tested in production PCI compliant environments and offers a large selection of security features. It’s also customisable in other languages other than Lua (Python, JS, and anything gRPC) ;-)
- rhymenoceros 8y agoHow does Tyk compare with Kong and other "API gateway" implementations?
- elkinthewoods 8y ago
- rhymenoceros 8y agoHas HAProxy cleaned up their dynamic reload issues? I am a pretty big fan having used HAProxy in production, but compared to the relative simplicity of "nginx -s reload" the restart complexity of HAProxy always gives me pause.
- rogerdonut 8y agoHello, HAProxy 1.8 brought hitless reloads and has solved all of these issues. You can find information on this here [1][2] [1] https://www.haproxy.com/blog/truly-seamless-reloads-with-haproxy-no-more-hacks/ https://www.haproxy.com/blog/truly-seamless-reloads-with-hap... [2] https://www.haproxy.com/blog/hitless-reloads-with-haproxy-howto/ https://www.haproxy.com/blog/hitless-reloads-with-haproxy-ho...
- rhymenoceros 8y agoThis is an improvement but it still seems like HAProxy is offloading a small (but annoying) amount of responsibility to users when handling restart requests. You still have to track the existing process' PID and give it to the new process, give the new process the same "-x [socket_file]" argument, and make sure the new process comes up before making any subsequent changes to the HAProxy config file. Does HAProxy have any plans to wrap this process juggling to make things as stupidly easy as nginx's reload behavior?
- rogerdonut 8y agoThe current method integrates with both init scripts and systemd. You shouldn't need to manually pass any of that information. Also, the -x option is not required if you are running HAProxy in master/worker mode in which case sending a SIGUSR2 to the master process would be sufficient. With that said, we do have further improvements planned for an upcoming release. Stay tuned :)