
Setting Up HTTP(S) Load Balancing – WebSocket proxy support - thesandlord
https://cloud.google.com/compute/docs/load-balancing/http/#websocket_proxy_support
======
thesandlord
I'm pretty sure this means Kubernetes Ingress on GCP now support WebSockets as
well! People have been asking for this feature for a long time, glad it's
available now.

(I work on GCP)

~~~
numbsafari
SNI support would also be really awesome. For certain kinds of traffic, the
risks associated with SSL proxying means the HTTP(s) Load Balancer is off
limits. Which is a shame, because it's an incredibly power feature compared to
AWS offering.

~~~
doubleorseven
Since when AWS is offering SNI on their load balancers?

I work at a SaaS company and we were facing the same issue in the cloud and
have to implement our own TCP LB's to support SNI. I really hope we will see
it in the near future but as i see it, Will I allow my clients to push
bytecode into my production machines on demand with the lowest sandboxing
possible to provide low execution times? I guess not.

~~~
numbsafari
As far as I know it doesn't.

I should have been more clear: GCP's Anycast, no-warming-need LB is way cooler
than AWS traditional, single-region with totally unreliable DNS "routing" on
top (because you always want to rely on client DNS TTLs to handle a service
cutover...).

The problem is, if you can't use a TLS proxy for security reasons, then you
can't use the HTTP(s) LB, which will make you less happy than if you could use
it.

~~~
zimbatm
In what scenarios is GCP's load-balancer not trusted but their compute
instance is?

~~~
numbsafari
When, up until recently, not even Google was willing to cover their own load
balancer under their BAA.

The load balancer is a shared resource. Your data is being decrypted and re-
encrypted in a shared memory space with all other customer's data. Consider
the issue CloudFlare customers faced recently [1].

[1] [https://techcrunch.com/2017/02/23/major-cloudflare-bug-
leake...](https://techcrunch.com/2017/02/23/major-cloudflare-bug-leaked-
sensitive-data-from-customers-websites/)

~~~
vgt
I am not in compliance, but absence of evidence doesn't imply evidence of
absence.

Google Cloud has probably industry's highest security standards in place [0] .
Getting governing bodies to sign off on their accreditations is a very
separate issue.

(work on Google Cloud)

