説明
loop プラグインは、自身にランダムなプローブクエリを送信し、その出現回数を追跡します。2回以上検出された場合、CoreDNSが転送ループを検出したと判断し、プロセスを停止します。
このプラグインは、最大30秒間クエリを送信しようとします。これは、CoreDNSの起動時間を確保するためです。クエリが正常に送信されると、loop はクエリ・オブ・デスを防ぐために自身を無効化します。
loop は、サーバーブロックで最初に指定されたゾーンに対してのみ「ループクエリ」を送信することに注意してください。
送信されるクエリは、タイプがHINFOに設定された<乱数>.<乱数>.zone
です。
構文
loop
例
デフォルトポートでサーバーを起動し、loop と forward プラグインをロードします。forward プラグインは自身に転送します。
. {
loop
forward . 127.0.0.1
}
CoreDNSが起動した後、ログを出力しながらプロセスを停止します。
plugin/loop: Loop (127.0.0.1:55953 -> :1053) detected for zone ".", see https://coredns.dokyumento.jp/plugins/loop#troubleshooting. Query: "HINFO 4547991504243258144.3688648895315093531."
制限事項
このプラグインは、起動時の単純な静的転送ループのみを検出しようとします。ループを検出するには、次の条件が満たされている必要があります。
-
ループは起動時に存在している必要があります。
-
ループは
HINFO
クエリタイプに対して発生する必要があります。
トラブルシューティング
CoreDNSのログにLoop ... detected ...
というメッセージが含まれている場合、loop
検出プラグインが、アップストリームDNSサーバーのいずれかで無限の転送ループを検出したことを意味します。これは致命的エラーです。無限ループで動作すると、メモリとCPUを消費し続け、最終的にホストのメモリ不足でクラッシュします。
転送ループは通常、次によって発生します。
- 最も一般的な原因は、CoreDNSが自身に直接転送リクエストを送信することです。例:
127.0.0.1
、::1
、または127.0.0.53
などのループバックアドレスを介して。 - まれに、CoreDNSがアップストリームサーバーに転送し、そのサーバーがCoreDNSにリクエストを転送するケースもあります。
この問題を解決するには、ループが検出されたゾーンへのすべてのforward
をCorefileで確認してください。ローカルアドレスまたはCoreDNSにリクエストを転送する他のDNSサーバーに転送していないことを確認してください。forward
がファイル(例:/etc/resolv.conf
)を使用している場合は、そのファイルにローカルアドレスが含まれていないことを確認してください。
Kubernetesクラスタでのループのトラブルシューティング
KubernetesにデプロイされたCoreDNS Podがループを検出すると、CoreDNS Podは「CrashLoopBackOff」状態になります。これは、CoreDNSがループを検出して終了するたびに、KubernetesがPodを再起動しようとするためです。
Kubernetesクラスタにおける転送ループの一般的な原因は、ホストノードのローカルDNSキャッシュ(例:systemd-resolved
)との相互作用です。たとえば、特定の構成では、systemd-resolved
はループバックアドレス127.0.0.53
をネームサーバーとして/etc/resolv.conf
に配置します。Kubernetes(kubelet
経由)は、デフォルトでは、default
dnsPolicyを使用してこの/etc/resolv.conf
ファイルをすべてのPodに渡すため、DNSルックアップを実行できなくなります(CoreDNS Podも含まれます)。CoreDNSはこの/etc/resolv.conf
をアップストリームのリクエスト転送先リストとして使用します。ループバックアドレスが含まれているため、CoreDNSは最終的に自身にリクエストを転送することになります。
この問題を回避する方法はいくつかあります。いくつかを以下に示します。
kubelet
の設定yamlに次の行を追加します:resolvConf: <実際のresolv.confファイルへのパス>
(またはコマンドラインフラグ--resolv-conf
を使用、1.10では非推奨)。「実際の」resolv.conf
は、アップストリームサーバーの実際のIPアドレスが含まれており、ローカル/ループバックアドレスが含まれていないファイルです。このフラグは、kubelet
に代替resolv.conf
をPodに渡すように指示します。systemd-resolved
を使用するシステムでは、「実際の」resolv.conf
の場所は通常/run/systemd/resolve/resolv.conf
ですが、ディストリビューションによって異なる場合があります。- ホストノードのローカルDNSキャッシュを無効にし、
/etc/resolv.conf
を元に戻します。 - 簡単な解決策として、Corefileを編集し、
forward . /etc/resolv.conf
をアップストリームDNSのIPアドレス(例:forward . 8.8.8.8
)に置き換えることができます。しかし、これはCoreDNSの問題のみを解決します。kubeletは引き続き無効なresolv.conf
をすべてのdefault
dnsPolicy Podに転送し続け、DNSを解決できなくなります。