使用 DeepFlow 開啟 DNS 可觀測性

語言: CN / TW / HK

目前針對 DNS 監控的 Grafana Dashboard 並不多,使用率較高的 Grafana CoreDNS 只適用於 K8s 環境,對於雲伺服器、物理硬體模式下的 DNS 監控也並不通用;同時,對於應用研發人員想定位 DNS 查詢異常或者時延問題時,CoreDNS 的 Dashboard 僅提供 DNS 服務端視角,無法從應用視角出發來分析問題,只能依賴自身程式碼增加了 DNS 日誌。

明確這些問題後,我們基於 DeepFlow 構建了對一個高效可配置無侵入面向應用的 DNS 監控面板,可監控 DNS 服務的網路異常、吞吐、時延,以及訪問日誌,以快速定位效能瓶頸和排查故障原因。部署了 DeepFlow 之後,deepflow-agent 會自動採集所在節點上的可觀測資料,我們基於這些資料構建了一個 Dashboard,內容包括:

  • Overview
  • Delay
  • Error
  • Request
  • Log Analysis

前往我們的線上 Demo 也可快速體驗 Dashboard

同時,歡迎大家預約 “原力釋放 雲原生可觀測性分享會” 直播。

直播活動由雲原生社群主辦,雲杉網路發起,並聯合OPPO聯合舉辦,本期聚焦 “淺談可觀測性生態的優化和豐富” 主題。將分享OPPO自研時序資料庫在業務高基數、持久化儲存、亂序寫入、多租戶隔離等場景下的思考及實戰演進,以及 DeepFlow 對 Grafana 外掛做詳細解析,講解如何從零開始開發一個 Grafana 的 Datasource。

  • 直播時間:12 月 8 日 (週四) 20:00~21:00
  • 直播平臺:雲原生社群視訊號&B 站、雲杉網路視訊號、開源江湖、GrafanaFans
  • 活動連結:https://www.slidestalk.com/m/1336
  • 掃描海報二維碼預約直播

0x0: Dashboard 介紹

接下來,詳細介紹下 Dashboard 的使用

進入 Dashboard 後,可通過變數來控制需要分析的 DNS 服務端,下面詳細說下變數的使用方式:

  • ①:DNS 服務端部署在 K8s 環境中,例如 CoreDNS,使用 cluster/dns_service/dns_wildcard 變數
    • cluster:選擇 DNS 服務端所部署的 K8s 叢集
    • dns_service:選擇 DNS 服務端對應的 K8s 服務名
    • dns_wildcard:通過萬用字元的形式篩選 dns_service
  • ②:DNS 服務端部署在雲伺服器環境中,使用 dns_chost 變數
    • 特別說明:此時需要將 cluster/dns_service 設定為Disabled
  • ③:使用外部的 DNS 服務端,例如使用運營商提供的114.114.114.114,則在 dns_ip 變數輸入對應的 IP 即可
    • 特別說明:此時需要將 cluster/dns_service/dns_chost 設定為Disabled
  • ④:DeepFlow 可在多個位置採集資料,可通過 tap_side 來控制需要檢視的資料統計位置,位置點的詳細說明,可參考文件

模板變數說明模板變數說明

設定好變數後,接下來就可以利用 Dashboard 來分析 DNS 了,通過 Overview 可快速瞭解 DNS 請求總量有無異常存在應用的 DNS 訪問拓撲DNS 響應時延的整體分佈情況,得到大概總覽情況後,可以結合 ErrorDelayRequest 模組中的曲線快速分析問題發生的時間點,然後利用 client 分組,可快速得到觸發問題發生的客戶端服務

OverviewOverview

ErrorError

Delay + RequestDelay + Request

接下來可以利用 Log_Analysis 模組來詳細分析發生問題的客戶端服務的 DNS 請求,分析之前,需要先設定 client_for_Log_Analysis  status_for_Log_Analysis 變數

  • ⑤ client_for_Log_Analysis:輸入在前面模組得到的客戶端服務
  • ⑥ status_for_Log_Analysis:確定需要分析的 DNS 請求的狀態
  • ⑦ domain_for_Log_Analysis:輸入需要分析的 DNS 請求的域名

模板變數說明模板變數說明

通過 Log_Analysis 模組,可快速得到存在問題的 TOP N ClientRequest DomainRequest Type Response Desc 以及客戶端服務訪問 DNS 的整個時延分佈

Log_AnalysisLog_Analysis

接下來,讓我們結合實際案例,來體驗一下 DNS Dashboard 給我們帶來的高效分析能力。

0x1: 案例1 - 無效內部域名解析

現象

我們的叢集裡的應用規模不大,理論上 DNS 請求不會太多,但我們開啟 DNS Dashboard 後,發現有大量 DNS 查詢請求,且有訪問異常:

Client Request Log ErrorClient Request Log Error

