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?
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.