kubectl error while connecting to Rancher Kube API server behind nginx - nginx

My setup has Rancher and Nginx.
Nginx handles SSL Certificate and forwards requests to Rancher.
Rancher recommends using this config in Nginx:
The nginx config is done as recommended by rancher. It looks like this:
location / {
proxy_pass http://localhost:8082/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# This allows the ability for the execute shell window to remain open for up to 15 minutes. Without this parameter, the default is 1 minute and will automatically close.
proxy_read_timeout 900s;
proxy_buffering off;
}
However I get this error when I use kubectl:
$ kubectl get all
Error from server (InternalError): an error on the server ("invalid upgrade response: status code 200") has prevented the request from succeeding
Since the error message points to some problem related to "upgrade", I comment these two lines from the nginx config above and reload nginx:
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade";
After this, kubectl starts working properly but Rancher UI gives this error:
How do I make both - kubectl and Rancher UI - work properly?

I solved this by creating another nginx location configuration for URLs accessed by kubectl, and commented out other customizations.
Rancher hosts the Kube API at https://mydomain/k8s/clusters/mycluster
Assuming URLs beginning with /k8s/ don't require Websockets or anything fancy, I disabled upgrade (and subsequently all customizations) for this section of the URL space.
The working config looks like this:
location / {
proxy_pass http://localhost:8082/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# This allows the ability for the execute shell window to remain open for up to 15 minutes. Without this parameter, the default is 1 minute and will automatically close.
proxy_read_timeout 900s;
proxy_buffering off;
}
location /k8s/ {
proxy_pass http://localhost:8082/k8s/;
}

Related

Configure subdomain shinyproxy

