-
Notifications
You must be signed in to change notification settings - Fork 38.7k
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
HTTP L7 load balancer / reverse proxy #561
Comments
Discussed a bit in #260 already. I've got some folks looking at adding arbitrary load balancer units and label based query backends for http(s), sni, and websockets - will have them describe some of what they're working on soon. |
/cc @thockin |
Pull openshift/origin#88 in origin is a prototype of a route - a resource representing an inbound connection from the external network that would be satisfied by a load balancer and direct traffic to a service. It will (but is not yet) complemented by a go client implementation that can read endpoints like the kube-proxy and generate arbitrary proxy server configs for things like apache, haproxy, and nginx. Ideally, those would be routers running in docker containers with external ips, parameterized by the address of the master. |
Yeah, I think something will need to work more or less out of the box On Wed, Sep 24, 2014 at 9:50 PM, Clayton Coleman notifications@github.com
|
FYI, /api/v1betaX/proxy/services/serviceName works already, and it's as load balanced as anything else in our system ;) |
I somehow doubt we want to route all external traffic through our apiserver On Thu, Sep 25, 2014 at 10:24 AM, Daniel Smith notifications@github.com
|
Just a headsup: Mailgun has a very slick go-based, etcd configured (with additional http control points) http proxy, Vulcand: https://github.com/mailpipe/vulcand |
For reference, GCE's L7 APIs:
"Route" sounds too network-y. URLMapper sounds more accurate. Not sure how fancy we'd want to get with URL mapping. Probably at least permit a target path, in order to facilitate multiplexing. Ideally not more general-purpose pattern matching. Copied from #2585: OpenShift's Route type:
Much like our service proxy watches endpoints, an HTTP reverse proxy, such as HAProxy, could watch routes and reprogram itself (or a management agent could do that to the proxy). I'd change this to follow v1beta3 metadata/spec/status conventions --host, path, and serviceName would go in spec. Also, rather than just service name, I'd be inclined to use whatever our canonical object cross-reference format is -- ObjectReference or (partial) URL (#1490 (comment)). I'm more and more leaning towards partial URLs, which would be generated similarly to selfLink upon GET of a particular API version. |
This is very much of interest to us as we run numerous applications, all fronted by a single external endpoint (eg, http://api.example.com). We've run our own in-house layer 7 load balancer / router for a few years now, and aside from URL rewriting (which is mentioned with the 'target path' thing), the only other feature I can think of which would be of interest is source address filtering. I'm also wondering if it would be good to define what http headers get added to the request. Since a layer 7 router hides a lot of the client information, this'll need to be passed on. Information such as client IP address, client/server port, whether the client is using SSL, SSL client cert subject & verification status, etc. |
Hi, I am master student who want to apply to GSOC. I am interested with this problem. And I had project that involving nginx as load balancer and reverse proxy in the past. Can this be implemented using nginx? |
It could, although we would prefer a solution that is generic to load balancers. The OpenShift route concept and mechanism is mostly fully implemented and integrates now with HAProxy and F5 automatically, and has a generic template mode for any other router. I think that a lot of the work for this has really been done, and it's a matter of defining how we evolve the service api and then moving that code over to Kube.
|
Hi guys, I've already created a working example of http reverse proxy and loadbalancer inside kubernetes using nginx + confd (with etcd backend, which is just a proxy to the master etcd). It is composed by three components:
A working controller+service example is also available at: https://github.com/glerchundi/kubernetes-http-loadbalancer Any comment is really appreciated! |
@glerchundi Thanks for the pointers! Just a quick comment for now since we're trying to wrap up 1.0. If you define a service (set portalIP: "None" if you don't need a VIP allocated) for your pods, the endpoints controller will generate a list of their addresses and ports in an Endpoints object for you. |
@bgrant0607 ok, thanks for pointing that out. After watching some videos about kubernetes, it seems that the best way/pattern to handle this is to watch services and not replication controllers / pods and modify the http load-balancer accordingly. Something like: Service 1: App Production (label: app, production) This would balance between two services (App Production & App Canary) which in turn will balance between all pods belonging to the corresponding replication controller. |
@glerchundi Do you mean "service 1" and "service 2" or "replication controller 1" and "replication controller 2"? Otherwise, yes, that's the recommended approach. |
I don't think joining is terrible. The route is an atomic unit of change, On Aug 7, 2015, at 8:54 PM, Prashanth B notifications@github.com wrote: Another idea we discussed was to move from a service-per-route model, to a type: routeSpec: That seems to fit better with my mental model of a website with multiple The openshift model is to have a route for /prod and another for /test, and Another wrinkle is that a router might be one or multiple IPs and DNSes. Is there a reason to handle each path with a different route object? — |
Ok, so it sounds like the main reason is that a single-service-per-route keeps it hermetic. I mostly buy that. I also like small resources because they're easier to update, watch, display etc, and I can invalidate a single path<->service (eg: because the service doesn't have nodeport, which is currently required for gce l7). So the model we're assuming is: a hostname + multiple url endpoints, each managed by a different kubernetes service. To make a useful 1.1 l7 api around this I think we need the ability to route all requests for that hostname, through a single ip, to different backends based on routes, without creating a global router up front (because gce only allows one cert per loadbalancer ip, and mixing the models complicates things). There are 2 ways to achieve this:
@thockin and @bgrant0607 wdyt? |
I'm having a hard time seeing the whole picture from this thread. I want e.g ingress{"foobar.com"} -> map{"/foo": Service{"foo", 80}, "/bar": Changing that to multiple route objects seems confusing and unnecessary. It might help to get a sketch of the data model and some examples using it. On Fri, Aug 7, 2015 at 7:34 PM, Prashanth B notifications@github.com
|
I may not have expressed it clearly, but having multiple paths and services per route doesn't seem so bad (nor multiple hosts) because you can change them atomically (which when doing a blue-green cutover has some advantages). We did not start with that due to caution, but in practice folks have asked for it. |
Gotcha. That sort of approximates GCE's API, too. We do need to think @justinsb (should have looped him in sooner, sorry). On Fri, Aug 7, 2015 at 9:12 PM, Clayton Coleman notifications@github.com
|
If we do have multiples we have to consider partial rejection on shared On Aug 8, 2015, at 12:15 AM, Tim Hockin notifications@github.com wrote: Gotcha. That sort of approximates GCE's API, too. We do need to think @justinsb (should have looped him in sooner, sorry). On Fri, Aug 7, 2015 at 9:12 PM, Clayton Coleman notifications@github.com
— |
Please review #12827 when you have time |
AWS ELB has very limited Layer 7 support. Although it has some Layer 7 features, these are limited to SSL termination (with a single cert), sticky sessions based on cookies, and writing an access log. There is no path-based routing for example. Typically you set up ELB in front of nginx/haproxy. I think we would likely want to do the same thing for AWS, with a k8s managed nginx/haproxy/vulcand. In other words, the AWS API for load balancing is so limited that I do not think we should even try to constrain the k8s API to fit within it. Rather, we should have a k8s option that uses a cloudprovider Layer 4 load balancer in front of a k8s managed software load balancer. If you have a better load balancer (GCE, OpenStack, hardware) then ideally we would allow you to use that instead. But AWS will be primarily software implemented. |
In AWS land, they have a separate service for this, API Gateway. It's basically another layer that sits on top of the ELB. |
Oh, good point @phemmer. I hadn't seen it marketed this way, but it does look like we could indeed use API Gateway as "just" a Layer 7 load balancer. I can't help but worry that it isn't really what it is intended for, but I'm very happy for the suggestion - we'll have to evaluate it! |
Yeah, that's how we use ELB today - as the HA layer for a pair of redundant On Mon, Aug 17, 2015 at 10:14 PM, Justin Santa Barbara <
Clayton Coleman | Lead Engineer, OpenShift |
This is exactly the case for loadbalancer classes (either embedded in the ingress point or via claims). I'm a little wary of offer this out of the box, because there are several multi-tier setups (ELB l7 for ssl termination -> nginx, f5 l4 -> apache ssl proxy -> l7 etc). You should have 2 loadbalancer controllers, one for aws and another for haproxy. handwaving a bit in this example: aws and haproxy loadbalancer controllers running in cluster
This is why I'd like to move away from the current interface/cloud-provider model, to a more plugin centric approach. Each loadbalancer is a different beast and kube should just get out of the way. Most of the points @justinsb mentioned for ELB are true for GCELB as well. |
/cc @mikedanese https://github.com/kubernetes/contrib/tree/master/service-loadbalancer seems a nice project to fork and take further on to support other load-balancing solutions. |
@bprashanth actually authored that package. I'm just git blamed since I moved it out of the main repo. |
I haven't seen this mentioned here, but is there any thought on integrating the new HTTPS LBs on GCE? https://cloud.google.com/compute/docs/load-balancing/http/ssl-certificates?hl=en_US We currently create separate RCs to host a standard nginx reverse-proxy with SSL termination for each "real" service that we host on Kubernetes. This is managable so far, but leveraging Kubernetes to auto-create a managed LB for us, would be much better. |
@pires yeah the real challenge is providing a consistent interface that allows multiple loadbalancers to co-exist in the same cluster. https://github.com/kubernetes/kubernetes/pull/12827/files talks about our efforts in this direction. @JeanMertz yes. See same TLS bits on same proposal. |
related to https://github.com/kubernetes/contrib/tree/master/service-loadbalancer which proposes resolution of this issue as a possible next iteration |
Can this be closed in favor of more specific follow-up issues? |
I'm closing this in favor of the more detailed bugs, now that we have something. Yay! |
Make machine-id sources flag a comma-separated list.
Remove node_modules from GitBook
Resolving conflicts for pull request kubernetes#561 and adding documentation.
Added arm64 targets for linux binaries
Configurable, using labels to route traffic.
From discussion: https://groups.google.com/d/msg/google-containers/frOLMyNl5U4/W5_DQUL933IJ
Like I said, I'm not sure this is needed if there's a good load balancer and DNS name resolution, but filing this for tracking the discussion.
The text was updated successfully, but these errors were encountered: