<p>Conditions:
I have a <em>3 tier application</em> to deploy using Kubernetes. I have created <strong>two namespaces</strong> for <em>backend</em> and <em>frontend</em> respectively.</p>
<p>Problem:
I want to know how would my <strong>backend</strong> talk to the <strong>frontend</strong> or vice versa.</p>
<p>In simple words, how do backend and frontend communicate if they are in different namespaces?</p>

<p>You should create <a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">services</a> for frontend and backend, and then you can communicate using:</p>
<ul>
<li>(Recommended) a <strong>DNS names of the services</strong> <code>&lt;service-name&gt;.&lt;namespace-name&gt;.svc.cluster.local</code> which will be always the same</li>
<li>(Not recommended) a IP address of the services (but they will be different with each re-creation of the service)</li>
</ul>
<p>Example and further explanation below.</p>
<p>Let's create deployments with 3 replicas - one in <code>default</code> namespace, one in <code>test</code> namespace:</p>
<pre><code>kubectl create deployment nginx --image=nginx --replicas=3
kubectl create deployment nginx --image=nginx --replicas=3 -n test
</code></pre>
<p>For each deployment we will <a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#expose" rel="nofollow noreferrer">create service type ClusterIP using <code>kubectl expose</code></a>(It's the same if I had created a service from a yaml file:):</p>
<pre><code>kubectl expose deployment nginx --name=my-service --port=80
kubectl expose deployment nginx --name=my-service-test --port=80 -n test
</code></pre>
<p>Time to get IP addresses of the services:</p>
<pre><code>user@shell:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       &lt;none&gt;        443/TCP   64d
my-service   ClusterIP   10.107.224.54   &lt;none&gt;        80/TCP    12m
</code></pre>
<p>And in <code>test</code> namespace:</p>
<pre><code>user@shell:~$ kubectl get svc -n test
NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
my-service-test   ClusterIP   10.110.51.62   &lt;none&gt;        80/TCP    8s
</code></pre>
<p>I will exec into pod in default namespace and <code>curl</code> IP address of the <code>my-service-test</code> in second namespace:</p>
<pre><code>user@shell:~$ kubectl exec -it nginx-6799fc88d8-w5q8s -- sh
# curl 10.110.51.62
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
&lt;style&gt;
</code></pre>
<p>Okay, it's working... Let's try with hostname:</p>
<pre><code># curl my-service-test
curl: (6) Could not resolve host: my-service-test
</code></pre>
<p>Not working as expected. Let's check <code>/etc/resolv.conf</code> file:</p>
<pre><code># cat resolv.conf
nameserver 10.96.0.10
search test.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
</code></pre>
<p>It's looking for <a href="https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/#does-the-service-work-by-dns-name" rel="nofollow noreferrer">hostnames only in namespace where pod is located</a>.</p>
<p>So pod in the <code>test</code> namespace will have something like:</p>
<pre><code># cat resolv.conf
nameserver 10.96.0.10
search test.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
</code></pre>
<p>Let's try to curl <code>my-service-test.test.svc.cluster.local</code> from pod in default namespace:</p>
<pre><code># curl my-service-test.test.svc.cluster.local
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
</code></pre>
<p>It's working.</p>
<p>If you have problems, make sure you have a proper <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/" rel="nofollow noreferrer">CNI plugin</a> installed for your cluster - also check this article - <a href="https://kubernetes.io/docs/concepts/cluster-administration/networking/" rel="nofollow noreferrer">Cluster Networking</a> for more details. If you are using some cloud provided solution (like AWS EKS or GCP GKE) you should have it by default.</p>
<p>Also check these:</p>
<ul>
<li><a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-services/" rel="nofollow noreferrer">Access Services Running on Clusters | Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">Service | Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/" rel="nofollow noreferrer">Debug Services | Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/" rel="nofollow noreferrer">DNS for Services and Pods | Kubernetes</a></li>
</ul>
