はじめに
CoreDNSはサービスディスカバリ機能を持ったDNSです。
CNCFでGraduatedになっているプロジェクトで、KubernetesのデフォルトDNSにもなっています。
この記事では、CoreDNSはプラグイン方式で拡張するようになっているので、その実装を見ていきます。
※ 実装はde2f63d78747b48ae458b8f2c327a01e44cf725cを基にしています。
プラグイン登録
CoreDNSのプラグインは動的にロードするのではなく、Caddyの仕組みを使ってビルド時に組み込まれます。
また、プラグインの実行順序もビルド時に決定されています。
プラグイン情報はzdirectives.goというファイルに定義されていて、zdirectives.goの作成がタスク化されています。
以下のステップを経ることで、プラグインがCoreDNSに組み込まれます。
plugin.cfgに定義
plugin.cfgにはビルドに使用するプラグインと、実行順序が定義されています。
plugin.cfgの内容は以下のようなものです。
metadata:metadata tls:tls reload:reload ... on:github.com/mholt/caddy/onevent
左がプラグイン名で、右がパッケージ名です。
ここに書かれている順番で、プラグインが実行されます。
go generate
を実行
go generate
は以下のように動きます。
go run directives_generate.go
が呼ばれる- zdirectives.goと関連ファイルを作成される
これによって、以下の内容がzdirectives.goに書き込まれます。
var Directives = []string{ "metadata", "tls", "reload", ... "on", }
このDirectives
が、プラグインの順序を定義しています。
go build
を実行
go build
の実行時に、zdirectives.goが使用されます
プラグインチェーンの実行
次は、CoreDNSのプラグインは、実行時の振る舞いについて
開始時に初期化
CoreDNSの開始時に各プラグインを初期化して、zdirectives.goに書かれている順番でプラグインチェーンに登録します
プラグインチェーンの参照
リクエストが来たら、プラグインチェーンにある最初のプラグインが実行されます
server.goのh.pluginChain.ServeDNS
からプラグインチェーンが開始されます
最初のプラグインを実行
最初のプラグインが実行されます
プラグインはServeDNSというインターフェースを持つので、それが実行されます
後続プラグインの実行
次のプラグインが実行される
plugin#NextOrFailure
を呼び出すことで次のプラグインが実行されるので、その関数の前後がプラグイン独自のコードを書く場所です。
まとめ
以上、CoreDNSが実装しているプラグインチェーンを紹介しました。
このブログでは、この記事のようにプログラムを作る時の参考になることを書き続けるつもりです。
もし興味があれば、twitterやブログのフォローしていただけると嬉しいです。