6

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

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.

Error resolving host "internaldnsname.com": lookup internaldnsname.com on 10.96.0.10:53: no such host

What am i missing?

Ingress rule

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: /

Service definition

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: internaldnsname.com
Manikandan Kannan
  • 8,684
  • 15
  • 44
  • 65
  • can you give some more details about your external service? like what is it? is it a rest call to somewhere in the internet? or you mean external just to your k8s cluster? but in the same machine hosted as none k8s service? – garlicFrancium May 12 '20 at 12:50
  • Its a website within the same network but outside of K8S. I can access that website directly (not via ingress) – Manikandan Kannan May 12 '20 at 12:58
  • if it is within the same network then you must have a static ip? which can be your loadbalancer ip maybe. what i mean there should be a direct route possible via internal or external ip since it is in the same network? – garlicFrancium May 12 '20 at 13:01
  • all i can say is that the direct route is not possible and looking at options to see if it can go via K8S ingress – Manikandan Kannan May 13 '20 at 08:41

2 Answers2

9

Explanation of what's going on:

Ref

kube-proxy is responsible for implementing a form of virtual IP for Services of type other than ExternalName

The ingress controller is trying to resolve the external-service which has CNAME internaldns.com and when your kube-dns/coredns (10.96.0.10) tries to do a lookup, it can only find CNAME record but no A record, therefore, your ingress is failing to resolve the DNS name.

Ref

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

Moreover there is a clear warning on the website about ExternalNames:

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.

TL;DR: ingress is trying to resolve a DNS using kubernetes DNS(kube-dns/coredns) which doesn't have any A record, hence fails to associate DNS to IP!

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

Solution: - Create a Headless service without selector and then manually create an endpoint using the same name as of the service. Follow the example here

Note:

  1. in the above solutions you will need the static IP of the external service.
  2. 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!
garlicFrancium
  • 2,013
  • 14
  • 23
1

At least for ingress-nginx the ExternalName can work. See this answer for a similar question.

Wikiwix
  • 301
  • 2
  • 5