<p>I have a Kubernetes service on GKE as follows:</p>

<pre><code>$ kubectl describe service staging
Name:           staging
Namespace:      default
Labels:         &lt;none&gt;
Selector:       app=jupiter
Type:           NodePort
IP:             10.11.246.27
Port:           &lt;unnamed&gt;   80/TCP
NodePort:       &lt;unnamed&gt;   31683/TCP
Endpoints:      10.8.0.33:1337
Session Affinity:   None
No events.
</code></pre>

<p>I can access the service from a VM directly via one of its endpoints (<code>10.8.0.21:1337</code>) or via the node port (<code>10.240.251.174:31683</code> in my case). However, if I try to access <code>10.11.246.27:80</code>, I get nothing. I've also tried ports 1337 and 31683.</p>

<p>Why can't I access the service via its IP? Do I need a firewall rule or something?</p>

<p>Service IPs are virtual IPs managed by kube-proxy. So, in order for that IP to be meaningful, the client must also be a part of the kube-proxy "overlay" network (have kube-proxy running, pointing at the same apiserver).</p>

<p>Pod IPs on GCE/GKE are managed by GCE <a href="https://cloud.google.com/compute/docs/networking?hl=en#routes" rel="nofollow noreferrer">Routes</a>, which is more like an "underlay" of all VMs in the network.</p>

<p>There are a couple of ways to access non-public services from outside the cluster. <a href="https://stackoverflow.com/questions/31664060/how-to-call-a-service-exposed-by-a-kubernetes-cluster-from-another-kubernetes-cl/31665248#31665248">Here</a> they are in more detail, but in short:</p>

<ol>
<li>Create a bastion GCE route for your cluster's services.</li>
<li>Install your cluster's kube-proxy anywhere you want to access the cluster's services.</li>
</ol>
