CoreDNS は、ネットワーク通信用にドメイン名を IP アドレスに解決するために使用されるオープン ソースのドメイン ネーム システム (DNS) サーバーです。これは Go 言語で書かれた拡張可能な DNS サーバーで、従来の DNS サーバーを置き換え、より柔軟で構成可能な解決ソリューションを提供するように設計されています。
CoreDNS は、ユーザーが必要に応じてプラグインを選択および組み合わせて、DNS サーバーの機能と動作をカスタマイズできるモジュラー プラグイン システムを提供します。さまざまなプラグインを追加することで、ユーザーはキャッシュ、転送、書き換え、ポリシー ルーティング、サービス検出などの機能を実装し、さまざまな複雑なドメイン名解決要件を満たすことができます。
プラグインは、 Setup、Registration 、およびHandlerセクションで構成されます。
セットアップ プログラムは、プラグインの構成とディレクティブを解析します。
ハンドラーは、クエリを処理し、すべてのロジックを実装するコードです。
登録とは、プラグインを CoreDNS に登録することです。これは、CoreDNS のコンパイル時に行われます。サーバーは登録されているすべてのプラグインを使用でき、各サーバーでどのプラグインを構成するかは実行時に決定され、CoreDNS 構成ファイル Corefile で行われます。
インストールして実行する
macOS に CoreDNS をインストールします。
brew install coredns
実行して、 coredns -plugins
インストールされているプラグインを表示します。
coredns -plugins
Server types:
dns
Caddyfile loaders:
flag
default
Other plugins:
dns.acl
dns.any
dns.auto
dns.autopath
dns.azure
dns.bind
dns.bufsize
dns.cache
dns.cancel
dns.chaos
dns.clouddns
dns.debug
dns.dns64
dns.dnssec
dns.dnstap
dns.erratic
dns.errors
dns.etcd
dns.file
dns.forward
dns.geoip
dns.grpc
dns.header
dns.health
dns.hosts
dns.k8s_external
dns.kubernetes
dns.loadbalance
dns.local
dns.log
dns.loop
dns.metadata
dns.minimal
dns.nsid
dns.pprof
dns.prometheus
dns.ready
dns.reload
dns.rewrite
dns.root
dns.route53
dns.secondary
dns.sign
dns.template
dns.tls
dns.trace
dns.transfer
dns.tsig
dns.view
dns.whoami
on
CoreDNSの操作は非常に簡単で、 coredns
コマンドを実行してサーバーを起動するだけです。ポートの競合を避けるために、他のポートを指定して開始することができます。
coredns -dns.port=1053
.:1053
CoreDNS-1.10.0
darwin/arm64, go1.19.1,
-conf
DNS サーバーを構成する必要がある場合は、 Corefile 構成ファイルを指定する必要があります 。また、構成ファイルでプラグインを有効にすることもできます。設定ファイルが指定されていない場合、CoreDNS はデフォルトの設定[1]を使用し、「whoami」[2] と「log」[3] の 2 つのプラグインのみを有効にします。
.:PORT {
whoami
log
}
192.168.1.174
たとえば、 CoreDNS サーバーを実行している macOS アドレスである仮想マシンから DNS 解決リクエストを実行します。
dig @192.168.1.174 -p 1053 example.com
; <<>> DiG 9.16.1-Ubuntu <<>> @192.168.1.174 -p 1053 example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1283
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: d73ad3e9df490541 (echoed)
;; QUESTION SECTION:
;example.com. IN A
;; ADDITIONAL SECTION:
example.com. 0 IN A 192.168.1.11
_udp.example.com. 0 IN SRV 0 0 48788 .
;; Query time: 8 msec
;; SERVER: 192.168.1.174#1053(192.168.1.174)
;; WHEN: Sat Jul 15 02:38:11 UTC 2023
;; MSG SIZE rcvd: 114
応答では、 解決されたことが ADDITIONAL
わかります 。このアドレスは、要求を開始した仮想マシンの IP アドレスです。これはプラグイン[4] のロジックです 。example.com
192.168.1.11
whoami
whoami は、リクエスタのローカル IP アドレス、ポートを返します。
ソースコード分析
起動
Coredns は、Caddy [5]からの Coredns Caddy [6 ] のフォークを使用して DNS サーバーを起動します。
/etc/coredns/Corefile
指定された Corefile 設定ファイル ( `coremain/run.go#L60`など) をロードします [7]Caddy サーバーの起動 coremain/run.go#L66 [8]
プラグインの実行1. プラグインの構成ファイルを確認します。Coredns にはサポートされているプラグインのリストがあり[9]、このリスト内のプラグインの順序は重要です。
setup
2. 各プラグインのコントローラーを作成します 3. Kubernetes プラグインの`setup` [10]メソッドなど、プラグイン登録のための起動メソッドを見つけます 。各プラグインのsetup
メソッドは、coredns/plugin/[PLUGIN NAME]/setup.go
にあります。4. プラグインを起動します。サーバー core/dnsserver/register.go#L134 を作成[11]
サーバーを起動 github.com/coredns/[email protected]/caddy.go:542[12 ]
リクエストを処理する
サーバーが起動すると、DNS 解決リクエストの受信が開始されます。 github.com/coredns/[email protected]/caddy.go:805 [13]を参照してください。
DNS 解決リクエスト core/dnsserver/server.go#L173 [14]を処理します。ここでメソッド ServeDNS [15]が呼び出され 、設定されたプラグインが順番に実行され、すべてのプラグインは plugin.Handler [16] インターフェイスを実装します。
構成された各プラグインは、DNS 解決を実行するかどうか、および次のステップを決定します: 応答を返すか、エラーを報告するか、すぐに戻るか、次のプラグインを呼び出して実行を継続します。詳細は公式ドキュメントを参照[17]。
CoreDNS と Kubernetes
CoreDNS は Kubernetes で重要な役割を果たし、クラスター内で DNS 解決のためのサービスを提供します。Kubernetes との緊密な統合により、CoreDNS は信頼性の高いサービス検出および通信機能を提供し、コンテナーとサービスがドメイン名を介して相互にアクセスして通信できるようにし、Kubernetes クラスターの運用のためのインフラストラクチャ サポートを提供します。
すべての機能は、Kubernetes の DNS ベースのサービス検出仕様[19]を実装するkubernetes プラグイン[18]に実装されており、CoreDNS はこれを使用して kube-dns を置き換えます。
Kubernetes の CoreDNS 構成 ( ConfigMap で維持 coredns
):
.: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 {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
CoreDNS が解決リクエストを処理するとき、各プラグインが順番に実行されます。
プラグインの設定
kubernetes cluster.local in-addr.arpa ip6.arpa { #1
pods insecure #2
fallthrough in-addr.arpa ip6.arpa #3
ttl 30 #4
}
#1 kubernetes プラグインは、
cluster.local
ドメインの DNS 解決リクエスト (例:foo.bar.svc.cluster.local
;)in-addr.arpa
およびip6.arpa
逆引き DNS ルックアップ[20]の例: を処理します4.4.8.8.in-addr.arpa
。注※2
10-244-0-2.bar.pod.cluster.local
POD ドメイン名の解決モード ( など) を に設定しますinsecure
。disabled
他verified
の 2 つのモードもサポートされます。注※3 逆引きクエリの解析リクエストは他のプラグインに引き継いでクエリを継続します。
注※4 解析結果の有効期間はデフォルトでは5秒ですが、ここでは30秒に設定しています。
起動
CoreDNS が開始すると、Kubernetes API に接続してすべての監視対象オブジェクトを同期できるまで、DNS サービスの提供が最大 5 秒遅れます。ドキュメント[21]を参照してください。
kubernetes プラグインは、構成に従って最大 4 つのコントローラー[22]を起動し、それぞれ Service、Pod (解決モードが に設定されている verified
場合に、ローカル キャッシュを維持します。
リクエストを処理する
kubernetes プラグインは、リクエストに応答するときにローカル キャッシュからレコードを検索するための`plugin.ServiceBackend` インターフェイス[23]を実装します。
A レコードのクエリを例に挙げると、plugin#A メソッド[24] を呼び出して、`ServiceBackend#Services` メソッド[25]の実装を間接的に呼び出して 、IP アドレスを取得して返します。
nslookup -type=a foo.bar.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: foo.bar.svc.cluster.local
Address: 10.96.60.147
参考文献
[1]
デフォルト設定: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/register.go#L25
[2]whoami
: https://coredns.io/plugins/whoami/
log
: https://coredns.io/plugins/log/
ロジック: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/whoami/whoami.go#L22
[5]キャディ: https://github.com/caddyserver/caddy
[6]Coredns Caddy: https://github.com/coredns/caddy
[7]coremain/run.go#L60
: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/coremain/run.go#L60
coremain/run.go#L66: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/coremain/run.go#L66
[9]プラグインリスト: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/zdirectives.go#L12
[10]setup
: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/kubernetes/setup.go#L31
core/dnsserver/register.go#L134: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/register.go#L134
[12]github.com/coredns/[email protected]/caddy.go:542: https://github.com/coredns/caddy/blob/v1.1.1/caddy.go#L542
[13]github.com/coredns/[email protected]/caddy.go:805: https://github.com/coredns/caddy/blob/v1.1.1/caddy.go#L805
[14]core/dnsserver/server.go#L173: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/server.go#L173
[15]メソッド ServeDNS: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/core/dnsserver/server.go#L252
[16]plugin.Handler: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/plugin.go#L50
[17]公式ドキュメント: https://coredns.io/manual/plugins/#plugins
[18]kubernetes プラグイン: https://coredns.io/plugins/kubernetes/
[19]Kubernetes の DNS ベースのサービス検出仕様: https://github.com/kubernetes/dns/blob/master/docs/specation.md
[20]DNS 逆引き参照: https://en.wikipedia.org/wiki/Reverse_DNS_lookup
[21]ドキュメント: https://coredns.io/plugins/kubernetes/#startup
[22]最大 4 つのコントローラーを起動します: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/kubernetes/controller.go#L105
[23]plugin.ServiceBackend
インターフェース: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/backend.go#L13
plugin#A メソッド: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/backend_lookup.go#L17
[25]ServiceBackend#Services
メソッドの実装: https://github.com/coredns/coredns/blob/e550ebd51933fdc40569316a29f36bb881f22e88/plugin/kubernetes/kubernetes.go#L92