I would like to create several databases inside kubernetes, and expose them trough ingresses, similar like name based virtual hosting solutions at standard http applications (https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting).
The problem is, databases works with TCP protocol.
If I try to set up TCP loadbalancing in my ingress controller (https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md), it works but one port can be used for one database only.
kubectl get cm -n ingress-nginx ingress-nginx-tcp -oyaml
apiVersion: v1
data:
"1521": oracle/oracle-19c-ee-svc:1521
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: ingress-nginx
meta.helm.sh/release-namespace: ingress-nginx
creationTimestamp: "2023-03-27T11:52:08Z"
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.7.0
helm.sh/chart: ingress-nginx-4.6.0
name: ingress-nginx-tcp
namespace: ingress-nginx
resourceVersion: "3997675"
uid: 7c477751-1ee1-462a-a4d6-ad78b003abf7
I would like to achieve name based TCP routing, similar like in the first link I posted.
As example:
db1.example.com:1521 -> goes to service db1
db2.example.com:1521 -> goes to service db2
(where example.com resolved as the loadbalancer IP, service db1 and db2 are services in kubernetes connected to two different databases)
Have you any suggestion? Even if it only resolvable with different type of ingress controller? Or Gateway API?
this is simply not possible, the way HTTP(s) does this utilizes L7 support based on HOST header and/or SNI. TCP is not capable of understanding what name you are using, cause the resolution happens on the client end, and TCP connection is established using resulting IP with no trace of what domain name was used to resolve to that IP.
If you absolutely have to, one way to get around this could be to use a DB proxy service to create something a bit like a DB "ingress controller" which could route based on the username. Ie. user1@server1
proxies to server1 while user1@server2
proxies to server2. You can see this utilizes a L7 characteristic of usernames being provided with a routing indicator. If that is even available for your specific DB is a diffeent question.