Search code examples
kubernetesnginx-ingress

How to route kubernetes nginx-ingress to dashboard in another namespace


I am trying out kubernetes and I have deployed my Nginx in the default namespace and I am trying to create a virtual server to route the dashboard.

nginx: default namespace dashboard: kubernetes-dashboard namespace

However, when I try to create the virtual server, it is giving me a warning that the virtualserverroute doesn't exist or invalid? From what I understand, if I will want to route to a different namespace I could do so by putting the namespace in front of the service.

nginx-ingress-dashboard.yaml

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: kubernetes-dashboard
spec:
  host: k8.test.com
  tls:
    secret: nginx-tls-secret
    # basedOn: scheme
    redirect:
      enable: true
      code: 301
  upstreams:
  - name: kubernetes-dashboard
    service: kubernetes-dashboard
    port: 8443
  routes:
  - path: /
    route: kubernetes-dashboard/kubernetes-dashboard

kubernetes-dashboard

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

Any hints what I have done wrongly? Thanks in advance.

192.168.254.9 - - [27/Apr/2021:07:14:43 +0000] "GET /api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ HTTP/2.0" 400 48 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36" "-"2021/04/27 07:14:43 [error] 137#137: *106 readv() failed (104: Connection reset by peer) while reading upstream, client: 192.168.254.9, server: k8.test.com, request: "GET /api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ HTTP/2.0", upstream: "http://192.168.253.130:8443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/", host: "k8.test.com"
192.168.254.9 - - [27/Apr/2021:07:14:43 +0000] "GET /api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ HTTP/2.0" 400 48 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36" "-" 2021/04/27 07:14:43 [error] 137#137: *106 readv() failed (104: Connection reset by peer) while reading upstream, client: 192.168.254.9, server: k8.test.com, request: "GET /api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ HTTP/2.0", upstream: "http://192.168.253.130:8443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/", host: "k8.test.com"

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kubernetes-dashboard
type: Opaque

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-csrf
  namespace: kubernetes-dashboard
type: Opaque
data:
  csrf: ""

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-key-holder
  namespace: kubernetes-dashboard
type: Opaque

Solution

  • Instead of defining a route, you need to go with an action.pass, as you want to redirect the requests to the service directly.

    Additionally, I don't have much experience of the VirtualServer resource, but Ingress resources should usually be on the same namespace of the service that you want to serve. The Ingress Controller picks them up even if they are in a different namespace. (This means that the tls secret needs to be in that namespace tho)

    So, I would put an action.pass and also put the VirtualServer in the same namespace of the resource you want to serve, something like the following:

    apiVersion: k8s.nginx.org/v1
    kind: VirtualServer
    metadata:
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    spec:
      host: k8.test.com
      tls:
        secret: nginx-tls-secret
        # basedOn: scheme
        redirect:
          enable: true
          code: 301
      upstreams:
      - name: kubernetes-dashboard
        service: kubernetes-dashboard
        port: 443
      routes:
      - path: /
        action:
          pass: kubernetes-dashboard
    

    If you use route, then you need to define a VirtualServerRoute with that name, like explained in the documentation ( https://docs.nginx.com/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#virtualserverroute-specification )