Kubernetes TCP Load Balancing Based On Content - kubernetes-ingress

I have a TCP based application, which sends some ID on the first bytes when connecting to the server.
I want to use this ID to determine which server the load balancer should forward to.
(The first 4 bytes when a new client connects will determine the server to connect to behind the load balancer)
Unfortunately, I can't change the protocol, control the port or anything else that could help me determine based on metadata.
Today, I'm forced to write my own TCP load balancer which is basically a forwarder between sockets, but it sucks :-)
I looked at NGINX and HAProxy modules/add-ons but couldn't find how to do it.
Thanks in advance!

Related

Django ERR_EMPTY_RESPONSE

I am currently running a Django site on ec2. The site sends a csv back to the client. The CSV is of varying sizes. If it is small the site works fine and client is able to download the file. However, if the file gets large, I get an ERR_EMPTY_RESPONSE. I am guessing this is because the connection is aborting without giving adequate time for the process to run fully. Is there a way to increase this time span?
Here's what my site is returning to the client.
with open('//home/ubuntu/Fantasy-Fire/website/optimizer/lineups.csv') as myfile:
response = HttpResponse(myfile, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=lineups.csv'
return response
Is there some other argument that can allow me to ignore this error and keep generating the file even if it is taking awhile or is large?
I believe that you have any sort of backend proxy server which resets the connection to the Django backend and returns ERR_EMPTY_RESPONSE for the case. You should re-configure timeouts on your backend proxy. Usually that is nginx or apache used as a reverse proxy server.
What is Reverse Proxy Server
A reverse proxy server is an intermediate connection point positioned at a network’s edge. It receives initial HTTP connection requests, acting like the actual endpoint.
Essentially your network’s traffic cop, the reverse proxy serves as a gateway between users and your application origin server. In so doing it handles all policy management and traffic routing.
A reverse proxy operates by:
Receiving a user connection request
Completing a TCP three-way handshake, terminating the initial connection
Connecting with the origin server and forwarding the original request
More info at https://www.imperva.com/learn/performance/reverse-proxy/
One more possible case - your reverse proxy backend server doesn't have enough free space to process response from Django and aborts the request. You can also check free space on your reverse proxy balancer.
Within gunicorn, there is an argument for timeout, -t. When you run gunicorn, the default timeout is 30 seconds. Increase that to something your comfortable with like 90 or 120 seconds, whatever you think fits your application.

GCE managed group (autoscaling) - Proxy/Load Balancer for both HTTP(S) and TCP requests

I have an autoscaling istance group, i need to setup a Proxy/Load balancer that take request and send it to the istance group.
I thinked to use a Load balancer, but I need to grab both HTTP(S) and TCP requests.
There is some way (or some workaround) to solve this?
EDIT: The problem is that from TCP LB settings i can set the backend service (the managed group that i need to set) only for one port.
For your use case, a single load balancing configuration available on Google Cloud Platform will not be able to serve the purpose. On the other hand, since you are using managed instance groups (Autoscaling), it can not be used as backend for 2 different load balancers.
As per my understanding, the closest you can go is by using Network load balancing (TCP) and install SSL certificate to handle HTTPS requests
on the instance level.

GCE- UNHEALTHY target group machine

I am using Tomcat7 which is running on port 80.
Services directly to instance IP works just fine but calling services from LB IP throws 502 error.
Assuming, you are using managed instance group for maintaining the homogeneous instances. You need to establish a service endpoint which the load balancer can use to direct the traffic. This might be the problem.
I have written the steps to set up an load balancer here. As, load balancer contains lot of moving parts like target proxies, forwarding rules, backend services. It is difficult to debug without any config files. Posting your config here, would help us debug it better.
What I did to make Load balancing (LB) work is mentioned below.
I created a layer of nginx which by default runs on port 80.
I connected to tomcat7 layer using default file of nginx. Tomcat is now running on default port i.e. 8080.
So when LB tries to connect to my instance group it connects through http port 80.
Health check is really important. Health check of LB should pass. To make it pass keep a file on instance group instances. Like "/foo/bar/index.html" on "/var/lib/tomcat7/webapps/foo/bar/index.html". So that LB can directly connect to this file. Once the health check has passed. Then it wont show that instances are unhealthy.
Keep the same health check for instance group. Instance group also checks for same path as mentioned above.
Ideally health check should have passed without keeping this file. But have tried it several times it does not pass the health check the only way to make it pass is to keep that file.

Google Cloud HTTP Load Balancer can't connect to my instance

I have created a HTTP load balancer to basically redirect from port 80 to port 8080. The server on my instance is running on port 8080.
I can connect to the server directly but the LB is not able to connect to the instance, both accessing the LB's IP directly and also the health check always fails. The instance group the LB is using consist of just that single instance.
I read Google Compute Engine health checks failing
and the google-address-manager is running. However, when running ip route table list local there is no routing for my LB. The user in the above question is using Network load balancing and not HTTP load balancing (as I am) so I don't know if that is related?
Or perhaps it's related to a firewall? I have added my LB's ip address to a firewall rule that allows tcp:8080
Does anybode have any idea how can I fix this? I am not experienced with debian nor gcp.
Show I just try and run the route add command referenced in the above question? If so, how come the google-address-manager is not adding the route?
Thank you in advance!
You need to make sure that your port mapping on instance group is set to correct port, the 8080 in your case.
First, edit your instance group and change the port name and port to 8080:
Then, navigate to your http backend's settings and change the default port to the port name you've configured in your instance group.
Finally, make sure that your firewall rules allow access on port 8080 from 0.0.0.0/0 or at least from the IP address of HTTP load balancer (130.211.0.0/22)
I had the same issue and fixed it by adding a firewall rule for the health checker (which is not the same IP as your LB!). See https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=en_US#http_and_https_load_balancing for instructions.
In my case, I did not configure the HTTP health check correctly.
I used "/" as path, but on my backend, "/" redirects to a login-page (HTTP 301), which responds with a HTTP 200.
The health check does not follow a redirect, every HTTP response code != 200 is assumed unhealthy (from Debugging Health Checks in Load Balancing on Google Compute Engine).
So, I changed my path to "/login", this fixed my issue.

NodeJS + HTML5 + Telnet = isitpossible?

I have this project for my classes i'm currently workin' on. here it is:
WebPage client for Telnet not on standard ports, with ability to choose a port and connect
I have machines with telnet servers on them, just waiting for connection.
So my idea was to set up a nodeJS with express server on a dedicated machine. This would handle connections through telnet and host a page for clients, that would use socket.io to exchange information with server side.
But as i'm new to such technologies (telecommunications student) i wonder if it is possible. I spotted something like this - jsterm.com by Peter Nitsch, but i see there are some massive gaps in code and the demo does not really work so i don't know if it actually works. Did anyone try this?
My other problem is - when i send information to nodeJS server through websockets, which seems achievable for me, what do i do with this information? Do i just set up another websocket to pass the same data i got from client websocket directly to the telnet port?
Can sockets connect directly to specific port, without any websocket waiting on the other side?
If my idea is wrong, could anyone help me - maybe there exists some nice solution - i was thinking about Anyterm for example but i see that it requires an apache server and runs completely different technologies...
Just to be clear, WebSocket connections are not raw TCP socket connections. They have extra header information in each packet, browser to server data is masked using a running XOR, etc.
In order for the browser to communicate with a normal TCP server (e.g. a telnet server) you will need some sort of bridge service. It just so happens that such a thing already exists. websockify is a server that accepts WebSocket connections and bridges them to a raw TCP server.
In fact, the websockify project already includes a working telnet client as an example application. However, note that one limitation of websockify (for security reasons) is that the client cannot pick an arbitrary server address/port to connect to. The target address(es) must be predefined, either as a single target specified on the command line for websockify, or as multiple targets specified in a configuration file (and selected via a token in the WebSocket connect string).
There are multiple implementations of websockify in different languages (python, C, node, ruby, Clojure) however, only the python version currently supports multiple targets via a configuration file.
Disclaimer: I created websockify.