Multiple deployments in single service

8/2/2019

My backend has 5 different deployments, each serving the request in a specific port.

Frontend service contacts the backend service with the necessary details. The backend service should be able to decide the required pod (from one of the 5 deployments) to serve the request.

Instead of creating 5 different services, is it possible to link a single service to multiple deployments?

Kubernetes version: 1.12 Cloud being used: Amazon EKS

PS: My requirement is different from https://github.com/kubernetes/kubernetes/issues/24875 Similar question is unanswered: "Wire" multiple Deployments to one Service in Kubernetes

-- Rajavinoth
amazon-eks
eks
kubernetes

1 Answer

8/2/2019

The exact answer to your quest is: it is not possible today. As you have correctly seen in the issue and in the question (both facing the same situation) this could be a future implementation.

A possible solution/workaround is to delegate the problem to an upper layer but basically it depends on the situation and different services are always required.

Assuming that your deployments are 5 different application that do different things (otherwise why 5 different deployment and not 1 with n replicas?) and assuming they are http applications, you can use the ingress resource to ruote the traffic to the right deployment/service (assuming one service per deployment).

If your 5 deployment are created/updated/managed together (eg: are all in the same helm deployment) you can create a fanout ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: simple-fanout-example
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: service1
          servicePort: 4200
      - path: /bar
        backend:
          serviceName: service2
          servicePort: 8080
      - path: /aaaa
        backend:
          serviceName: service3
          servicePort: 4200
      - path: /bbbbb
        backend:
          serviceName: service4
          servicePort: 8080
      - path: /ccc
        backend:
          serviceName: service5
          servicePort: 8080

Or, if your 5 deployment are separated you can create 5 Different ingress serources with the same idea:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-for-app-1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: service1
          servicePort: 4200
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-for-app-1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /bar
        backend:
          serviceName: service2
          servicePort: 8080

and so on....

Creating 5 ingress or 1 fanout should produce the same result.

This approach works well with a nginx ingress controller but pay attention only to two things

  • path match: with the nginx controller version > 0.22 nginx.ingress.kubernetes.io/rewrite-target: / is an exact match. For example, if you wold like to redirect from /foo to / preserving all the uri after /foo (/foo/something?parameter=parameter_value to /something?parameter=parameter_value) your ingress rewrite rule should be like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-for-app-1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo/(.*)
        backend:
          serviceName: service1
          servicePort: 4200
  • conflict route: avoid conflicting rout, eg path: /foo/(.*) and path: /foo/bar/(.*) where a request for /foo/bar/something would match both the paths. The behavior could be difficult to predict and, if it worked as expected, it would not be stable
-- Federico Bevione
Source: StackOverflow