Kubernetes reverse proxy pod for node-specific services?

10/30/2018

In a Kubernetes cluster I have a per-node HTTP node-specific service deployed (using a DaemonSet). This service returns node-specific data (which is otherwise not available via the cluster/remote API). I cannot make use of a Kubernetes Service, as this would result in kind of a service roulette, as the client cannot control the exact node to which to connect (forward the HTTP request) to. As the service needs to return node-specific data, this would cause data to be returned for a random node, but not for the node the client wants.

My suspection is that I need a reverse proxy that uses a part of its own URL path to relay an incomming HTTP request deterministically to exactly the node the client indicates. This proxy then in turn could be either accessed by clients using the cluster/remote API service proxy functionality.

  • http://myservice/node1/.. --> http://node1:myservice/...
  • http://myservice/node2/... --> http://node2:myservice/...
  • ...

Is there a ready-made pod (or Helm chart) available that maps a service running on all cluster nodes to a single proxy URL, with some path component specifying the node whose service instance to relay to? Is there some way to restrict the reverse proxy to relay only to those nodes being specified in the DaemonSet of the pod spec defining my per-node service?

Additionally, is there some ready-made "hub page" available for the reverse proxy listing/linking to only those nodes were my service is currently running on?

Or is this something where I need to create my own reverse proxy setup specifically? Is there some integration between, e.g. nginx and Kubernetes?

-- TheDiveO
kubernetes
reverse-proxy

1 Answer

10/31/2018

It is almost impossible if you use DaemonSet, because you can't add a unique label for the pod in DaemonSet. If you need to distribute one pod per node you can use podaffinity. with StatefulSet or Deployments.

Then create a service for each node:

kind: Service
apiVersion: v1
metadata:
  name: svc-for-node1
spec:
  selector:
    nodename: unique-label-for-pod-on-node
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

And final setup Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /svc-for-node1
        backend:
          serviceName: svc-for-node1
          servicePort: 80
      - path: /svc-for-node2
        backend:
          serviceName: svc-for-node2
          servicePort: 80
-- Nick Rak
Source: StackOverflow