diff --git a/content/zh/blog/_posts/2018-07-10-coredns-ga.md b/content/zh/blog/_posts/2018-07-10-coredns-ga.md new file mode 100644 index 0000000000..5edcfb4693 --- /dev/null +++ b/content/zh/blog/_posts/2018-07-10-coredns-ga.md @@ -0,0 +1,306 @@ +--- +layout: blog +title: "用于 Kubernetes 集群 DNS 的 CoreDNS GA" +date: 2018-07-10 +--- + + + +**作者**:John Belamaric (Infoblox) + +**编者注:这篇文章是 [系列深度文章](https://kubernetes.io/blog/2018/06/27/kubernetes-1.11-release-announcement/) 中的一篇,介绍了 Kubernetes 1.11 新增的功能 + + +## 介绍 + +在 Kubernetes 1.11 中,[CoreDNS](https://coredns.io) 已经达到基于 DNS 服务发现的 General Availability (GA),可以替代 kube-dns 插件。这意味着 CoreDNS 会作为即将发布的安装工具的选项之一上线。实际上,从 Kubernetes 1.11 开始,kubeadm 团队选择将它设为默认选项。 + + +很久以来,基于 DNS 的服务发现在 kube-dns 集群插件中一直是 Kubernetes 的一部分。通常,此方法运行平稳,但对于实现的可靠性、灵活性和安全性仍存在一些问题。 + +CoreDNS 是通用的、权威的 DNS 服务器,提供与 Kubernetes 向后兼容但可扩展的集成。它解决了 kube-dns 遇到的问题,并提供了许多独特的功能,可以解决各种用例。 + +在本文中,您将了解 kube-dns 和 CoreDNS 的实现有何差异,以及 CoreDNS 提供的一些非常有用的扩展。 + + +## 实现差异 + +在 kube-dns 中,单个容器会使用多个 Pod: `kubedns`、 `dnsmasq`、和 `sidecar`。`kubedns` 容器监视 Kubernetes API 并根据 [Kubernetes DNS 规范](https://github.com/kubernetes/dns/blob/master/docs/specification.md) 提供 DNS 记录,`dnsmasq` 提供缓存和存根域支持,`sidecar` 提供指标和健康检查。 + + +随着时间的推移,此设置会导致一些问题。一方面,以往 `dnsmasq` 中的安全漏洞需要通过发布 Kubernetes 的安全补丁来解决。但是,由于 `dnsmasq` 处理存根域,而 `kubedns` 处理外部服务,因此您不能在外部服务中使用存根域,导致这个功能具有局限性(请参阅 [dns#131](https://github.com/kubernetes/dns/issues/131))。 + +所有这些功能都是在 CoreDNS 的单个容器中完成的,该容器正在运行用 Go 编写的进程。启用的不同插件可复制(并增强)在 kube-dns 中发现的功能。 + + +## 配置 CoreDNS + +在 kube-dns 中,您可以 [修改 ConfigMap](https://kubernetes.io/blog/2017/04/configuring-private-dns-zones-upstream-nameservers-kubernetes/) 来更改服务发现的性能。这允许添加诸如为存根域提供服务,修改上游名称服务器以及启用联盟之类的功能。 + + +在 CoreDNS 中,您可以类似地修改 CoreDNS [Corefile](https://coredns.io/2017/07/23/corefile-explained/) 的 ConfigMap,以更改服务发现的工作方式。这种 Corefile 配置提供了比 kube-dns 中更多的选项,因为它是 CoreDNS 用于配置所有功能的主要配置文件,即使与 Kubernetes 不相关的功能也可以操作。 + +使用 `kubeadm` 将 kube-dns 升级到 CoreDNS 时,现有的 ConfigMap 将为您生成自定义的 Corefile,包括存根域,联盟和上游名称服务器的所有配置。更多详细信息,请参见 [使用 CoreDNS 进行服务发现](/docs/tasks/administer-cluster/coredns/)。 + + +## 错误修复和增强 + +在 CoreDNS 中解决了 kube-dn 的多个未解决问题,无论是默认配置还是某些自定义配置。 + + + * [dns#55 - kube-dns 的自定义 DNS 条目](https://github.com/kubernetes/dns/issues/55) 可以使用 [kubernetes 插件](https://coredns.io/plugins/kubernetes) 中的 "应急" 机制,使用 [rewrite 插件](https://coredns.io/plugins/rewrite),或者分区使用不同的插件,例如 [file 插件](https://coredns.io/plugins/file)。 + + * [dns#116 - 只有一个记录集 A,对具有单个主机名的 Pod 提供 headless 服务](https://github.com/kubernetes/dns/issues/116)。无需任何其他配置即可解决此问题。 + * [dns#131 - externalName 不使用 stubDomains 设置](https://github.com/kubernetes/dns/issues/131)。无需任何其他配置即可解决此问题。 + * [dns#167 - 启用 skyDNS 循环 A/AAAA 记录](https://github.com/kubernetes/dns/issues/167)。可以使用 [负载均衡插件](https://coredns.io/plugins/loadbalance) 配置等效功能。 + * [dns#190 - kube-dns 无法以非 root 用户身份运行](https://github.com/kubernetes/dns/issues/190)。今天,通过使用 non-default 镜像解决了此问题,但是在将来的版本中,它将成为默认的 CoreDNS 行为。 + * [dns#232 - 在 dns srv 记录中修复 pod hostname 为 podname](https://github.com/kubernetes/dns/issues/232) 是通过下面提到的 "endpoint_pod_names" 功能进行支持的增强功能。 + + + +## 指标 + +默认 CoreDNS 配置的功能性能与 kube-dns 相同。但是,您需要知道的不同点是发布的指标是不同的。在 kube-dns 中,您将获得 `dnsmasq` 和 `kubedns` (skydns)的单独指标。在 CoreDNS 中,存在一组完全不同的指标,因为它们都是单独的进程。您可以在 CoreDNS [Prometheus 插件](https://coredns.io/plugins/metrics/) 页面上找到有关这些指标的更多详细信息。 + + +## 一些特殊功能 + +标准的 CoreDNS Kubernetes 配置旨在与以前的 kube-dns 性能向后兼容。但是,通过进行一些配置更改,CoreDNS 允许您修改 DNS 服务发现在群集中的工作方式。这些功能中的许多功能仍要符合 [Kubernetes DNS规范](https://github.com/kubernetes/dns/blob/master/docs/specification.md),增强了功能,但仍向后兼容。由于 CoreDNS 并非 *仅* 用于 Kubernetes,而是通用的 DNS 服务器,因此您可以做很多超出该规范的事情。 + + +### Pod 验证模式 + +在 kube-dns 中,Pod 名称记录是 "伪造的"。也就是说,任何 "a-b-c-d.namespace.pod.cluster.local" 查询都将返回 IP 地址 "a.b.c.d"。在某些情况下,这可能会削弱 TLS 提供的身份确认。因此,CoreDNS 提供了一种 "Pod 验证" 的模式,该模式仅在具有该 IP 地址的指定名称空间中存在 Pod 时才返回 IP 地址。 + + +### 基于 Pod 名称的端点名称 + +在 kube-dns 中,使用外设服务时,可以使用 SRV 请求获取该服务的所有端点的列表: + +``` +dnstools# host -t srv headless +headless.default.svc.cluster.local has SRV record 10 33 0 6234396237313665.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 10 33 0 6662363165353239.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 10 33 0 6338633437303230.headless.default.svc.cluster.local. +dnstools# +``` + + +但是,端点 DNS 名称(出于实际目的)是随机的。在 CoreDNS 中,默认情况下,您会根据端点 IP 地址获得端点 DNS 名称: + +``` +dnstools# host -t srv headless +headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-14.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-18.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-4.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-9.headless.default.svc.cluster.local. +``` + + +对于某些应用程序,需要具有容器名称,而不是容器 IP 地址(例如,参见 [kubernetes#47992](https://github.com/kubernetes/kubernetes/issues/47992) 和 [coredns#1190](https://github.com/coredns/coredns/pull/1190))。要在 CoreDNS 中启用此功能,请在 Corefile 中指定 "endpoint_pod_names" 选项,结果如下: + +``` +dnstools# host -t srv headless +headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-qv84p.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-zc8lx.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-q7lf2.headless.default.svc.cluster.local. +headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-566rt.headless.default.svc.cluster.local. +``` + + +### 自动路径 + +CoreDNS 还具有一项特殊功能,可以改善 DNS 中外部名称请求的延迟。在 Kubernetes 中,Pod 的 DNS 搜索路径指定了一长串后缀。可以在群集中请求服务时使用短名称 - 例如,上面的 "headless",而不是 "headless.default.svc.cluster.local"。但是,当请求一个外部名称(例如 "infoblox.com")时,客户端会进行几个无效的 DNS 查询,每次都需要从客户端到 kube-dns 往返(实际上是到 `dnsmasq`,然后到 `kubedns`) ,因为 [禁用了负缓存](https://github.com/kubernetes/dns/issues/121)) + + * infoblox.com.default.svc.cluster.local -> NXDOMAIN + * infoblox.com.svc.cluster.local -> NXDOMAIN + * infoblox.com.cluster.local -> NXDOMAIN + * infoblox.com.your-internal-domain.com -> NXDOMAIN + + * infoblox.com -> 返回有效记录 + + +在 CoreDNS 中,可以启用 [自动路径](https://coredns.io/plugins/autopath) 的可选功能,该功能使搜索路径存在于 *服务器中*。也就是说,CoreDNS 将从源 IP 地址中找出客户端 Pod 所在的命名空间,并且遍历此搜索列表,直到获得有效答案为止。由于其中的前三个是在 CoreDNS 本身内部解决的,因此它消除了客户端和服务器之间所有的来回通信,从而减少了延迟。 + + +### 其他一些 Kubernetes 的特定功能 + +在 CoreDNS 中,您可以使用标准 DNS 区域传输来导出整个 DNS 记录集。这对于调试服务以及将集群区导入其他 DNS 服务器很有用。 + +您还可以按名称空间或标签选择器进行过滤。这样,您可以运行特定的 CoreDNS 实例,该实例仅服务与过滤器匹配的记录,从而通过 DNS 公开受限的服务集。 + + +## 可扩展性 + +除了上述功能之外,CoreDNS 还可轻松扩展,构建包含您独有的功能的自定义版本的 CoreDNS。例如,以下功能已被用于扩展 CoreDNS ,使用 [unbound 插件](https://coredns.io/explugins/unbound) 进行递归解析,使用 [pdsql 插件](https://coredns.io/explugins/pdsql) 服务器直接记录,还有允许多个 CoreDNS 实例与 [redisc 插件](https://coredns.io/explugins/redisc) 共享一个公共的 2 级缓存。 + +添加了许多其他有趣的扩展,您可以在 CoreDNS 站点的 [外部插件](https://coredns.io/explugins/) 页面上找到这些扩展。Kubernetes 和 Istio 用户真正感兴趣的是 [kubernetai 插件](https://coredns.io/explugins/kubernetai),它允许单个 CoreDNS 实例连接到多个 Kubernetes 集群并在所有集群中提供服务发现 。 + + +## 下一步工作 + +CoreDNS 是一个独立的项目,许多与 Kubernetes 不直接相关的功能正在开发中。但是,其中许多功能将在 Kubernetes 中具有应用程序。例如,与策略引擎完成集成后,当请求 headless 服务时,CoreDNS 能够智能地选择返回哪个端点。这可用于将工程分流到到本地 Pod 或响应更快的 Pod。更多的其他功能正在开发中,当然作为一个开源项目,我们欢迎您提出建议并贡献自己的功能! + +上述特征和差异是几个示例。CoreDNS 还可以做更多的事情。您可以在 [CoreDNS 博客](https://coredns.io/blog) 上找到更多信息。 + + +### 参与 CoreDNS + +CoreDNS 是一个孵化的 [CNCF](https:://cncf.io) 项目。 + +我们在 Slack(和 GitHub)上最活跃: + +- Slack: #coredns on +- GitHub: + + +更多资源请浏览: + +- Website: +- Blog: +- Twitter: [@corednsio](https://twitter.com/corednsio) +- Mailing list/group: +