迴圈

原始碼

loop 外掛程式會偵測簡單的轉發迴圈並停止伺服器。

說明

loop 外掛程式會發送一個隨機探測查詢給自己,然後追蹤我們看到它的次數。如果我們看到它超過兩次,我們就假設 CoreDNS 遇到了轉發迴圈,並停止程序。

此外掛程式會嘗試發送查詢最多 30 秒。這樣做的目的是給 CoreDNS 足夠的時間啟動。一旦成功發送查詢,loop 就會停用自身,以防止發生死亡查詢。

請注意,loop 只會針對伺服器區塊中給出的第一個區域發送「迴圈查詢」。

發送的查詢是 <隨機數字>.<隨機數字>.zone,類型設定為 HINFO。

語法

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.dev.org.tw/plugins/loop#troubleshooting. Query: "HINFO 4547991504243258144.3688648895315093531."

限制

此外掛程式僅嘗試在啟動時找到簡單的靜態轉發迴圈。若要偵測迴圈,必須滿足以下條件:

  • 迴圈必須在啟動時存在。

  • 迴圈必須針對 HINFO 查詢類型發生。

疑難排解

當 CoreDNS 的記錄包含訊息 Loop ... detected ... 時,表示 loop 偵測外掛程式已偵測到其中一個上游 DNS 伺服器中存在無限轉發迴圈。這是一個致命的錯誤,因為在無限迴圈中運作會消耗記憶體和 CPU,直到主機最終記憶體不足而死亡。

轉發迴圈通常是由以下原因造成的:

  • 最常見的情況是,CoreDNS 將請求直接轉發給自己。例如,透過迴路位址,如 127.0.0.1::1127.0.0.53
  • 較不常見的情況是,CoreDNS 轉發到一個上游伺服器,而該伺服器又將請求轉發回 CoreDNS。

若要排除此問題,請在您的 Corefile 中尋找任何轉發到偵測到迴圈的區域的 forward。請確保它們沒有轉發到本機位址或另一個將請求轉發回 CoreDNS 的 DNS 伺服器。如果 forward 使用檔案 (例如 /etc/resolv.conf),請確保該檔案不包含本機位址。

Kubernetes 叢集中的迴圈疑難排解

當部署在 Kubernetes 中的 CoreDNS Pod 偵測到迴圈時,CoreDNS Pod 會開始「CrashLoopBackOff」。這是因為 Kubernetes 會在每次 CoreDNS 偵測到迴圈並退出時嘗試重新啟動 Pod。

Kubernetes 叢集中轉發迴圈的常見原因是在主機節點上與本機 DNS 快取 (例如 systemd-resolved) 的互動。例如,在某些配置中,systemd-resolved 會將迴路位址 127.0.0.53 作為名稱伺服器放入 /etc/resolv.conf。Kubernetes (透過 kubelet) 預設會將此 /etc/resolv.conf 檔案傳遞給所有使用 default dnsPolicy 的 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 的系統,/run/systemd/resolve/resolv.conf 通常是「實際」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。