<p>I have been trying to find a way to define a service in one namespace that links to a Pod running in another namespace.  I know that containers in a Pod running in <code>namespaceA</code> can access <code>serviceX</code> defined in <code>namespaceB</code> by referencing it in the cluster DNS as <code>serviceX.namespaceB.svc.cluster.local</code>, but I would rather not have the code inside the container need to know about the location of <code>serviceX</code>.  That is, I want the code to just lookup <code>serviceX</code> and then be able to access it.</p>

<p>The <a href="http://kubernetes.io/docs/user-guide/services/" rel="noreferrer">Kubernetes documentation</a> suggests that this is possible.  It says that one of the reasons that you would define a service without a selector is that <strong>You want to point your service to a service in another Namespace or on another cluster</strong>.</p>

<p>That suggests to me that I should:</p>

<ol>
<li>Define a <code>serviceX</code> service in <code>namespaceA</code>, without a selector (since the POD I want to select isn't in <code>namespaceA</code>).</li>
<li>Define a service (which I also called <code>serviceX</code>) in <code>namespaceB</code>, and then</li>
<li>Define an Endpoints object in <code>namespaceA</code> to point to <code>serviceX</code> in <code>namespaceB</code>.</li>
</ol>

<p>It is this third step that I have not been able to accomplish.</p>

<p>First, I tried defining the Endpoints object this way:</p>

<pre class="lang-yaml prettyprint-override"><code>kind: Endpoints
apiVersion: v1
metadata:
  name: serviceX
  namespace: namespaceA
subsets:
  - addresses:
      - targetRef:
          kind: Service
          namespace: namespaceB
          name: serviceX
          apiVersion: v1
    ports:
      - name: http
        port: 3000
</code></pre>

<p>That seemed the logical approach, and <em>obviously</em> what the <code>targetRef</code> was for.   But, this led to an error saying that the <code>ip</code> field in the <code>addresses</code> array was mandatory.  So, my next try was to assign a fixed ClusterIP address to <code>serviceX</code> in <code>namespaceB</code>, and put that in the IP field (note that the <code>service_cluster_ip_range</code> is configured as <code>192.168.0.0/16</code>, and <code>192.168.1.1</code> was assigned as the ClusterIP for <code>serviceX</code> in <code>namespaceB</code>; <code>serviceX</code> in <code>namespaceA</code> was auto assigned a different ClusterIP on the <code>192.168.0.0/16</code> subnet):</p>

<pre class="lang-yaml prettyprint-override"><code>kind: Endpoints
apiVersion: v1
metadata:
  name: serviceX
  namespace: namespaceA
subsets:
  - addresses:
        - ip: 192.168.1.1
          targetRef:
            kind: Service
            namespace: namespaceB
            name: serviceX
            apiVersion: v1
    ports:
      - name: http
        port: 3000
</code></pre>

<p>That was accepted, but accesses to <code>serviceX</code> in <code>namespaceA</code> did not get forwarded to the Pod in <code>namespaceB</code> - they timed out.  Looking at the iptables setup, it looks like it would have had to do NAT pre-routing twice to accomplish that.</p>

<p>The only thing I did find that worked - but is not a satisfactory solution - is to lookup the actual IP address of the Pod providing <code>serviceX</code> in <code>namespaceB</code> and put that address in the Endpoints object in <code>namespaceA</code>.  That isn't satisfactory, of course, because the Pod IP address may change over time.  That's the problem service IPs are there to solve.</p>

<p>So, is there a way to meet what seems to be the promise of the documentation that I can point a service in one namespace to a <em>service</em> running in a different namespace?</p>

<p>A commenter questioned why you would want to do this - here is a use case that makes sense to me, at least:</p>

<p>Say you have a multi-tenant system, which also includes a common data-access function that can be shared between tenants.  Now imagine that there are different flavors of this data-access function with common APIs, but different performance characteristics.  Some tenants get access to one of them, other tenants have access to another one.</p>

<p>Each tenant's pods run in their own namespaces, but each one needs to access one of these common data-access services, which will necessarily be in another namespace (since it is accessed by multiple tenants).  But, you wouldn't want the tenant to have to change their code if their subscription changes to access the higher-performing service.</p>

<p>A potential solution (the cleanest one I can think of, if only it worked) is to include a service definition in each tenant's namespace for the data-access service, with each one configured for the appropriate endpoint.  This service definition would be configured to point to the proper data-access service each tenant is entitled to use.</p>

David McKinley
<p>I stumbled over the same issue and found a nice solution which does not need any static ip configuration:</p>
<p>You can access a service via it's <a href="https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/" rel="noreferrer">DNS name</a> (as mentioned by you): <em>servicename.namespace.svc.cluster.local</em></p>
<p>You can use that DNS name to reference it in <a href="https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors" rel="noreferrer">another namespace via a local service</a>:</p>
<pre class="lang-yaml prettyprint-override"><code>kind: Service
apiVersion: v1
metadata:
  name: service-y
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: service-y.namespace-b.svc.cluster.local
  ports:
  - port: 80
</code></pre>
