【问题标题】:How to obtain Ip address of a kubernetes pod by querying DNS srv records?如何通过查询 DNS srv 记录获取 kubernetes pod 的 IP 地址?
【发布时间】:2019-10-25 17:13:04
【问题描述】:

我正在尝试创建一个 kubernetes 作业,我将在其中运行“dig srv”查询以找出在同一集群上运行的任何特定服务的所有 pod 的 IP 地址。

这可以实现吗?

我想详细说明问题陈述。集群上已经运行了一些服务。要求是有一个工具可以接受服务名称并列出属于该服务的所有 Pod 的 IP 地址。

我可以通过使用 kubectl 命令以及选择器和 jq 工具来做到这一点。但是由于某些原因,我不允许在这个环境中运行 kubectl 命令。

我想使用 dig srv 查询来解析提供的服务名称的 pod IP。

【问题讨论】:

    标签: kubernetes kubernetes-pod kube-dns kubernetes-jobs srv-record


    【解决方案1】:

    您可以使用无头服务(因此没有 ClusterIP 和内部负载平衡)。如果提供选择器,则可以查询服务的A记录。

    见:https://kubernetes.io/docs/concepts/services-networking/service/#headless-services

    考虑以下示例:

    部署一些 pod:

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

    为此部署添加了以下无头服务:

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    

    现在可以使用 DNS(在集群内)进行查询

    $ 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
    

    所有内部 Pod IP 都作为 DNS A 记录返回。

    【讨论】:

    • 我浏览了很多 Kubernetes 文档,但找不到确切的解决方案。也许您可以提供此类实现的参考示例。为了更清楚,我已经用详细的问题陈述编辑了这个问题。
    • 我可以按照您建议的方式获取无头服务的IP地址。但是,如果我使用的服务不是无头服务,我只会获得该服务的 IP 地址。如何列出非无头服务的所有 Pod 的 IP 地址?
    • 我建议您决定是要通过查询无头服务的端点直接访问 IP,还是要使用带有 ClusterIP 的内部负载平衡。如果出于某种原因,您想同时拥有两者,您可以创建两个服务,一个用于访问服务,另一个用于查询 IP 地址。
    • 我做了更多的研究并浏览了文档。看起来我想要实现的目标是不可能的。我要开发的工具接受服务名称并返回所有 pod 的 IP 地址。这只有在服务是无头的情况下才有可能。查找任何其他服务的所有 pod 的 IP 似乎并不可行。
    • 如果相信给定的问题陈述,使用(附加)无头服务的答案是正确的。如果这不是您真正想要实现的,请打开一个新问题并更准确地解释您的用例。
    【解决方案2】:

    这在DNS for Services and Pods里面有解释。

    集群中定义的每个服务(包括 DNS 服务器本身)都被分配了一个 DNS 名称。默认情况下,客户端 Pod 的 DNS 搜索列表将包括 Pod 自己的命名空间和集群的默认域。最好用例子来说明这一点:

    假设在 Kubernetes 命名空间 bar 中有一个名为 foo 的服务。在命名空间 bar 中运行的 Pod 可以通过简单地对 foo 进行 DNS 查询来查找此服务。在命名空间 quux 中运行的 Pod 可以通过对 foo.bar 进行 DNS 查询来查找此服务。

    这是Kubernetes DNS-Based Service Discovery 的详细文档。

    至于查询POD的ip地址,要看是否指定了spec.hostname

    如果在与 Pod 相同的命名空间中存在与子域同名的无头服务,则集群的 KubeDNS Server 也会返回 Pod 的完全限定主机名的 A 记录。例如,给定一个主机名设置为“busybox-1”且子域设置为“default-subdomain”的 Pod,以及同一命名空间中名为“default-subdomain”的无头服务,该 pod 将看到自己的 FQDN 为“busybox-1.default-subdomain.my-namespace.svc.cluster.local”。 DNS 以该名称提供一条 A 记录,指向 Pod 的 IP。 “busybox1”和“busybox2”这两个 pod 都可以有各自不同的 A 记录。

    Endpoints 对象可以为任何端点地址指定 hostname 及其 IP。

    注意:因为没有为 Pod 名称创建 A 记录,所以创建 Pod 的 A 记录需要hostname。没有hostname 但有subdomain 的Pod 只会为无头服务(default-subdomain.my-namespace.svc.cluster.local)创建A 记录,指向Pod 的IP 地址。此外,除非在 Service 上设置了 publishNotReadyAddresses=True,否则 Pod 需要准备好才能有记录。

    希望这足以解释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      相关资源
      最近更新 更多