First things first, I'm quite a beginner at hosting shiny apps on docker and shinyproxy. The terms I use might be a bit layman and incorrect.
I have my application running well on shinyproxy and can be accessed through serveripaddress:8080/app/01_hello.
The problem comes when I try to use a link ie. theapp.company.com instead of the ip address. This is what it shows when I go to the link:
Here is the necessary part of 01_hello nginx configuration file:
location / {
proxy_pass http://localhost:8080/app/01_hello;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 600s;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
But when I change the proxy_pass to:
proxy_pass http://localhost:8080;
then go to theapp.company.com it shows the landing page of all apps on shinyproxy and then I can go to theapp.company.com/app/01_hello which works, but not what I want.
I just want it to be theapp.company.com. How do I achieve this?
I have a very similar setup and it works for me. I believe the problem is that you are using "app" instead of "app_direct" in proxy_pass. This is my nginx proxy config (localhost instead of 127.0.0.1 or 0.0.0.0 should be fine):
location / {
proxy_pass http://127.0.0.1:8080/app_direct/mimosa/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 600s;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Using the /app/ path seems to confuse shinyproxy. If you run shinyproxy via java directly (with your setup) you will see requests that do not match the correct URI. You can also check the console (F12 in chromium), which shows failed loading of resources.
Not sure if this can be fixed easily with the nginx config.
Usually, the navbar at the top is not needed, so app_direct is a simple solution. Hope it helps. If not, can you post your entire nginx config and application.yml? (you can remove sensitive parts)

StreamLit behind Nginx behind reverse proxy (load balancer)

I have a Docker app running on an Nginx webserver, that works fine connecting directly to the webserver. However, the webserver is behind a separate Nginx reverse proxy server (functioning as WAF, load balancer, and in some cases directs path specific requests to different servers - as in this specific case).
The internal server config, which works if I connect directly to this server, look like:
# redirect without the trailing slash because the author did not include the full path in the Docker app
location /apppath/editor {
return 302 /apppath/editor/;
}
location /apppath/editor/ {
proxy_redirect off;
proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://0.0.0.0:8501/editor/;
}
location /apppath {
alias /var/www/dockerapp;
try_files $uri $uri/ =404;
}
I could not find examples of multiple levels of reverse proxy for a websocket app, so I have tried countless variations, but the public (LB/WAF) config currently looks like:
location /apppath {
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_headers_hash_bucket_size 128;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_set_header Host $host;
proxy_http_version 1.1;
#proxy_buffering off;
#proxy_set_header Forwarded "for=$proxy_add_x_forwarded_for;proto=$scheme";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
#proxy_set_header Referer $http_referer;
proxy_pass https://10.0.6.13:443;
}
From the public location, requests to /apppath/pages.html work fine, but when I attempt to hit /apppath/editor/ I see only "Please wait..." with the "Made with Streamlit" tag at the bottom.
My browser shows repeated requests for /apppath/editor/healthz and the console is full of:
WebsocketConnection WebSocket onerror
Uncaught Error: Unsupported state transition
State: PINGING_SERVER
Event: CONNECTION_TIMED_OUT
...

Proxy_pass to url NGINX with a Meteor Server

I have configured a meteor server and setup the nginx configuration. The route works however when configuring dynamic subdomains to point to a specific part of the web app it produces a 404 error on the browser when loading the meteor file.
I am attempting to direct all *.domain.com to http://localhost:3000/booking/
My configuration is:
server {
server_name *.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000/booking/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
The 404 occurs in the Meteor JS file.
If I remove the above nginx subdomain configuration and go to a subdomain it works perfectly, loading the route application. I assume I am missing something to load the application correctly.
The issue only occurs when I proxy_pass to a route within the URL <url>/booking
There are different ways of solving the issue.
1 - In case of 404 try a fallback option without booking in url
server {
server_name *.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000/booking/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
error_page 404 = #fallback;
}
location #fallback {
proxy_pass http://localhost:3000/$request_uri;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
2 - Have a separate block for js and css
server {
server_name *.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000/booking/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
location ~ \.(js|css|font)$ {
proxy_pass http://localhost:3000/$request_uri;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
I have a similar setup, where I have configured different Meteor applications on several subdomains plus a static website on the domain root, all pointing interlly to different ports.
Here is my setup step by step.
Folder structure, location and proxy pass
First thing to think about is the folder strucutre. Depending on your subdomain's VHost-root directory there is a relative path to your subdomain's application folder.
Imagine the following setup:
/www (dir, usually under /var)
/domain (dir)
/websitexy (dir, a static website is deployed under this dir)
/subdomain (dir)
/books (dir, subdomain app is deployed under this dir)
For such a setup I made my nginx config to point to the app's location within the subdomain:
location /books {
I had a similar issue when first time starting my app. One thing I found out is, that my config worked, when setting proxy_pass on my private ip/port combination:
proxy_pass http://172.x.x.x:3000;
This also involves to remove the route name (/books) adter the port number on this entry. Now your proxy pass involves all routing within your subdomain.
Note on routing
Note, that there can be confusion about routing here. By setting the location property you set the routing on the nginx level (server's directory structure), which is why there is no route within your proxy pass.
Your application may have it's own internal routing defined. It is important, that you app's internal router retrieves all requests based from it's application ur root. This is why it is important to have the proxy pass not to include any path after the port number.
Websocket
I have read some articles on nginx and websocket connections. Basically my initial settings came from this article and looked like from this documentation article:
location /app {
proxy_pass 172.x.x.x;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
I also had to add a proxy_read_timeout and proxy_send_timeout because there was an issue with the websocket protocol otherwise:
By default, the connection will be closed if the proxied server does
not transmit any data within 60 seconds. This timeout can be increased
with the proxy_read_timeout directive
So I also set the timeout values:
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
proxy_set_header Connection "upgrade";
Read more on this here and here.
Summarizing my setup looks like the following (using your app credentials):
location /books {
proxy_pass http://172.x.x.x:3000;
proxy_http_version 1.1;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
So to solve your case, you may check on your vhost directory (the one where your app is deployed, see folder structure above) and change your location and proxy_pass setting accordingly.
If this is not working, you may need to add some more output of your errors, e.g. a excerpt of the log when attempt to connect.

nginx proxy doesn't wait for slow meteor app

I have a meteor app running at meteor:3000, but some files are served to the client very slow (up to 10s), because the server isn't powerful.
It works when accessing the meteor app directly, but using the nginx reverse proxy the files that need long to serve don't get served at all, they result in a 404.
This is my proxy configuration
location / {
proxy_pass http://meteor:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
proxy_connect_timeout 100000000s; # these values seem to not affect nginx at all
proxy_send_timeout 150000000s;
proxy_read_timeout 200000000s;
}
Loading the site using reverse proxy
Loading the site directly

Using Flask-Sijax's Comet with Nginx

I have a Flask app in which I'm using Sijax's Comet to stream data from the back end to the front end. This works normally when I'm running my app by starting it with the command python app.py
Now I'm trying to run my app with Nginx. Instead of streaming my data nicely as it comes along, the app seems to wait until all data has been streamed before sending it to the browser.
Is there some Nginx configuration or Sijax setting to enable or disable?
You can find a nginx configuration like this on StackOverflow.
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_cache off;

Resources