CoreDNS之光:Kubernetes中的服务发现策略

发布时间 2023-08-29 18:29:30作者: 技术颜良

 

点击上方蓝字 ?关注公众号,别让消息溜走

后台回复【加群】,与牛人互动不停

 


 

在 Kubernetes 中,DNS 名称被分配给 Pod 和服务,以便通过名称而不是 IP 地址进行通信。

集群内DNS解析默认使用的域名为cluster.local,可以根据需要自定义。Service 的 DNS 名称遵循<service-name>.<namespace>.svc.cluster.local格式,而Pod 的 DNS 名称遵循<pod-ip-address-replace-dot-with-hyphen>.<namespace>.pod.cluster.local格式。

CoreDNS 的运行基于名为Corefile的配置文件,该文件指定 DNS 服务器应如何运行并响应传入请求。

图片Kubernetes:DNS

DNS解析

在 Kubernetes 中,分配给 Pod 和服务的DNS 名称用集群内的名称解析,允许Pod 和服务通过名称而不是 IP 地址相互通信。

云原生百宝箱
行万里路,此处相逢,共话云原生之道。 偶逗趣事,明月清风,与君同坐。
20篇原创内容

默认域名:cluster.local

在 Kubernetes 中,cluster.local是集群内用于 DNS 解析的默认域名。当对同一命名空间内的服务或 Pod 进行 DNS 查询时,Kubernetes DNS 服务会将命名空间和cluster.local后缀附加到名称中,以形成完全限定域名 (FQDN)。虽然它是默认域名,但如果需要,可以自定义使用不同的域名。

Service的 DNS 名称

Kubernetes 中服务的 DNS 名称遵循以下格式:

图片Service的 DNS 名称
<service-name>.<namespace>.svc.cluster.local

service-name的是Service的名称,而namespace表示Service运行的命名空间。

例如,如果一个名为的服务my-service正在my-namespace命名空间中运行,则相应的 DNS 名称将为:

my-service.my-namespace.svc.cluster.local

Pod 的 DNS 名称

Kubernetes 中 Pod 的 DNS 名称遵循以下格式:

图片Pod 的 DNS 名称
<pod-ip-address-replace-dot-with-hyphen>.<namespace>.pod.cluster.local

pod-ip-address-replace-dot-with-hyphen是 Kubernetes 分配给 Pod 的 IP 地址,其中点由连字符替换。namespace是Pod 运行所在的命名空间。

例如,如果具有10.1.2.3 IP 地址的 Pod在my-namespace命名空间中运行,则其 DNS 名称将为:

10-1-2-3.my-namespace.pod.cluster.local

使用 DNS 名称进行 Pod 和服务交互

同一命名空间中的 Pod 和服务

当 Pod 和 Services 位于同一命名空间时,你可以使用服务名称而不是完全限定域名 (FQDN)通过查询访问 Services。

图片同一命名空间中的 Pod 和服务

不同命名空间中的 Pod 和服务

当 Kubernetes 中 Pod 和 Service 位于不同的命名空间时,需要同时指定Service 名称和命名空间,才能从 Pod 访问 Service。

图片不同命名空间中的 Pod 和服务

CoreDNS

在引入 CoreDNS 之前,Kubernetes 使用kube-dns作为默认的 DNS 解决方案。DNS 服务器处理集群中服务和 Pod 的 DNS 请求。根据Kubernetes 官方文档,从 1.11 版本开始,推荐使用 CoreDNS 作为默认 DNS 解决方案,并默认与 kubeadm 一起安装。

配置文件:核心文件

Corefile 是一个文本文件,指定 DNS 服务器应如何操作和响应传入请求。

核心文件示例:

.:53 {
      errors
      health {
          lameduck 5s
      }
      ready
      kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
          ttl 30
      }
      prometheus :9153
      forward . /etc/resolv.conf
      cache 30
      loop
      reload
      loadbalance
 }  

集群的顶级域名在Kubernetes 插件配置中指定为“ cluster.local ” 。该插件还配置为使用 in-addr.arpa 和 ip6.arpa 域处理 IPv4 和 IPv6 地址的反向 DNS 查找。

要了解有关 Corefile 及其语法的更多信息,请参阅CoreDNS Manual或CoreDNS ConfigMap options中提供的官方文档。

CoreDNS 指标

DNS服务器将记录存储在其数据库中并使用该数据库回答域名查询。如果 DNS 服务器没有此数据,它会尝试从其他 DNS 服务器寻找解决方案。

DNS 解析是任何应用程序的基本要求,因此你需要确保其正常工作。我们建议查看dns-debugging-resolution故障排除指南,并确保你的 CoreDNS 已配置并正确运行。

