为 CoreDNS 编写插件

有关 CoreDNS 插件编写的简介。

插件为 CoreDNS 添加了功能,例如,缓存指标和基本区域文件服务都是插件。

如果您想编写一个新插件并希望将其默认包含,即合并到代码库中,请首先打开一个 问题,讨论最初的设计以及可能出现的其他事项。通常来说,从一个 README 文件开始解释从用户角度如何操作是个好主意。

请参阅 示例插件,了解如何构建、编写和测试插件。代码中有很多注释可帮助您完成。

如何注册 CoreDNS 插件?

在编写插件代码时,您需要向 CoreDNS 注册它。可以通过调用以下函数来完成

func init() { plugin.Register("foo", setup) }

在这种情况下,每个插件都必须有一个名称,即 foo。在配置中遇到 foo 时,将在该程序包中调用 setup 函数。

Setup 函数

setup 函数(可以称为其他名称,但几乎每个插件都只将其称为 setup)解析配置并填充内部数据结构。

setup 函数是一个 caddy.Controller,并返回一个错误:(我们使用 plugin.Error 为返回的错误加上前缀 plugin/foo:,以改善错误报告)。

func setup(c *caddy.Controller) error {
  if err != nil {
    return plugin.Error("foo", err)
  }

  // various other code

  return nil
}

如果我们在 Corefile 中看到了一行,例如

foo gizmo

我们可以像这样获取第一个参数(“gizmo”)的值

for c.Next() {              // Skip the plugin name, "foo" in this case.
    if !c.NextArg() {       // Expect at least one value.
        return c.ArgErr()   // Otherwise it's an error.
    }
    value := c.Val()        // Use the value.
}

您通过迭代 c.Next() 解析为您的插件提供的标记,只要有更多标记要解析,它就是正确的。由于插件可能多次出现,因此您必须迭代 c.Next() 以获取您的插件的所有出现并使用标记。

添加到 CoreDNS

若要将您的插件插入 CoreDNS,请放入 plugin.cfg 并运行 go generate

如果您正在使用外部的非核心插件,那么从插件目录到您的插件建立符号链接会是最简单的。例如

cd plugin
ln -s ../../example .
cd ..
vi plugin.cfg # add example:example
go generate
go build

插件在 CoreDNS 中的工作方式

查看 插件包的 Godoc。最重要的类型是 plugin.Handler

处理器是处理 DNS 请求的函数。CoreDNS 将为您完成设置 DNS 服务器的所有簿记工作,但您需要实现这两种类型。

编写处理器

plugin.Handler 是一个类似于 http.Handler 的接口,区别在于它处理 DNS,并且 ServeDNS 方法返回 (int, error)int 是状态代码,而 error(如果不是 nil)会被记录。请参阅 plugin.md 以详细了解这些返回值。

处理器通常是一个包含至少一个字段(链中的下一个处理器)的结构体。

type MyHandler struct {
  Next plugin.Handler
}

要实现 plugin.Handler 接口,我们编写一个名为 ServeDNS 的方法。此方法是实际的处理程序函数,并且除非它自己完全处理该请求,否则它应调用链中的下一个处理程序

func (h MyHandler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
  return h.Next.ServeDNS(ctx, w, r)
}

该接口还需要一个方法 func Name() string

func (h MyHandler) Name() string { return "foo" }

这就是全部内容(当然除了编写实际上可以对 DNS 请求做点什么的代码)。

延伸阅读

可以在 CoreDNS 中找到的插件的简单示例有

  • root;不将自身注册为插件。它只是执行一些设置。
  • chaos;响应 CH txt version.bind 请求的 DNS 插件。
  • example;一个在响应查询时打印“example”的示例插件。

请记住:最好的文档是 godoc代码 本身!

Miek Gieben
发布日期:并标记为 corednsdocumentationpluginplugins,使用了 674 字。