<p>I have created a deployment and a service on Google Kubernetes Engine. These are running on Cloud Compute instances.</p>

<p>I need to make my k8s application reachable from other Compute instances, but not from the outside world. That is because there are some legacy instances running outside the cluster and those cannot be migrated (yet, at least).</p>

<p>My understanding is that a <code>Service</code> makes the pod reachable from other cluster nodes, whereas an <code>Ingress</code> exposes the pod to the external traffic with an external IP.</p>

<p>What I need is something in the middle: I need to expose my pod outside the cluster, but only to other local Compute instances (in the same zone). I don't understand how I am supposed to do it.</p>

<p>In Google Kubernetes Engine this is accomplished with a <code>LoadBalancer</code> type Service that is annotated to be an internal load balancer. The documentation for it is at <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing" rel="noreferrer">https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing</a>.</p>

<p>Assuming you had a Deployment with label <code>app: echo-pod</code> that listened on port 080 and you wanted to expose it as port 80 to GCE instance the service would look something like:</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: echo-internal
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
  labels:
    app: echo-pod
spec:
  type: LoadBalancer
  selector:
    app: echo-pod
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
</code></pre>

<p>It will take a moment to create the Service and internal load balancer. It will have an external IP once created:</p>

<pre><code>$ kubectl get services
NAME              TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
echo-internal     LoadBalancer   10.4.11.165   10.128.0.35   80:31706/TCP   2m33s
kubernetes        ClusterIP      10.4.0.1      &lt;none&gt;        443/TCP        20m
</code></pre>

<p>The <code>10.128.0.35</code> IP is actually an <em>internal</em> IP address only accessible inside your VPC. From another GCE instance you can access it on the exposed port:</p>

<pre><code>$ curl http://10.128.0.35


Hostname: echo-deployment-5f55bb9855-hxl7b
</code></pre>

<p>Note: You need to have the "Load balancing" add-on enabled when you provisioned your cluster. But it is enabled by default and should be working unless you explicitly disabled the "Enable HTTP load balancing" option at cluster creation.</p>
