What I did:
- Install Docker Desktop for Windows
- Enabled Kubernetes (throught "Settings" -> "Kubernetes" -> "Enable Kubernetes")
- Installed Nginx Ingress via YAML manifest: https://kubernetes.github.io/ingress-nginx/deploy/
- Installed kubernetes-dashboard via YAML manifest: https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/#deploying-the-dashboard-ui
- Checked that dashboard services and pods working fine:
- Took a minimal Ingress example (https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource) and created ingress manifest on it:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: root-ingress
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /dashboard
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
-
curl -k -v https://localhost response on localhost:
PS C:Windowssystem32> curl.exe -k -v https://localhost
* Trying [::1]:443...
* Connected to localhost (::1) port 443
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* ALPN: server accepted http/1.1
* using HTTP/1.1
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/8.4.0
> Accept: */*
>
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
< HTTP/1.1 404 Not Found
< Date: Mon, 22 Jan 2024 20:20:40 GMT
< Content-Type: text/html
< Content-Length: 146
< Connection: keep-alive
< Strict-Transport-Security: max-age=15724800; includeSubDomains
<
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host localhost left intact
- curl -k -v https://localhost response on localhost/dashboard:
PS C:Windowssystem32> curl.exe -k -v https://localhost/dashboard
* Trying [::1]:443...
* Connected to localhost (::1) port 443
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* ALPN: server accepted http/1.1
* using HTTP/1.1
> GET /dashboard HTTP/1.1
> Host: localhost
> User-Agent: curl/8.4.0
> Accept: */*
>
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
< HTTP/1.1 400 Bad Request
< Date: Mon, 22 Jan 2024 20:23:04 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Strict-Transport-Security: max-age=15724800; includeSubDomains
<
Client sent an HTTP request to an HTTPS server.
* Connection #0 to host localhost left intact
2
Answers
Else expose the 443 on your local machine for using curl
Quick fix
Just use NodePort
Dashboard will be available at https://localhost:31000
Root cause
What you are sending looks like this
Browser ==HTTPS==> ingress ==HTTP==> k8s-dashboard
But expected is
Browser ==HTTPS==> ingress ==HTTPS==> k8s-dashboard
The issues it that
k8s-dashboard
service expects HTTPS request, this is the reason why you getClient sent an HTTP request to an HTTPS server.
It was decrypted by ingress and later on forward by using plain HTTP
Solution
1 Export TCP port without using ingress
Instead of using ingress you can use NodePort (I gave it in Quick fix) or LoadBalancer. Idea is to work on ISO Layer 4(IP) instead of routing it using Layer 7(HTTP)
2 Use
ssl-passthrough
from nginx-ingressTo make it work it needs two changes
kubectl edit
You have to add
- --enable-ssl-passthrough
(just one line) to theargs
After change it should look like
When route is created you can’t specify path like
/dashboard
because k8s dashboard doesn’t know it’s working in some subpath, so usingrewrite
will not resolve it as links generated by dashboard will be wrong(I wrote more about it here)So we need ingress route like this (with
ssl-passthrough
andbackend-protocol
)3 Disable https in kubernetes dashboard (I didn’t try)
When you disable HTTPS in kubernetes dashboard your flow will look like this
Browser ==HTTPS==> ingress ==HTTP==> k8s-dashboard
It will perfectly match what you have right now and should work without issues
As I didn’t try it I will leave this article how to do it.
There is also raw manifest but maybe a little old