<p>I'm looking for a generic way to expose multiple GKE TCP services to the outside world. I want SSL that's terminated at cluster edge. I would also prefer client certificate based auth, if possible.</p>
<p>My current use case is to access PostgreSQL services deployed in GKE from private data centers (and only from there). But basically I'm interested in a solution that works for any TCP based service without builtin SSL and auth.</p>
<p>One option would be to deploy an nginx as a reverse proxy for the TCP service, expose the nginx with a service of type LoadBalancer (L4, network load balancer), and configure the nginx with SSL and client certificate validation.</p>
<p>Is there a better, more GKE native way to achieve it ?</p>

<p>To the best of my knowledge, <strong>there is no GKE-native way to achieve exactly what you need</strong>.</p>
<p>If this was only dealing with HTTP-based traffic, you could simply use <a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress" rel="nofollow noreferrer">GKE Ingress for HTTP(S) Load Balancing</a> but taking into consideration:</p>
<blockquote>
<p>But basically I'm interested in a solution that works for any TCP
based service without builtin SSL and auth.</p>
</blockquote>
<p>this is not your use case.</p>
<p>So you can either <strong>stay with what you've already set up</strong> as it seems to work well or as an alternative you can use:</p>
<ol>
<li><p>✅ <a href="https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/" rel="nofollow noreferrer">nginx ingress</a>, which unlike <a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress" rel="nofollow noreferrer">GKE ingress</a> is able to expose to the external world <strong>not only HTTP/HTTPS-based traffic</strong>, but also <strong>can proxy TCP connections</strong> coming to arbitrary ports.</p>
</li>
<li><p>✅ You can use <strong>TLS termination proxy</strong> as a <strong>sidecar</strong> (something like <a href="https://hub.docker.com/r/mnuessler/tls-termination-proxy" rel="nofollow noreferrer">this one</a> or <a href="https://github.com/flaccid/docker-tls-proxy" rel="nofollow noreferrer">this one</a>) behind <a href="https://cloud.google.com/load-balancing/docs/network" rel="nofollow noreferrer">External TCP/UDP Network Load Balancer</a>. As it is <strong>not a proxy</strong> but a <strong>pass-through LB</strong>, it cannot provide SSL termination and will only be able to pass the encrypted TCP traffic to the backend <code>Pod</code> where it needs be handled by the above mentioned <strong>sidecar</strong>.</p>
</li>
<li><p>❌ From the GCP-native load balancing solutions presented in <a href="https://cloud.google.com/load-balancing/docs/choosing-load-balancer#summary-of-google-cloud-load-balancers" rel="nofollow noreferrer">this table</a> only <a href="https://cloud.google.com/load-balancing/docs/ssl#firewall_rules" rel="nofollow noreferrer">SSL Proxy</a> may seem useful at first glance as <strong>it can handle TCP traffic with SSL offload</strong>, however ❗<strong>it supports only limited set of well-known TCP ports</strong> and as far as I understand, you need to be able to <strong>expose arbitrary TCP ports</strong> so this won't help you much:</p>
</li>
</ol>
<blockquote>
<p><strong>SSL Proxy Load Balancing support for the following ports:</strong> 25, 43, 110, 143, 195, 443, 465, 587, 700, 993, 995, 1883, 3389, 5222, 5432,
5671, 5672, 5900, 5901, 6379, 8085, 8099, 9092, 9200, and 9300. When
you use Google- managed SSL certificates with SSL Proxy Load
Balancing, the frontend port for traffic must be 443 to enable the
Google-managed SSL certificates to be provisioned and renewed.</p>
</blockquote>
