Issue Load balancing via k8s ingress to containers instances within same pod

Hello,

I am tried to troubleshoot a scenario where traefik ingress is not load balancing between the backends defined in the ingress rule.

Here’s some background.

I have a pod, that has two instances of the same app container. Each instance listening on a different port.
I have created two different services, with each service routing to one of the app instances, based on targetPort.

Here’s how these services look.

apiVersion: v1
kind: Service
metadata:
  name: app1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9000
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP
apiVersion: v1
kind: Service
metadata:
  name: app1-s1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9001
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

I can hit these services and reach the respective container instance.
However, I am trying to put both of these container instances, behind a single IP.
So,, that services that consume this app, can reach to both instances of the container within the pod.
And for this reason, I am trying to leverage traefik ingress vs a native k8s service, which I couldnt figure out if there is a way to do.

So, here’s how I created the traefik ingress rule.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    traefik.ingress.kubernetes.io/service-weights: |
     app1-s1: 50%
     app1: 50%
  name: app1-traefik
  namespace: exp
spec:
  rules:
  - host: app1-traefik
    http:
      paths:
      - backend:
          serviceName: app1-s1
          servicePort: 8001
        path: /
      - backend:
          serviceName: app1
          servicePort: 80
        path: /

I also have a service app1-traefik, setup this way.

apiVersion: v1
kind: Service
metadata:
    name: app1-traefik
  namespace: exp
spec:
  externalName: traefik-ingress-service.kube-system.svc.clusterexp
  sessionAffinity: None
  type: ExternalName

I try to hit the url app1-traefik from the pods, that want to consume the app1 service in the two containers within the pod.
It works, but it always seems to route to the pod behind the service defined to the end/last in the ingress rule above.

In the ingress rule above “app1-traefik”, app1 port 80 is defined to the end. And the requests via app1-traefik always go to the container behind this service.
the service weights seem to be playing no role here..or are not being honored.

And if and when I move app1-s1 on port 8001 to the end, the requests sent via app1-traefik seems to be always going to the container behind service app1-s1.

Note that I currently successfully use traefik, where the two backend services in the ingress rules are pointing to container in different pods.

However, this seems to not work when the containers are in the same pod.

Is this the expected behavior? Or am I missing something here?

Thanks and greatly appreciate any pointers.

What about something like this?

apiVersion: v1
kind: Service
metadata:
  name: app1
  namespace: exp
spec:
  ports:
  - name: web
    port: 9000
    protocol: TCP
  - name: admin
    port: 9001
    protocol: TCP
 selector:
    service: app1-service
  type: ClusterIP
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
   name: app1-traefik
   namespace: exp
spec:
  rules:
  - host: app1-traefik
    http:
      paths:
      - backend:
          serviceName: app1
          servicePort: 9000
        path: /
      - backend:
          serviceName: app1
          servicePort: 9001
        path: /

Can you see if this works out for you?

Thanks @daniel.tomcej I;ve tried what youve suggested.
Requests only go to the port defined last in the ingress.
In the post above 9001 is the one defined last, so requests always go to the container thats listening on 9001.
If i move 9000 to the bottom, the reqeussts go to the container thats listening on 9000.