什么是 CoreDNS?
CoreDNS 是一个 DNS 服务器。它是用Go编写的。
CoreDNS 与其他 DNS 服务器不同,例如(所有优秀的) BIND、 Knot、 PowerDNS和 Unbound(技术上是解析器,但仍然值得一提),因为它非常灵活,几乎所有功能都外包到插件中。
插件可以是独立的,也可以一起工作以执行“DNS 功能”。
那么什么是“DNS 功能”?对于 CoreDNS,我们将其定义为实现 CoreDNS 插件 API 的软件。实现的功能可能会大相径庭。有些插件本身不会创建响应,例如metrics或 cache,但会添加功能。然后有一些插件会生成响应。这些也可以做任何事情:有与 Kubernetes通信以提供服务发现的插件,从文件或数据库中读取数据的插件。
目前默认 CoreDNS 安装中包含大约 30 个插件,但也有一大堆外部插件可以编译到 CoreDNS 中以扩展其功能。
CoreDNS 由插件提供支持。
编写新插件应该很容易,但需要了解 Go 并了解 DNS 的工作原理。CoreDNS 抽象了很多 DNS 细节,这样你就可以专注于编写你需要的插件功能。
插件链处理
一旦 CoreDNS 启动并解析了配置,它就会运行服务器。每个服务器都由它服务的区域和端口定义。每个服务器都有自己的插件链。
当 CoreDNS 处理查询时,将执行以下步骤:
如果配置了多个服务器来侦听查询的端口,它将检查哪个服务器具有此查询的最特定区域(最长后缀匹配)。例如,如果有两台服务器,一台为example ,一台为a.example ,查询为.a.example ,它将被路由到后者。
找到服务器后,它将通过为此服务器配置的插件链进行路由。这总是以相同的顺序发生。该(静态)排序在 plugin.cfg.
每个插件都会检查查询并确定它是否应该处理它(一些插件允许您进一步过滤查询名称或其他属性)。现在可能会发生几件事:
查询由此插件处理。
该插件不处理查询。
查询由这个插件处理,但在它进行到一半时,它决定仍然要调用链中的下一个插件。我们在启用它的关键字之后将此称为失败。
该插件处理查询,添加“提示”并调用下一个插件。该提示提供了一种“”(最终)响应并据此采取行动的方法。
处理查询意味着插件将以回复响应客户端。
请注意,插件可以随意偏离上述列表。目前,CoreDNS 附带的所有插件都属于这四个组之一。请注意,这篇博文还提供了查询路由的背景知识。
查询已处理
该插件处理查询。它查找(或生成,或插件决定此插件做什么)响应并将其发送回客户端。查询处理在这里停止,没有调用下一个插件。一个像这样工作的(简单)插件是whoami。
查询未处理
如果插件决定不处理查询,它只需调用链中的下一个插件。如果链中的最后一个插件决定不处理查询,CoreDNS 会将 SERVFAIL 返回给客户端。
查询处理失败
在这种情况下,插件处理查询,但它从后端得到的回复(即它可能得到 NXDOMAIN)是这样的,它希望链中的其他插件也可以。如果提供了fallthrough (并启用了!),则调用下一个插件。像这样工作的插件是 主机插件。首先,尝试在主机表 ( /etc/hosts) 中查找,如果找到答案,则返回该答案。如果没有,它会掉到下一个,希望其他插件可以向客户端返回一些东西。
使用提示处理查询
这种插件会处理一个查询,并且总是调用下一个插件。但是,它提供了一个提示,允许它将写入客户端的响应。执行此操作的插件是prometheus。它计算持续时间(除其他外),但实际上并没有对 DNS 请求做任何事情——它只是将其传递并检查返回路径上的一些元数据。
未注册的插件
还有一类特殊的插件根本不处理任何 DNS 数据,但会影响 CoreDNS 在其他方面的行为。以控制 CoreDNS 应该绑定到哪些接口的绑定插件为例。以下插件属于此类:
bind - 如前所述,控制要绑定的接口。
root - 设置 CoreDNS 插件应该在其中查找文件的根目录。
health - 启用 HTTP 健康检查端点。
就绪- 支持插件的就绪报告。
插件剖析
插件由设置、注册和处理程序部分组成。
安装程序解析配置和插件的指令(这些应该记录在插件的自述文件中)。
Handler是处理查询并实现所有逻辑的代码。
注册部分在 CoreDNS 中注册插件 - 这发生在编译 CoreDNS 时。服务器可以使用所有注册的插件。在每个服务器中配置哪些插件的决定发生在运行时,并在 CoreDNS 的配置文件 Corefile 中完成。
插件文档
每个插件都有自己的自述文件,详细说明了如何配置它。本自述文件包括示例和用户应注意的其他内容。这些 README 中的每一个最终都位于