How to obtain Ip address of a kubernetes pod by querying DNS srv records?

6/11/2019

I am trying to create a kubernetes job inside which I will run "dig srv" queries to find out the IP address of all the pods for any specific service running on the same cluster.

Is this achievable ?

I would like to elaborate a little more on the problem statement. There are a few services already running on the cluster. The requirement is to have a tool that can accept a service name and list down the IP addresses of all the pods belonging to that service.

I was able to do this by using kubectl commands along with selector and jq tooling. But for some reasons, I am not allowed to run kubectl commands on this environment.

I want to use dig srv queries to resolve pod IPs for provided service name.

-- nakul shukla
kube-dns
kubernetes
kubernetes-jobs
kubernetes-pod
srv-record

2 Answers

6/11/2019

This is explained inside DNS for Services and Pods.

Every Service defined in the cluster (including the DNS server itself) is assigned a DNS name. By default, a client Pod’s DNS search list will include the Pod’s own namespace and the cluster’s default domain. This is best illustrated by example:

Assume a Service named foo in the Kubernetes namespace bar. A Pod running in namespace bar can look up this service by simply doing a DNS query for foo. A Pod running in namespace quux can look up this service by doing a DNS query for foo.bar.

Here is a detailed docs for Kubernetes DNS-Based Service Discovery.

As for querying the POD ip address it depends if spec.hostname is specified.

If there exists a headless service in the same namespace as the pod and with the same name as the subdomain, the cluster’s KubeDNS Server also returns an A record for the Pod’s fully qualified hostname. For example, given a Pod with the hostname set to “busybox-1” and the subdomain set to “default-subdomain”, and a headless Service named “default-subdomain” in the same namespace, the pod will see its own FQDN as “busybox-1.default-subdomain.my-namespace.svc.cluster.local”. DNS serves an A record at that name, pointing to the Pod’s IP. Both pods “busybox1” and “busybox2” can have their distinct A records.

The Endpoints object can specify the hostname for any endpoint addresses, along with its IP.

Note: Because A records are not created for Pod names, hostname is required for the Pod’s A record to be created. A Pod with no hostname but with subdomain will only create the A record for the headless service (default-subdomain.my-namespace.svc.cluster.local), pointing to the Pod’s IP address. Also, Pod needs to become ready in order to have a record unless publishNotReadyAddresses=True is set on the Service.

Hope this explains enough.

-- Crou
Source: StackOverflow

6/11/2019

You can use a headless service (therefore no ClusterIP and no internal loadbalancing). If you provide a selector, you can query for A records of the service.

See: https://kubernetes.io/docs/concepts/services-networking/service/#headless-services

Consider the following example:

Deployment of some pods:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
        - containerPort: 80

For this deployment the following headless service is added:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

This can now be queried using DNS (inside the cluster)

$ kubectl run shell  -i --rm --tty --restart=Never --image=busybox
# nslookup -type=A nginx
Server:     10.96.0.10
Address:    10.96.0.10:53

Name:   nginx.default.svc.cluster.local
Address: 10.34.0.2
Name:   nginx.default.svc.cluster.local
Address: 10.42.0.2
Name:   nginx.default.svc.cluster.local
Address: 10.46.0.1

All internal Pod IPs are returned as DNS A records.

-- Thomas
Source: StackOverflow