默认情况下,当你配置集群时,你应该始终有一个仪表板来观察关键的 CoreDNS 指标。为了获取 CoreDNS 指标,你应该在 CoreDNS 配置中启用Prometheus 插件。

下面的示例配置使用prometheus插件启用从 CoreDNS 实例收集指标。

.:53 {
    errors
    health
    kubernetes cluster.local in-addr.arpa ip6.arpa {
      pods verified
      fallthrough in-addr.arpa ip6.arpa
    }
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

以下是我们建议在你的仪表板中包含的关键指标。如果你使用 Prometheus、DataDog、Kibana 等,你可能会发现可以使用来自社区/提供商的仪表板模板。

  • • 缓存命中百分比:使用 CoreDNS 缓存响应的请求的百分比

  • • DNS 请求延迟 - CoreDNS:CoreDNS 处理 DNS 请求所花费的时间 - 上游服务器:处理转发到上游的 DNS 请求所花费的时间

  • • 转发到上游服务器的请求数

  • • 请求的错误代码 - NXDomain:不存在的域 - FormErr:DNS 请求中的格式错误 - ServFail:服务器故障 - NoError:无错误,已成功处理请求

  • • CoreDNS 资源使用情况:服务器消耗的不同资源,如内存、CPU 等。

我们使用 DataDog 进行特定应用程序监控。以下只是我使用 DataDog 构建的用于分析的示例仪表板。

图片CoreDNS 指标

减少 DNS 搜索

当我们开始深入了解应用程序如何向 CoreDNS 发出请求时,我们观察到大多数出站请求是通过应用程序发送到外部 API 服务器的。

这通常是 resolv.conf 在应用程序部署 Pod 中的外观。

nameserver 10.100.0.10
search kube-namespace.svc.cluster.local svc.cluster.local cluster.local us-west-2.compute.internal
options ndots:5

如果你了解 Kubernetes 如何尝试解析 FQDN,就知道它会尝试在不同级别进行 DNS 查找。

考虑到上述 DNS 配置,当 DNS 解析器向 CoreDNS 服务器发送查询时,它会尝试考虑搜索路径来搜索域。

如果我们正在寻找域名 boktube.io,它将进行以下查询,并在最后一个查询中收到成功的响应。

botkube.io.kube-namespace.svc.cluster.local  <= NXDomain
botkube.io.svc.cluster.local <= NXDomain
boktube.io.cluster.local <= NXDomain
botkube.io.us-west-2.compute.internal <= NXDomain
botkube.io <= NoERROR

由于我们进行了太多的外部查找,因此我们收到了大量针对 DNS 搜索的 NXDomain 响应。为了优化这一点,我们spec.template.spec.dnsConfig在 Deployment 对象中进行了自定义。变化是这样的:

dnsPolicy: ClusterFirst
     dnsConfig:
       options:
       - name: ndots
         value: "1"

通过上述更改,pod 上的resolve.conf 发生了更改。仅针对外部域执行搜索。这减少了对 DNS 服务器的查询数量。这也有助于减少应用程序的 5xx 错误。你可以在下图中注意到 NXDomain 响应计数的差异。

图片减少 DNS 搜索

对于这个问题,一个更好的解决方案是Kubernetes 1.18+ 引入的节点级缓存。

云原生百宝箱
行万里路,此处相逢,共话云原生之道。 偶逗趣事,明月清风,与君同坐。
20篇原创内容

 

定制 CoreDNS

 

 

图片

 

 

我们可以通过插件来定制CoreDNS。Kubernetes 支持不同类型的工作负载,标准 CoreDNS 配置可能无法满足你的所有需求。CoreDNS 有几个插件。根据你在集群上运行的工作负载类型(假设相互通信的应用程序或在 Kubernetes 集群外部交互的独立应用程序),你尝试解析的 FQDN 类型可能会有所不同。

假设你在特定的公共/私有云中运行 Kubernetes,并且大多数 DNS 支持的应用程序都在同一云中。在这种情况下,CoreDNS 还提供特定的云相关或通用插件,可用于扩展 DNS 区域记录。

是否在 Kubernetes 集群中运行适当数量的 CoreDNS 实例是需要做出决定的关键因素之一。建议运行至少两个 CoreDNS 服务器实例,以更好地保证 DNS 请求得到服务。根据所服务的请求数量、请求性质、集群上运行的工作负载数量以及集群大小,你可能需要添加额外的 CoreDNS 实例或为集群配置 HPA。

图片

云原生百宝箱

最喜欢你一言不合就打赏的样子

收录于合集 #Kubernetes
 21
上一篇流量何处来又往何处去,这次一目了然下一篇Kubernetes CNI 插件选型和应用场景探讨
阅读 882
云原生百宝箱
 
 
关注后可发消息