Получить Pod DNS-имя программно
У меня есть Statefulset с 3 членами. Они доступны изнутри кластера с чем-то вроде:
podname-{0..n}.service.default.svc.cluster.local
Я использую API Kubernetes из контроллера. Я только что создал Statefulset с:
import (
"k8s.io/client-go/kubernetes"
appsv1 "k8s.io/api/apps/v1"
)
...
s := appsv1.StatefulSet{ /* some data */ }
kubernetes.AppsV1().StatefulSets(nameSpace).Create(s)
Давайте предположим, что все работает правильно, и через несколько минут у меня есть 3 запущенных модуля. Как я могу получить записи DNS для вновь созданных модулей?
Я знаю, что могу построить DNS с:
fmt.Sprintf("%s-%d.%s.%s.svc.cluster.local", s.Name, idx, service, S.Namespace)
Но я нахожу некоторые проблемы:
- Мне придется рассчитать индекс в зависимости от количества реплик
- Мне нужно знать об имени службы, используемой для этого
StatefulSet
- Я предполагаю, что домен кластера
cluster.local
что не обязательно верно
Я думаю, что он должен существовать (но я не уверен, что он действительно существует), это API, который с учетом StatefulSet позволит мне узнать DNS-имена созданных реплик. Существует ли такой API?
2 ответа
Когда вы создаете безголовый Service
с StatefulSet
, он должен создавать записи DNS SRV. Вы можете запросить это, чтобы получить список всех имен хостов модулей, соответствующих безголовым Service
не зная числа. Например, если вы используете Python, вы можете сделать:
>>> 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.>
Увидеть:
Отслеживание событий, что вам нужно, в значительной степени точно так же, как работает KubeDNS.
Так что используйте здесь старый и простой способ. взглянуть podWatchFunc
метод. Итак, вот краткий пример кода
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
}
}
Еще один хороший и рекомендуемый способ в официальном документе
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))
...
Вы также можете понять, что dns - это отдельная служба k8s, а не часть служб кластера. Так что найдите ip/host и позвоните в конечную точку dns. Подробно, если вы используете политику именования по умолчанию и службу coredsn или dns-masq. Вы также можете иметь доменное имя из имени метаданных pod или 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