<p>Application <strong>A</strong> and application <strong>B</strong> are two applications running in the same kubernetes cluster. Application A can access B by reading the <code>B_HOST</code> env ( with value <code>b.example.com</code>) passed to A's container. Is there any way by which an <strong>A would be able access B</strong>:</p>
<ul>
<li>internally: using the DNS name of B's service (<code>b.default.svc.cluster.local</code>)</li>
<li>externally: using the FQDN of B, that is also defined in the ingress resource (<code>b.example.com</code>)</li>
</ul>
<p>at the same time?</p>
<p>For example,</p>
<p>If you try to <code>curl b.example.com</code> inside the pod/container of A, it should resolve to <code>b.default.svc.cluster.local</code> and get the result via that service.</p>
<p>If you try to <code>curl b.example.com</code> outside the k8s cluster, it should use ingress to reach the service B and get the results.</p>
<p>As a concept, adding an extra host entry (that maps B's FQDN to its service IP) to the container A's <code>/etc/hosts</code> should work. But that doesn't seem to be a good practice as it needs to get the IP address of B's service in advance and then create A's pod with that <a href="https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/" rel="nofollow noreferrer"><code>HostAliases</code></a> config. Patching this field into an existing pod is not allowed. The service IP changes when you recreate the service, and adding the dns name of the service instead of its IP in <code>HostAliases</code> is also not supported.</p>
<p>So, what would be a good method to achieve this?</p>
<p>Found a similar discussion in this <a href="https://github.com/kubernetes/kubernetes/issues/39792" rel="nofollow noreferrer">thread</a>.</p>
<p><strong>Additional Info:</strong></p>
<p>I'm using Azure Kubernetes service (AKS) and using application gateway as ingress controller (AGIC).</p>

AnjK
<p>You can try different methods, then see which one works for you.</p>
<p><strong>Method 1 :</strong></p>
<p>Modifying the coreDNS configuration of your k8s cluster.</p>
<p>Reference: <a href="https://coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/" rel="nofollow noreferrer">https://coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/</a></p>
<p>In AKS, it can be done as described here:
<a href="https://learn.microsoft.com/en-us/azure/aks/coredns-custom#rewrite-dns" rel="nofollow noreferrer">https://learn.microsoft.com/en-us/azure/aks/coredns-custom#rewrite-dns</a></p>
<p><strong>Method 2 :</strong></p>
<p>Specifying an <a href="https://kubernetes.io/docs/concepts/services-networking/service/#external-ips" rel="nofollow noreferrer"><code>externalIP</code></a> manually for the service <code>B</code> and then adding the same IP in <code>/etc/hosts</code> file of pod <code>A</code> using <a href="https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/" rel="nofollow noreferrer">hostAliases</a> seems working.</p>
<p>Part of pod definition of app A:</p>
<pre><code>apiVersion: v1
kind: Pod
metadata:
  name: a
  labels:
    app: a
spec:
  hostAliases:
  - ip: &quot;10.0.3.165&quot;
    hostnames:
    - &quot;b.example.com&quot;
</code></pre>
<p>Part of service definition of app B:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: b
spec:
  selector:
    app: b
  externalIPs:
    - 10.0.3.165  
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
</code></pre>
<p>But not sure if that is a good practice; there could be pitfalls.
One being that the <code>externalIP</code> we are defining could be any random valid IP address - be it private or public, without a conflict to other IPs of cluster resources.Unpredictable behaviour can result if overlapping IP ranges are used.</p>
<p><strong>Method 3 :</strong></p>
<p>The clusterIP of the service will be available inside pod <code>A</code> as an <a href="https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables" rel="nofollow noreferrer">environment variable</a> <code>B_SERVICE_HOST</code> by default.</p>
<p>So, instead of adding an <code>externalIP</code> you can try to get the actual service IP (clusterIP) of <code>B</code> from env <code>B_SERVICE_HOST</code> and add to <code>/etc/hosts</code> of the pod <code>A</code> - either using <code>hostAliases</code> or directly, whichever works.</p>
<pre><code>echo $B_SERVICE_HOST 'b.example.com' &gt;&gt; /etc/hosts
</code></pre>
<p>You can do this using a <a href="https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/" rel="nofollow noreferrer">postStart hook</a> for the container in the pod definition:</p>
<pre><code>  containers:     
  - image: &quot;myreg/myimagea:tag&quot;
    name: container-a
    lifecycle:
      postStart:
        exec:
          command: [&quot;/bin/sh&quot;, &quot;-c&quot;, &quot;echo $B_SERVICE_HOST 'b.example.com' &gt;&gt; /etc/hosts&quot;]  
</code></pre>
<p>Since this is a <a href="https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/" rel="nofollow noreferrer">container lifecycle hook</a>, the changes will be specific to that one container. So other containers in the same pod may not have the same changes applied to their hosts file.</p>
<p>Also note that, service of B should be created before the pod A in order to be able to get IP from <code>B_SERVICE_HOST</code> env.</p>
<p><strong>Method 4 :</strong></p>
<p>You can try to create a public DNS zone and a private DNS zone in your cloud tenant. Then add records in it to point to ther service. For example, create a private DNS zone in Azure then do either of the following 2 methods:</p>
<ul>
<li>Add A record mapping <code>b.example.com</code> to svc B's clusterIP</li>
<li>Add CNAME record mapping <code>b.example.com</code> to internal loadbalancer dns label provided by azure for the service. On a wider perspective, if you have multiple applications in the cluster with same reequirement, Create a static IP, create a loadbalancer type service for your ingress controller using this static IP as <code>loadBalancerIP</code> and with an annotation <code>service.beta.kubernetes.io/azure-dns-label-name</code> as described <a href="https://learn.microsoft.com/en-us/azure/aks/static-ip#apply-a-dns-label-to-the-service" rel="nofollow noreferrer">here</a>. You'll get a dns label for that service. Then add a CNAME record in your private zone with mapping <code>*.example.com</code> to this azure-provided dns label. Still I doubt if this would be suitable if your ingress controller is Azure application gateway.</li>
</ul>
<p><strong>NOTE:</strong></p>
<p>Also consider how the method you adopt will affect your debugging process in future if any networking related issue arises.</p>
<p>If you feel that would be problem, consider using two different environment variables <code>B_HOST</code> and <code>B_PUBLIC_HOST</code> separately for external and internal access.</p>
