4
votes

I have configured a kubernetes ingress service but it only works when the path is /

I have tried all manner of different values for the path including:

/*
/servicea
/servicea/
/servicea/*

This is my ingress configuration (that works)

- apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: boardingservice
    annotations:
      ingress.kubernetes.io/rewrite-target: /
  spec:
    rules:
    - host: my.url.com
      http:
        paths:
        - path: /
          backend:
            serviceName: servicea-nodeport
            servicePort: 80

This is my nodeport service

- apiVersion: v1
  kind: Service
  metadata:
    name: servicea-nodeport
  spec:
    type: NodePort
    ports:
    - port: 80
      targetPort: 8081
      nodePort: 30124
    selector:
      app: servicea

And this is my deployment

- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: servicea
  spec:
    replicas: 1
    template:
      metadata:
        name: ervicea
        labels:
          app: servicea
      spec: 
        containers:
        - image: 350329402011.dkr.ecr.eu-west-2.amazonaws.com/servicea
          name: servicea
          ports: 
          - containerPort: 8080
            protocol: TCP              
        - image: 350329402011.dkr.ecr.eu-west-2.amazonaws.com/serviceb
          name: serviceab
          ports: 
          - containerPort: 8081
            protocol: TCP  

If the path is / then I can do this http://my.url.com/api/ping but as I will have multiple services I want to do this: http://my.url.com/servicea/api/ping but when I set the path to /servicea I get a 404.

I am running kubernetes on AWS with an ingress-nginx ingress controller

Any idea?

2

2 Answers

6
votes

You are not using kubernetes Pods as they are intended to be used. A Pod

it contains one or more application containers which are relatively tightly coupled — in a pre-container world, they would have executed on the same physical or virtual machine.

If you have two applications, servicea and serviceb, they should be running on different Pods: one pod for servicea and another one for serviceb. This has many benefits: you can deploy them separately, scale them independently, etc. As the docs say

A Pod represents a unit of deployment: a single instance of an application in Kubernetes, which might consist of either a single container or a small number of containers that are tightly coupled and that share resources.

These Pods can be created using Deployments, as you were already doing. That's fine and recommended.

Once you have the Deployments running, you'd create a different Service that would balance traffic between all the Pods for a given Deployment.

And finally, you want to hit servicea or serviceb depending on the request URL. That can be done with Ingress, as you were trying, but mapping each path to different services. For example

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: my.url.com
    http:
      paths:
      - path: /servicea
        backend:
          serviceName: servicea
          servicePort: 80
      - path: /serviceb
        backend:
          serviceName: serviceb
          servicePort: 80

That way, requests going to your ingress controller using the /servicea path would be served by the Pods behind the servicea Service. And requests going to your ingress controller using the /serviceb path would be served by the Pods behind the serviceb Service.

6
votes

For anyone reading this, my configuration was correct (even though unorthodox, as pointed out by fiunchinho), the error was in my Spring Boot applications, that were running in the containers. I needed to change the context paths to match the Ingress path - I could, of course, have changed the @GetMapping and @PostMapping methods in my Spring Controller, but I opted to change the context path.