Search code examples
kubernetestcp

How to expose multiple TCP Servers through one load balancer


I have multiple deployments which run pods which run TCP servers. These TCP servers listen all on port 9999

Currently each deployment has their own load balancer service, which results in a different IP for each deployment.

However I would like to have one IP address to expose the deployments and only distinguish by port.

So for example:

<public-ip>:9001 -> deployment 1
<public-ip>:9002 -> deployment 2
<public-ip>:9003 -> deployment 3

I have read about Ingress but the docs state that

An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.

So that seems to be not an option.

For context the kubernetes is hosted in azure in an vnet and only needs to be accessed from within this vnet.


Solution

  • Functionality ingress depends on the controller implementation that you are using. For example nginx ingress controller supports TCP/UDP proxy as documented here

    The next example shows how to expose the service example-go running in the namespace default in the port 8080 using the port 9000

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tcp-services
      namespace: ingress-nginx
    data:
      9000: "default/example-go:8080"
    

    If TCP/UDP proxy support is used, then those ports need to be exposed in the Service defined for the Ingress.

    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      type: LoadBalancer
      ports:
        - name: http
          port: 80
          targetPort: 80
          protocol: TCP
        - name: https
          port: 443
          targetPort: 443
          protocol: TCP
        - name: proxied-tcp-9000
          port: 9000
          targetPort: 9000
          protocol: TCP
      selector:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx