<p>I have issues trying to redirect the traffic to an external service using the type as ExternalName and with the ingress controller.</p>

<p>I get the following error and i can access this host from the host machine but not from K8S. Alsothe IP 10.96.0.10 is tied to the kube-dns service.</p>

<blockquote>
  <p>Error resolving host "internaldnsname.com": lookup internaldnsname.com
  on 10.96.0.10:53: no such host</p>
</blockquote>

<p>What am i missing?</p>

<p><strong>Ingress rule</strong></p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: external-ingress
  annotations:
    kubernetes.io/ingress.class: “nginx”
    nginx.ingress.kubernetes.io/ingress.class: “nginx”
    nginx.ingress.kubernetes.io/preserve-host: “false”
spec:
  rules:
  - host:
    http:
      paths:
      - backend:
          serviceName: external-service
          servicePort: 80
        path: /
</code></pre>

<p><strong>Service definition</strong></p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: internaldnsname.com
</code></pre>

<p><strong>Explanation of what's going on</strong>:</p>

<p><a href="https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies" rel="noreferrer">Ref</a></p>

<blockquote>
  <p>kube-proxy is responsible for implementing a form of virtual IP for Services of type other than ExternalName</p>
</blockquote>

<p>The ingress controller is trying to resolve the <code>external-service</code> which has <a href="https://support.dnsimple.com/articles/cname-record/" rel="noreferrer">CNAME</a> <code>internaldns.com</code> and when your kube-dns/coredns (10.96.0.10) tries to do a lookup, it can only find CNAME record but no <a href="https://support.dnsimple.com/articles/a-record/" rel="noreferrer">A record</a>, therefore, your ingress is failing to resolve the DNS name.</p>

<p><a href="https://kubernetes.io/docs/concepts/services-networking/service/#externalname" rel="noreferrer">Ref</a></p>

<blockquote>
  <p>When looking up the host my-service.prod.svc.cluster.local, the cluster DNS Service returns a CNAME record with the value my.database.example.com</p>
</blockquote>

<p>Moreover there is a clear warning on the <a href="https://kubernetes.io/docs/concepts/services-networking/service/#externalname" rel="noreferrer">website</a> about ExternalNames:</p>

<blockquote>
  <p>You may have trouble using ExternalName for some common protocols, including HTTP and HTTPS. If you use ExternalName then the hostname used by clients inside your cluster is different from the name that the ExternalName references.</p>
</blockquote>

<p>TL;DR: ingress is trying to resolve a DNS using kubernetes DNS(kube-dns/coredns) which doesn't have any <a href="https://support.dnsimple.com/articles/a-record/" rel="noreferrer">A record</a>, hence fails to associate DNS to IP!</p>

<p>If ingress was made to lookup a different DNS server (other than kubernetes DNS) which has A record entry for <code>internaldns.com</code> then this problem may not have happened but I am not 100% sure if that's possible .</p>

<p><strong>Solution</strong>:
 - Create a <a href="https://kubernetes.io/docs/concepts/services-networking/service/#headless-services" rel="noreferrer">Headless service</a> <strong>without</strong> selector and then manually create an endpoint using the same name as of the service. Follow the example <a href="https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors" rel="noreferrer">here</a></p>

<p>Note: </p>

<ol>
<li>in the above solutions you will need the static IP of the external service.</li>
<li>I would use ExternalNames only when my Pod directly wants to talk to a 3rd party service over the internet, which is to say the service is hosted outside my local network. I would follow such an approach because if I can access something locally via IP why would deter performance by talking to a Nameserver to resolve DNS name!</li>
</ol>