[0]
[https://cloud.google.com/security/whitepaper](https://cloud.google.com/security/whitepaper)

------
19eightyfour
Congratulations!

This has been a long time coming. Good to see it landing. There must be some
technical challenges with doing a load balancer that is optimized for both
HTTP round trips, AND, HTTP upgrades to long lived TCP connections.

One issue is that, as stated in the Troubleshooting section of the linked
docs, source IP is not forwarded to application. Maybe in future the
X-Forwarded-For header, or some other source identification, will be provided,
as well.

~~~
manigandham
The HTTP load balancer does provide the X-Forwarded-For header. This is
standard behavior for all CDNs and load balancers now.

~~~
19eightyfour
If that's the case...how to explain that the docs say source IP is not
provided?

    
    
      Troubleshooting
      
      Load balanced traffic does not have a source address of the original client
      
      Traffic from the load balancer to your instances has an IP address in the ranges of 130.211.0.0/22 and 35.191.0.0/16. When viewing logs on your load balanced instances, you will not see the source address of the original client. Instead, you will see source addresses from this range.
    

Is it the case that, if the X-Forwarded-For header is present, then it is not
providing a source IP, or it is providing a source IP, but that this IP is not
listed in the traffic logs?

~~~
manigandham
The source IP of the HTTP request is the IP of the system that makes the TCP
connection, so when you use a load balancer it will always be coming from a
single IP. This is what webservers and other software use when logging which
is why the source IP does is not accurate in regular logging. That's what the
documentation is saying - it's in the _troubleshooting_ section because if
you're only seeing a single IP then it's because you're looking at logs that
won't have the right information.

Instead most proxies and load balancers add the X-Forwarded-For header which
appends all IPs that are involved in the request. If you read the entire
documentation page, the Fundamentals section shows what headers are added:

[https://cloud.google.com/compute/docs/load-
balancing/http/#c...](https://cloud.google.com/compute/docs/load-
balancing/http/#components)

    
    
       The proxies set HTTP request/response headers as follows:
    
       Via: 1.1 google (requests and responses)
       X-Forwarded-Proto: [http | https] (requests only)
       X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) 
       X-Cloud-Trace-Context: <trace-id>/<span-id>;<trace-options> (requests only)

~~~
19eightyfour
Just wanted to thank you for that information. And also give you some feedback
on commenting. The HN commennt guidelines mention to not insinuate someone
hasn't read the article. What you might not know is that I did read the
section you quote, but I did not know enough to resolve it myself without
asking a question. When I read that you didn't think I had, I felt you were
saying, the answer would be obvious if you had read it. That hurt because it
was like saying my question was stupid, which I don't like and I don't want to
feel discouraged from asking questions in future. Anyway, thanks for your
information, and I hope this feedback is useful.

------
nailer
Hey cool, they support HTTP/2 [1] and ECC (using P-256 curve) HTTPS certs [2]

[1] [https://cloud.google.com/compute/docs/load-
balancing/http](https://cloud.google.com/compute/docs/load-balancing/http) [2]
[https://cloud.google.com/compute/docs/load-
balancing/http/ss...](https://cloud.google.com/compute/docs/load-
balancing/http/ssl-certificates)

~~~
stephenr
Http/2 is only supported from clients to the load balancer. Connections back
to your instances will always be http/1.1

------
nodesocket
Feature request for GCE load balancers: Attach multiple/lots of SSL
certificates to a single LB instance.

~~~
manigandham
You need to ask on the Google issue tracker, not HN.

This is the outstanding ticket:
[https://issuetracker.google.com/issues/35904767](https://issuetracker.google.com/issues/35904767)

~~~
nodesocket
Thanks for the link. I added my +1 with the comment:

"Would be a competitive advantage as well since AWS ELB's don't support
multiple certificates attached to a single ELB."

------
Kiro
What applications can use a load balancer with WebSockets? All the stuff I've
built has required the WS connection to point to the same server anyway
(multiplayer etc) and I feel that's the most common case but I might be
completely wrong.

~~~
jdub
If your backends aren't stateless, then yeah, you'll have to make sure
connections hit the same backend (with session affinity via client IP,
cookies, etc).

But session affinity is a scalability anti-pattern, which should generally
only be used to support legacy applications. Ideally, you'd design your
application to use stateless backends, which tend to share state at another
layer (the database, memcache, Redis, etc).

~~~
caleblloyd
I disagree that session affinity, or any affinity for that matter is a
scalability anti-pattern. Why add more load on Redis or the Database if you
can do it in the app server? Your just adding latency and increasing database
load. Unused memory in the app server is free candy.

~~~
jdub
There are plenty of good reasons to avoid app server state (and thus session
affinity), among them: Inefficiently imbalanced load balancing can affect
performance and reliability, app server changes (service restart, reboot,
scale down) will drop state causing interruptions (often user visible), etc.

If you don't want unused memory on your app servers, don't provision it. :-)

~~~
caleblloyd
There's pros and cons to each method, as we've both pointed out. My main point
is that it's not an anti-pattern, it's an architecture decision, and the pros
and cons of each should be weighed when designing an app.

I just finished working on a real-time collaborative document editing service
and chose to use document affinity so that the app server could handle
collaboration directly. It is extremely performant and I'd choose this
approach again any day versus farming out to Redis/RethinkDB/etc. It persists
to a database as writes come in, and performs initial load from the database.
Local memory accesses are orders of magnitude faster than going over the
network, and it reaps the benefits.

------
jhgg
What's the benefit here instead of using the tcp load balancer? I'm guessing
it's primarily URL mapping.

Does it support websocket compression (meaning the load balanced servers don't
need to do compression - as it'd be handled by the proxy) We would probably
switch in a heartbeat if it did

~~~
searchfaster
Not sure if it GCP does, but the load balancer can handle HTTPS termination
and even filter out DOS attacks or handle rate limiting.

~~~
dyngts
Hi searchfaster,

Can you elaborate more from documentation that this new features can filter
out DDOS attacks or handle rate limiting? Because i can't find out that
statement

Thank you

~~~
Elect2
http(s) load balancer only route http(s) requests to your compute instances,
and hide the instance IPs. So at least Layer 3 DDOS can not touch your
instances.

~~~
dyngts
But, when talking Kubernetes. it is currently no support for internal load
balancer, right? so it's still have vulnerability to get exposed to the world.
Any comment about this?

Thank you!

------
stephenr
I find it quite ironic that Google - who pushed so hard to make http/2 happen,
and is pushing so hard to make https the defacto default for the web - don't
fully support _either_ in their own load balancing solution.

------
cemerick
Heroku has supported websockets through its routing infrastructure for ages,
along with things like SNI (which has been mentioned elsewhere here as things
people wish were available in GCP). Not a ding on GCP necessarily, just
notable how featureful mature cloud platforms are, such that "even Google" is
playing catch-up.

~~~
rdeckard0104
I wouldn't say playing catch up so much as I would say they're focused on
features that provide the greatest amount of benefit to the greatest number of
users. SNI is easily solved by setting up a Nginx proxy behind their HTTPS
load balancer. Sure, I would really like it if SNI were baked in, but where
they may seem like they fall short on small things, like this they are eons
ahead of other providers with products, like BigQuery. BigQuery has made all
the difference in the world for our engineering department. We have a vast,
robust data warehouse, it's easy to read/write, easy to manage, and best of
all we do not have the brunt maintenance around supports its own
infrastructure.

------
amasad
It doesn't say how this changes the load distribution algorithm. Since
websocket connections are usually long-running it wouldn't be as useful to use
the default RPS (requests per second) algorithm. Ideally, it would be
something that takes into account the number of connection each backend
instance has.

~~~
Cidan
You can already adjust the load distribution algorithm when creating the LB,
so I imagine this doesn't really change anything.

~~~
amasad
The distribution algorithm options are either a) rate or b) utilization. Re
rate, you can configure the Requests Per Second but this doesn't mean much in
a long-running connection context because some connections can be drastically
longer (hours, days?). This may lead to starvation or overloading an instance.

------
jpillora
Does this include AppEngine?

~~~
cobookman
It doesn't include appengine, but it enables appengine flex to one day support
it.

Also FYI Appengine Flex does support HTTP2 Server Push. You just got to do the
following:

Set Headers to: Content-Type: text/event-stream

Cache-Control: no-cache

Connection: keep-alive

//
[https://www.nginx.com/resources/wiki/start/topics/examples/x...](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-
buffering) X-Accel-Buffering: no

And use your favorite http2 server push framework.

~~~
luhn
What you showed in your example is Server-Sent Events, not HTTP2 Server Push.

~~~
spullara
It does work really well but is unsupported on IE.

