<p>I am new to microservices and want to understand what is the best way I can implement below behaviour in microservices deployed on Kubernetes :</p>

<p>There are 2 different K8s clusters. Microservice B is deployed on both the clusters.</p>

<p>Now if a Microservice A calls Microservice B and B’s pods are not available in cluster 1, then the call should go to B of cluster 2.</p>

<p>I could have imagined to implement this functionality by using Netflix OSS but here I am not using it.</p>

<p>Also, keeping aside the inter-cluster communication aside for a second, how should I communicate between microservices ?</p>

<p>One way that I know is to create Kubernetes Service of type NodePort for each microservice and use the IP and the nodePort in the calling microservice.</p>

<p>Question : What if someone deletes the target microservice's K8s Service? A new nodePort will be randomly assigned by K8s while recreating the K8s service and then again I will have to go back to my calling microservice and change the nodePort of the target microservice. How can I decouple from the nodePort?</p>

<p>I researched about kubedns but seems like it only works within a cluster.</p>

<p>I have very limited knowledge about Istio and Kubernetes Ingress. Does any one of these provide something what I am looking for ?</p>

<p>Sorry for a long question. Any sort of guidance will be very helpful.</p>

<p>You can expose you application using services, there are some kind of services you can use:</p>
<blockquote>
<ul>
<li><p><code>ClusterIP</code>: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default  <code>ServiceType</code>.</p>
</li>
<li><p><a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" rel="nofollow noreferrer"><code>NodePort</code></a>: Exposes the Service on each Node’s IP at a static port (the  <code>NodePort</code>). A  <code>ClusterIP</code>  Service, to which the  <code>NodePort</code>  Service routes, is automatically created. You’ll be able to contact the  <code>NodePort</code>  Service, from outside the cluster, by requesting  <code>&lt;NodeIP&gt;:&lt;NodePort&gt;</code>.</p>
</li>
<li><p><a href="https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer" rel="nofollow noreferrer"><code>LoadBalancer</code></a>: Exposes the Service externally using a cloud provider’s load balancer.  <code>NodePort</code>  and  <code>ClusterIP</code>  Services, to which the external load balancer routes, are automatically created.</p>
</li>
<li><p><a href="https://kubernetes.io/docs/concepts/services-networking/service/#externalname" rel="nofollow noreferrer"><code>ExternalName</code></a>: Maps the Service to the contents of the  <code>externalName</code>  field (e.g.  <code>foo.bar.example.com</code>), by returning a  <code>CNAME</code>  record</p>
</li>
</ul>
</blockquote>
<p>For <strong>internal communication</strong> you  an use service type <code>ClusterIP</code>, and you could configure the service dns for your applications instead an IP.
I.e.: a service called <code>my-app-1</code> could be reach internnaly using the dns <code>http://my-app-1</code> or with fqdn <code>http://my-app-1.&lt;namespace&gt;.svc.cluster.local</code>.</p>
<p>For <strong>external communication</strong>, you can use <code>NodePort</code> or <code>LoadBalancer</code>.</p>
<p><code>NodePort</code> is good when you have few nodes and know the ip of all of them. And yes, by the <a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" rel="nofollow noreferrer">service docs</a> you can specify a specific port number:</p>
<blockquote>
<p>If you want a specific port number, you can specify a value in the <code>nodePort</code> field. The control plane will either allocate you that port or report that the API transaction failed. This means that you need to take care of possible port collisions yourself. You also have to use a valid port number, one that’s inside the range configured for NodePort use.</p>
</blockquote>
<p><code>LoadBalancer</code> give you more flexibility, because you don't need to know all node ips, you just must to know the service IP and port. But <code>LoadBalancer</code> is only supported in cloudproviders, if you wan to implement in bare-metal cluster, I recomend you take a look in <a href="https://metallb.universe.tf/" rel="nofollow noreferrer">MetalLB</a>.</p>
<p>Finally, there is another option that is use <code>ingress</code>, in my point of view is the best way to expose HTTP applications externally, because you can create rules by path and host, and it gives you much more flexibility than services. But <strong>only</strong> HTTP/HTTPS is supported, if you need TCP then go to Services.</p>
<p>I'd recommend you take a look in these links to understand in deep how services and ingress works:</p>
<p><a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">Kubernetes Services</a></p>
<p><a href="https://kubernetes.io/docs/concepts/services-networking/ingress/" rel="nofollow noreferrer">Kubernetes Ingress</a></p>
<p><a href="https://kubernetes.github.io/ingress-nginx/" rel="nofollow noreferrer">NGINX Ingress</a></p>
