skip to Main Content

I’m trying to deploy my frontend client application and backend API on the same domain and I want the frontend on the base path: /

However, I realized that the frontend and the backend need two different rewrite-target to accomplish this.

front-end works with:

nginx.ingress.kubernetes.io/rewrite-target: /

while the backend works with:

nginx.ingress.kubernetes.io/rewrite-target: /$2

I tried using two different ingress services in order to accommodate different rewrite-target, but that fails because the host was the same domain.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: test
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-staging
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/add-base-url: "true"
    nginx.ingress.kubernetes.io/service-upstream: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "server: hide";
      more_set_headers "X-Content-Type-Options: nosniff";
      more_set_headers "X-Xss-Protection: 1";
spec:
  tls:
  - hosts:
    - test.eastus.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: test.eastus.cloudapp.azure.com
    http:
      paths:
      - backend:
          serviceName: webapp
          servicePort: 80
        path: /
      - backend:
          serviceName: api
          servicePort: 80
        path: /api(/|$)(.*)

I know I can make both work with the same rewrite-target /$2 if I change the frontend path to path: /app(/|$)(.*) but I don’t want to that except it is the only option.

Is there a way for me to better configure a single ingress to work for 2 different rewrite-target?

3

Answers


  1. I don’t know would you take it or not but it can a be solution. You can use two ingress for achieving your target. Each one will use different annotations. It will work fine.

    Just as like your current ingress yaml, make another yaml and put two different annotations in them and also put your front-end and back-end in them separately. host (host: test.eastus.cloudapp.azure.com) will be same as you provided here.

    Login or Signup to reply.
  2. Ingress with API version networking.k8s.io/v1 with k8s version 1.19+ can solve your problem. I have given an example below.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: simple-fanout-example
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: backend-service
                port:
                  number: 8080
    
    

    According to kubernetes documentation:

    In some cases, multiple paths within an Ingress will match a request. In those cases precedence will be given first to the longest matching path. If two paths are still equally matched, precedence will be given to paths with an exact path type over prefix path type.

    So, when you are looking for a resource located at path "/home.html", it only matches with your frontend service. But when you are looking for a resource located at path "/api/something" then it matches both service. But it will go to backend service always because of maximum path match stated above.

    Login or Signup to reply.
  3. [My original answer was closed on a technicality by @Samuel Liew – Samuel, the answer was actually a better fit for this question since it specifically addresses the issue of not getting a blank page on refresh when using Vue frontend routing]

    TLDR: The trick is to use "nginx.ingress.kubernetes.io/configuration-snippet" = "if ($request_uri !~* ^/(api|assets)) { rewrite ^/.*$ / break; }" which rewrites all paths except /api and /assets. The other thing to point out, I put my favicon within the assets folder and then <link rel="shortcut icon" href="/assets/favicon.ico"> in main.ts

    For the full solution, see: https://stackoverflow.com/a/75913365/7182570

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search