Route external traffic from a standalone nginx service to kubernetes nodeport service

1/31/2021

GOAL I want to get access to kubernetes dashboard with a standalone nginx service and a microk8s nodeport service.

CONTEXT I have a linux server. On this server, there are several running services such as:

  • microk8s
  • nginx (note: I am not using ingress, nginx service works independently from microk8s).

Here is the workflow that I am looking for: 1) http:// URL /dashboard 2) NGINX service (FROM http:// URL /dashboard TO nodeIpAddress:nodeport) 3) nodePort service 4) kubernetes dashboard service

ISSUE: However, each time I request http:// URL /dashboard I receive a 502 bad request answer, what I am missing?

CONFIGURATION Please find below, nginx configuration, node port service configuration and the status of microk8s cluster:

nginx configuration: /etc/nginx/site-availables/default

node-port-service configuration

node ip address

microk8s namespaces

Thank you very much for your helps.

-- itbob
kubernetes
nginx

2 Answers

1/31/2021

Indeed @AndD, you advice me to execute this command :

sudo microk8s kubectl describe service -n kube-system kubernetes-dashboard

In order to get these below information

  • Labels:k8s-app=kubernetes-dashboard
  • TargetPort:8443/TCP

thanks to this above information, I could fix the nodePort service, you can find below a snippet:

spec:
  type: NodePort
  k8s-app: 'kubernetes-dashboard'
ports:
 - protocol: TCP
  port: 8443
  targetPort: 8443
  nodePort: 30000

However, I did change the nginx configuration to

proxy_pass https://51.68.123.169:30000/

I do receive a successful response (html), then all remaining requests have a 404 status (js, css, assets).

http 404


edit

the html file contains a set of dependencies (js/img/css)

<link rel="stylesheet" href="styles.3aaa4ab96be3c2d1171f.css"></head>
...
<script src="runtime.3e2867321ef71252064e.js" defer></script>

So it tries to get these assets with these URL:

  • https::// URL/styles.3aaa4ab96be3c2d1171f.css
  • https::// URL/runtime.3e2867321ef71252064e.js

instead of using:

  • https::// URL/dashboard/styles.3aaa4ab96be3c2d1171f.css
  • https::// URL/dashboard/runtime.3e2867321ef71252064e.js

edit #2

I just changed again the subpath => dashboad/ to dash/

new nginx conf

And it works with chromium. But it doesn't with firefox. (not a big deal)

thank you very much AndD!


Besides, I got a similar issue with jenkins, however jenkins image contains a parameter that fixes the issue. docker run --publish 8080:8080 --env JENKINS_OPTS="--prefix=/subpath" jenkins/jenkins

I was expecting to find something similar with kubernetesui/dashboard but I haven't found anything https://hub.docker.com/r/kubernetesui/dashboard

https://github.com/kubernetes/dashboard

Well, I do not know how to configure very well nginx in order to display correctly the dashboard in a subpath and I didn't find any parameter in the kubernetes\dashboard image to handle the subpath.

-- itbob
Source: StackOverflow

1/31/2021

I'll summarize the whole problem and solutions here.

First, the service which needs to expose the Kubernetes Dashboard needs to point at the right target port, and also needs to select the right Pod (the kubernetes-dashboard Pod)

If you check your service with a:

kubectl desribe service <service-name>

You can easily see if its selecting a Pod (or more than one) or nothing, by looking at the Endpoints section. In general, your service should have the same selector, port, targetPort and so on of the standard kubernetes-dashboard service (which expose the dashboard but only internally to the cluster)

Second, your NGINX configuration proxy the location /dashboard to the service, but the problem is that the kubernetes-dashboard Pod is expecting requests to reach / directly, so the path /dashboard means nothing to it.

To solve the second problem, there are a few ways, but they all lay in the NGINX configuration. If you read the documentation of the module proxy (aka http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) you can see that the solution is to add an URI in the configuration, something like this:

proxy_pass https://51.68.123.169:30000/

Notice the trailing slash, that is the URI, which means that the location matching the proxy rule is rewritten into /. This means that your_url/dashboard will just become your_url/

Without the trailing slash, your location is passed to the target as it is, since the target is only and endpoint.

If you need more complex URI changes, what you're searching is a rewrite rule (they support regex and lots more) but adding the trailing slash should solve your second problem.

-- AndD
Source: StackOverflow