问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/56541015/how-to-obtain-ip-address-of-a-kubernetes-pod-by-querying-dns-srv-records