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.
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 namespacebar
. A Pod running in namespacebar
can look up this service by simply doing a DNS query forfoo
. A Pod running in namespacequux
can look up this service by doing a DNS query forfoo.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 nohostname
but withsubdomain
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 unlesspublishNotReadyAddresses=True
is set on the Service.
Hope this explains enough.
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.