<p>I have k8s cluster with Istio ingress controller installed. And load balancer has its external IP assigned by cloud provider.</p>
<p>Inside cluster, I made 2 deployments that runs database and web server, respectively. (Note that database is not important. it can be any TCP-based service.)</p>
<p>For web server, there are bunch of examples routing HTTP and HTTPS for Istio VirtualService and Gateway, So I could made it work easily.</p>
<p>And this is what I'd like to ask.</p>
<p><strong>Can I route TCP similar to HTTP one does, based on domain? As far as I know, this cannot be done simply because TCP is not working like that.</strong></p>
<p>I'm asking this because I have advise that this is possible using Istio.
True or not, following to advice, the figure below is what I want to see, if it really works.</p>
<pre><code>+-------------+                                                 +---------+  +------------+
| A.my.domain |--+                                           +--| Service |--| MariaDB #1 |
+-------------+  |  +----+  +---------+  +----------------+  |  +---------+  +------------+
                 +--| LB |--| Gateway |--| VirtualService |--+
+-------------+  |  +----+  +---------+  +----------------+  |  +---------+  +------------+
| B.my.domain |--+                                           +--| Service |--| MariaDB #2 |
+-------------+                                                 +---------+  +------------+
</code></pre>
<p>Let say there are multiple TCP-based services receive traffics through single load balancer on same port. Since I've mentioned service as DB, assume that load balancer have listener for 3306 port.</p>
<p>Also, I have <code>my.domain</code> with NS records given by cloud provider configured. So I can map whatever into like <code>A.my.domain</code>, <code>B.my.domain</code>. Both domains are mapped with same load balancer IP for A record. (Or, random-generated super long domain for CNAME record.)</p>
<p>If user connect with <code>A.my.domain:3306</code>, then it must reach to <code>MariaDB #1</code> and for <code>B.my.domain:3306</code> must reach to <code>MariaDB #2</code>.</p>
<p>As mentioned, my opinion is this is impossible but I'm being said that I can use host field, which makes me doubt.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: product-gw
  namespace: product-ns
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 3306
      name: tcp-mariadb
      protocol: TCP
    hosts:
    - &quot;*&quot;              # Does it mean that I can use this for my purpose?
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: product-vs
  namespace: product
spec:
  hosts:
  - &quot;*&quot;                # And this one?
  gateways:
  - product-gw
  tcp:
  - match:
    - port: 3306
    route:
    - destination:
        host: product-db-1.product.svc.cluster.local
        port:
          number: 3306
...
</code></pre>
<p>I've done some searching and trial-and-error. Or, as other option, I thought 'do I have to make multiple load balancers with new IP whenever new services are deployed by namespace?', though I'm not sure this is common approach for cloud service.</p>
<p>Any advice would be appreciated.</p>

Nukaccino
<p>The domain is not a property of TCP but is only used to lookup the IP address. In the TCP traffic only the IP address can be seen but not the domain name - unless it is specifically included as part of an application protocol like in HTTP.</p>
<p>Therefore it is impossible to balance arbitrary TCP traffic on the same IP addressed based on the domain the client might have intended to access the IP address - the information necessary to do this does not exist.</p>