其中有較多 DNS 客戶端異常,響應碼為 0x3,錯誤描述是:Non-Existent Domain,意味著應用訪問了不存在的域名。(更多的異常定義可見 DeepFlow-資料庫欄位定義

我們通過異常排序,檢視訪問無效 Top10 域名,發現大量 DNS 請求字尾包含了 cluster.local,而這是 k8s 自動填充的搜尋域:

Client Request Domain TopN ErrorClient Request Domain TopN Error

原因分析

我們結合 k8s 的 DNS 原理來分析問題原因。首先,一個典型的 k8s Pod 中 resolv.conf 檔案的內容如下:

1
2
3
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

這裡有三個配置,search 是域名檢索的搜尋域,nameserver 是叢集內的 DNS 服務地址,options 是自定義選項,其中 ndots=5,意味著當一個域名中包含.的數量小於 5 時,會優先解析為內部域名,並按照 search 的順序依次新增搜尋域字尾來檢索,如果它依然無法被解析,才會把這個域名當作外部域名來解析。
那為什麼 k8s 的 ndots 預設配置是 5 呢?Issue#33554 也做出瞭解釋,簡單來說:

  1. 同命名空間下,形如 $service 的域名要被優先解析為內部域名,所以 ndots>=1,並在搜尋域 $namespace.svc.$zone 下搜尋。
  2. 跨名稱空間下,形如 $service.$namespace 的域名要被優先解析為內部域名,所以 ndots>=2,並在搜尋域 svc.$zone 下搜尋。
  3. 訪問非 Service Name 時,形如 $name.$namespace.svc 的域名要被優先解析為內部域名,所以 ndots>=3,並在搜尋域 $zone 下搜尋。
  4. 對於 StatefulSet 型別的應用,由於需要支援形如 $name-0.service.$namespace.svc 的域名內部解析,所以 ndots>=4。
  5. 對於形如 _$port._$proto.$service.$namespace.svc 的 SRV Record 要被優先解析為內部域名,所以 ndots>=5。

綜上,k8s 的 resolv.conf 中 ndots 預設值是 5 。但這符合我們的使用場景嗎?我們要訪問的域名是一個.小於 5 的外部域名,但它被解析為內部域名,並嘗試通過 $url.default.svc.cluster.local / $url.svc.cluster.local / $url.cluster.local 的順序來解析,最後才去訪問 $url 本身,所以產生了大量的異常記錄。

修復建議

要解決這個問題,有幾個可選的方案:

  1. k8s 文件中 Pod DNS 配置一節,只需要修改 Pod 的 DNS 策略,定義 ndots=2,這樣就可以優先將域名解析為外部域名,弊端在於這樣反而會使得內部域名的解析變慢。
  2. 把訪問的外部域名修改為 FQDN,比如我們要訪問的是 vpc.tencentcloudapi.com,修改為 vpc.tencentcloudapi.com.,這樣可以直接訪問域名,不會依次檢索搜尋域。
  3. CoreDNS 使用 autopath 外掛,減少搜尋次數,但這依賴於 API Watch 機制,會使得 CoreDNS 增加記憶體消耗。
  4. 使用 Node LocalDNS,增加 DNS 解析效能,減少 CoreDNS 壓力,但同樣的,它需要使用記憶體來做 DNS 快取查詢,增加了記憶體消耗。

經過權衡,方案(2)對叢集的侵入性和修改難度是最低的,效果也比較理想,所以我們採用方案(2)達成了目標。

0x2: 案例2 - 對已失效服務的依賴

現象

同樣通過 DNS Request Log 分析,我們發現還有大量的 Non-Existent Domain 異常,且它不是訪問外部域名:

Client Request Domain TopNClient Request Domain TopN

原因分析

叢集裡沒有 zipkin 的 Service,按照上述的 k8s 的 DNS 原理分析,在訪問域名的時候同樣會嘗試按搜尋域順序依次訪問,造成了不小的 CoreDNS 壓力,這說明應用的配置有錯誤,嘗試訪問無效的服務,導致冗餘的開銷

修復建議

檢查程式碼或配置中是否還在訪問失效的服務,去掉配置後恢復正常。

0x3: 後續規劃

我們目前在製作一批 Dashboard,包括:Nginx、MySQL/PostgreSQL、HTTP、Dubbo/gRPC、Kafka/MQTT、TCP/UDP/IP 等,希望能帶來社群高度自動化高精度的可觀測性體驗,期待有社群的小夥伴能加入一起。

0x4: 什麼是 DeepFlow

DeepFlow 是一款開源的高度自動化的可觀測性平臺,是為雲原生應用開發者建設可觀測效能力而量身打造的全棧、全鏈路、高效能資料引擎。DeepFlow 使用 eBPF、WASM、OpenTelemetry 等新技術,創新的實現了 AutoTracing、AutoMetrics、AutoTagging、SmartEncoding 等核心機制,幫助開發者提升埋點插碼的自動化水平,降低可觀測性平臺的運維複雜度。利用 DeepFlow 的可程式設計能力和開放介面,開發者可以快速將其融入到自己的可觀測性技術棧中。

GitHub 地址:https://github.com/deepflowys/deepflow

訪問 DeepFlow Demo,體驗高度自動化的可觀測性新時代。