I have a statefulset with 3 members. They are accessible from inside the cluster with something like:
podname-{0..n}.service.default.svc.cluster.local
I'm using the Kubernetes API from a Controller. I just created the Statefulset with:
import (
"k8s.io/client-go/kubernetes"
appsv1 "k8s.io/api/apps/v1"
)
...
s := appsv1.StatefulSet{ /* some data */ }
kubernetes.AppsV1().StatefulSets(nameSpace).Create(s)
Let's assume everything worked correctly, and after a few minutes I have 3 running Pods. How can I get the Pod DNS entries for the newly created Pods?
I know I can build the DNS with:
fmt.Sprintf("%s-%d.%s.%s.svc.cluster.local", s.Name, idx, service, S.Namespace)
But I'm finding some issues:
StatefulSet
cluster.local
which is not necessarily trueWhat I think it should exists (but I'm not sure if it really exists), is an API, that given a StatefulSet will allow me to know the DNS names of the Replicas that were created. Does an API like this exists?
When you create the headless Service
with the StatefulSet
, it should create DNS SRV entries. You can query that to get a list of all host names of the pods corresponding to the headless Service
without knowing the number. For example, if using Python you can do:
>>> import dns
>>> for item in dns.resolver.query('your-app-name-headless', 'SRV'): item
...
<DNS IN SRV rdata: 10 25 0 2555bb89.your-app-name-headless.your-project.svc.cluster.local.>
<DNS IN SRV rdata: 10 25 0 830bdb18.your-app-name-headless.your-project.svc.cluster.local.>
<DNS IN SRV rdata: 10 25 0 aeb532de.your-app-name-headless.your-project.svc.cluster.local.>
<DNS IN SRV rdata: 10 25 0 a432c21f.your-app-name-headless.your-project.svc.cluster.local.>
See:
Event sniffing what you need is pretty much exactly how KubeDNS works.
So code here of old and simple way. take a look podWatchFunc
method. So here short example of code
func podWatchFunc(c *kubernetes.Clientset, ns string, s labels.Selector) func(options meta.ListOptions) (watch.Interface, error) {
return func(options meta.ListOptions) (watch.Interface, error) {
if s != nil {
options.LabelSelector = s.String()
}
w, err := c.CoreV1().Pods(ns).Watch(options)
if err != nil {
return nil, err
}
return w, nil
}
}
Another good and recommended way in official doc
import (
"fmt"
"k8s.io/client-go/1.4/kubernetes"
"k8s.io/client-go/1.4/pkg/api/v1"
"k8s.io/client-go/1.4/tools/clientcmd"
)
...
// uses the current context in kubeconfig
config, _ := clientcmd.BuildConfigFromFlags("", "path to kubeconfig")
// creates the clientset
clientset, _:= kubernetes.NewForConfig(config)
// access the API to list pods
pods, _:= clientset.CoreV1().Pods("").List(v1.ListOptions{})
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
...
You also may understand that dns is separate k8s service, not part of cluster services. So find ip/host and call your dns endpoint For details if you use default naming policy and coredsn or dns-masq service. You also can have domain name from pod metadata name or selflink
metadata:
creationTimestamp: 2018-04-01T13:45:01Z
generateName: client-deployment-f8454db47-
labels:
app: client
pod-template-hash: "940108603"
name: client-deployment-f8454db47-5gk64
namespace: novaposhta
ownerReferences:
- apiVersion: extensions/v1beta1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: client-deployment-f8454db47
uid: d833ef0f-35b2-11e8-9278-42010a840112
resourceVersion: "73550"
selfLink: /api/v1/namespaces/novaposhta/pods/client-deployment-f8454db47-5gk64