Using Kubernetes ingress with two services and internal web API routing

6/15/2021

I have two ASP.NET Core applications app1 and app2. Inside these apps I have routes as defined in this simplified code:

app1:

endpoints.MapGet("/app1ep1", async context =>
{
    await context.Response.WriteAsync("x1");
});

endpoints.MapGet("/app1ep2", async context =>
{
    await context.Response.WriteAsync("x2");
});

app2:

endpoints.MapGet("/app2ep1", async context =>
{
    await context.Response.WriteAsync("y1");
});

endpoints.MapGet("/app2ep2", async context =>
{
    await context.Response.WriteAsync("y2");
});

I am trying to define without success an ingress rule that will apply the following routings:

  • myhost.com/app1/app1ep1 will route to the service app1 and then internal routing to ep1
  • myhost.com/app2/app2ep1 will route to the service app2 and then internal routing to ep1
  • the point goes on, please comment if extra clarification required

My ingress rule:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - path: /app1
        pathType: Prefix
        backend:
          service:
            name: myservice1
            port:
              number: 80
      - path: /app2
        pathType: Prefix
        backend:
          service:
            name: myservice2
            port:
              number: 80

Actual result is that the services are found but I get 404 error. In other words, browsing to myhost.com/app1/app1ep1 (or any other combination) routes to the service (myservice1) but then internal route is lost. Is there any way to fix this? Thanks for helping

Edit: I am noticing some other problem. I tried to reduce the problem to a single service. So my ingress now looks like:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - path: /app1
        pathType: Prefix
        backend:
          service:
            name: myservice1
            port:
              number: 80

Also added this controller to the "myservice1" app:

endpoints.MapGet("/", async context =>
{
    await context.Response.WriteAsync("x");
});

Going to myhost.com/app1 returns 404. That again means that the app is found but the route isn't found in the application (although I defined "/" route). Maybe this information can help discover the problem

-- Ohad
asp.net-web-api
c#
kubernetes
nginx
nginx-ingress

1 Answer

6/15/2021

I have solved this issue with the following ingress rule:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - path: /app1(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: myservice1
            port:
              number: 80
      - path: /app2(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: myservice2
            port:
              number: 80
-- Ohad
Source: StackOverflow