了解 DNS

Istio 以不同的方式與 DNS 互動,這可能會讓人感到困惑。本文深入探討 Istio 和 DNS 如何協同運作。

請求的生命週期

在這些範例中,我們將逐步說明當應用程式執行 curl example.com 時會發生什麼事。雖然此處使用 curl,但同樣適用於幾乎所有用戶端。

當您將請求傳送至網域時,用戶端將執行 DNS 解析,以將其解析為 IP 位址。無論任何 Istio 設定如何,都會發生這種情況,因為 Istio 只會攔截網路流量;它無法變更應用程式的行為或傳送 DNS 請求的決策。在下面的範例中,example.com 解析為 192.0.2.0

$ curl example.com -v
*   Trying 192.0.2.0:80...

接下來,請求將被 Istio 攔截。此時,Istio 將看到主機名稱(來自 Host: example.com 標頭)和目的地位址(192.0.2.0:80)。Istio 使用此資訊來判斷預期的目的地。了解流量路由深入探討了此行為如何運作。

如果用戶端無法解析 DNS 請求,則請求會在 Istio 接收之前終止。這表示如果將請求傳送至 Istio 已知的 (例如,透過 ServiceEntry) 但 DNS 伺服器不知道的主機名稱,則請求將會失敗。Istio DNS 代理可以變更此行為。

一旦 Istio 識別了目標目的地,它必須選擇要傳送到的位址。由於 Istio 先進的負載平衡功能,這通常不是用戶端傳送的原始 IP 位址。根據服務配置,Istio 有幾種不同的方式來實現這一點。

  • 使用用戶端的原始 IP 位址(在上面的範例中為 192.0.2.0)。對於類型為 resolution: NONE(預設值)的 ServiceEntry無頭 Services,情況就是如此。
  • 在一組靜態 IP 位址上進行負載平衡。對於類型為 resolution: STATICServiceEntry,將使用所有 spec.endpoints,或者對於標準 Services,將使用所有 Endpoints,情況就是如此。
  • 定期使用 DNS 解析位址,並在所有結果之間進行負載平衡。對於類型為 resolution: DNSServiceEntry,情況就是如此。

請注意,在所有情況下,Istio 代理中的 DNS 解析與使用者應用程式中的 DNS 解析是正交的。即使用戶端進行 DNS 解析,代理也可能會忽略解析的 IP 位址,並使用自己的位址,這可能是來自靜態 IP 清單或通過執行自己的 DNS 解析(可能是相同的 hostname 或不同的 hostname)獲得的。

Proxy DNS 解析

與大多數用戶端在請求時按需執行 DNS 請求(然後通常會快取結果)不同,Istio 代理絕不會執行同步 DNS 請求。當配置 resolution: DNS 類型的 ServiceEntry 時,代理會定期解析配置的主機名稱,並將這些主機名稱用於所有請求。此間隔由 DNS 回應的TTL決定。即使代理從未向這些應用程式傳送任何請求,也會發生這種情況。

對於具有許多代理或許多 resolution: DNS 類型的 ServiceEntries 的網格,尤其是在使用低 TTL 時,這可能會導致 DNS 伺服器上的高負載。在這些情況下,以下方法可以幫助減少負載

  • 切換到 resolution: NONE 以完全避免代理 DNS 查詢。這適用於許多使用案例。
  • 如果您控制要解析的網域,請增加其 TTL。
  • 如果您的 ServiceEntry 只需要少數工作負載,請使用 exportToSidecar 限制其範圍。

DNS 代理

Istio 提供代理 DNS 請求的功能。這允許 Istio 捕獲用戶端傳送的 DNS 請求並直接返回回應。這可以改善 DNS 延遲、減少負載,並允許解析 ServiceEntries,否則 kube-dns 不會知道這些 ServiceEntries

請注意,此代理僅適用於用戶端應用程式傳送的 DNS 請求;當使用 resolution: DNS 類型的 ServiceEntries 時,代理對 Istio 代理的 DNS 解析沒有任何影響。

這個資訊有用嗎?
您有任何改進建議嗎?

感謝您的回饋!