【问题标题】:Obtain Pod DNS Name Programmatically以编程方式获取 Pod DNS 名称
【发布时间】:2018-09-15 12:47:55
【问题描述】:

我有一个有 3 个成员的 statefulset。可以通过以下方式从集群内部访问它们:

podname-{0..n}.service.default.svc.cluster.local

我正在使用控制器中的 Kubernetes API。我刚刚创建了 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 个正在运行的 Pod。如何获取新创建的 Pod 的 Pod DNS 条目?

我知道我可以使用以下方法构建 DNS:

fmt.Sprintf("%s-%d.%s.%s.svc.cluster.local", s.Name, idx, service, S.Namespace)

但我发现了一些问题:

  1. 我必须根据副本的数量计算索引
  2. 我需要知道用于此StatefulSet 的服务名称
  3. 我假设集群域是cluster.local,这不一定是真的

我认为它应该存在(但我不确定它是否真的存在)是一个 API,给定 StatefulSet 将允许我知道创建的副本的 DNS 名称。是否存在这样的 API?

【问题讨论】:

    标签: kubernetes kubernetes-go-client


    【解决方案1】:

    您需要的事件嗅探几乎就是 KubeDNS 的工作原理。

    所以code here 是古老而简单的方式。 看看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
        }
    }
    

    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))
    ... 
    

    full code

    您也可能理解 dns 是单独的 k8s 服务,而不是集群服务的一部分。所以找到 ip/host 并调用你的 dns 端点 For details 如果您使用默认命名策略和 coredsn 或 dns-masq 服务。 您也可以拥有来自pod metadata 名称或自链接的域名

        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
    

    【讨论】:

    【解决方案2】:

    当您使用 StatefulSet 创建无头 Service 时,它应该创建 DNS SRV 条目。您可以查询它以获取与无头Service 对应的 pod 的所有主机名的列表,而无需知道编号。例如,如果使用 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.>
    

    见:

    【讨论】:

    • 如何从这些项目中获取 IP?我正在尝试将它们用作 Kafka 消费者的引导服务器,但我无法获得正确的字符串来传递...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2016-02-03
    • 2018-09-20
    • 2019-03-07
    • 2012-03-11
    • 2015-10-06
    相关资源
    最近更新 更多