ループ

ソースコード

loop は、単純な転送ループを検出し、サーバーを停止します。

説明

loop プラグインは、自身にランダムなプローブクエリを送信し、その出現回数を追跡します。2回以上検出された場合、CoreDNSが転送ループを検出したと判断し、プロセスを停止します。

このプラグインは、最大30秒間クエリを送信しようとします。これは、CoreDNSの起動時間を確保するためです。クエリが正常に送信されると、loop はクエリ・オブ・デスを防ぐために自身を無効化します。

loop は、サーバーブロックで最初に指定されたゾーンに対してのみ「ループクエリ」を送信することに注意してください。

送信されるクエリは、タイプがHINFOに設定された<乱数>.<乱数>.zoneです。

構文

loop

デフォルトポートでサーバーを起動し、loopforward プラグインをロードします。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を解決できなくなります。