What I would like to avoid doing is setting up a separate pod like HAProxy that routes per port.
You don't need to set up such separate Pod.
The Kubernetes Ingress by default does not support TCP or UDP services. But for example, ingress-nginx
controller provides a mechanism to support TCP or UDP on different ports. You can expose TCP or UDP ports by modifying ConfigMaps.
For this reason, this Ingress controller uses the flags '--tcp-services-configmap' and '--udp-services-configmap' to point to an existing config map where the key is the external port to use and the value indicates the service to expose using the format:
<namespace/service name>:<service port>:[PROXY]:[PROXY]
Check additional info here.
Such ConfigMap should already be available before deploying the Ingress Controller.
So, try to:
1. Create a ConfigMap with the following TCP service configuration.
$ cat ingress-nginx-tcp.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-tcp
namespace: default
data:
"22": targetnamespace/target-service:22
2. Point Ingress controller to this ConfigMap using the --tcp-services-configmap
flag in the configuration like this:
$ kubectl get deployment ingress-nginx-controller -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
namespace: default
spec:
...
template:
...
spec:
containers:
- args:
- /nginx-ingress-controller
- --tcp-services-configmap=$(POD_NAMESPACE)/ingress-nginx-tcp
...
3. Expose port 22 in the Service defined for the Ingress like this:
$ kubectl get svc ingress-nginx-controller -o yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: default
spec:
ports:
- name: tcp-22
nodePort: 30957
port: 22
protocol: TCP
targetPort: 22
...
type: LoadBalancer
...
You can define any number of ports that can be exposed using this method.
There is another option for those who are using an ingress-nginx helm chart. Most of the configuration is already done, and you just need to specify your ports in tcp section like this:
tcp:
2222: "default/example-tcp-svc:22"
where 2222
is the exposed port and 22
is the service port.