使用 KubeSkoop exporter 監測和定位容器網絡抖動問題

本文是 8 月 17 日直播的文字稿整理,微信公衆號「阿里云云原生」可觀看直播回放。除去文章內容外,還包括針對實際網絡問題的實戰環節。

容器網絡抖動問題發生頻率低,時間短,是網絡問題中最難定位和解決的問題之一。不僅如此,對 Kubernetes 集羣內的網絡狀態進行日常的持續性監測,也是集羣運維中很重要的一環。

KubeSkoop 基於 eBPF 技術,提供了 Pod 粒度的、低開銷的、可熱插拔的實時網絡監測能力,不僅可以滿足日常網絡監控的需要,也能夠在出現網絡問題後,通過開啓對應的探針,快速定位及解決問題。KubeSkoop 提供了基於 Prometheus 的指標和 Grafana 大盤,同時也提供了基於命令行、基於 Loki 的異常事件透出能力,提供問題現場的詳細信息。

本次分享將包括:

  • 應用如何收到/發出數據包
  • 網絡問題排查的難點,傳統網絡問題排查工具以及傳統工具的問題
  • 對 KubeSkoop 和網絡監測部分(即 KubeSkoop exporter)的簡單介紹
  • 結合內核中的不同的模塊詳細介紹 KubeSkoop exporter 的探針、指標和事件
  • 在日常監測和異常排查中使用 KubeSkoop exporter 的一般流程
  • KubeSkoop exporter 的未來規劃。

容器中的應用如何收到/發出數據包?

在網絡中,數據是以數據包爲單位進行傳輸的。在 Linux 系統上,數據包需要經過內核中各個模塊層層處理,才能夠正常地被應用接收,或是被應用發送。

我們先來看接收過程:

  • 網卡驅動收取網絡報文後,發起中斷
  • 內核 ksoftirqd 得到調度後,得到數據,進入到協議棧處理
  • 報文進入網絡層,網絡層經過 netfilter 等處理後,進入傳輸層
  • 傳輸層處理報文後,將報文的 payload 放入 socket 接收隊列中,喚醒應用進程,讓出 CPU
  • 應用進程被調度後,通過系統調用將數據收取的用戶態進行處理

再來看發送過程:

  • 應用程序通過系統調用向 socket 發送隊列寫入數據
  • 進入到內核態,socket 調用傳輸層進行報文發送
  • 傳輸層組裝報文,調用網絡層發送
  • 網絡層經過 netfilter 等處理後,進入 tc egress
  • tc qdisc 將報文按照順序調用網卡驅動進行發送

我們在入方向並沒有關注到 tc 的處理,但在出方向着重的提了一下,這也是鏈路中產生丟包異常的常見原因之一。

由上面的介紹可以看出,一個包在 Linux 內核中需要經過複雜的處理步驟。內核網絡子系統的模塊衆多,代碼量龐大且複雜,是造成網絡問題排查的難點之一;包的接收和發送經過的鏈路長,給問題定位帶來了相當的難度。同時網絡相關係統的參數繁多,配置複雜,因爲某些功能或者參數的限制導致了網絡問題,也需要我們花大量的時間去定位;同時,系統的磁盤、調度、業務代碼缺陷等,都可能表現爲網絡問題,需要對系統狀態進行全面的觀測。

常用網絡排查工具

接下來,我們再來介紹一下 Linux 環境下常見網絡問題排查工具,以及其背後的實現技術。

net-tools(netstat 等)

net-tools 所提供的工具,能夠用於查看網絡統計信息,包括網絡當前狀態、異常統計計數等

它的原理是,通過 procfs 中的 /proc/snmp 和 /proc/netstat 文件獲取當前的網絡狀態和異常計數,特點是性能好,開銷小,但是它所能提供的信息相對較少,並且不可定製。

procs 是 linux 所提供的虛擬文件系統之一。它能夠提供系統的運行信息、進程信息和計數器信息。用戶進程通過 write() 或者 read() 系統調用函數,對 procfs 所提供的文件進行訪問,如 /proc/net/netstat,或 /proc/<pid>/net/snmp 等。內核中的 procfs 實現,會將信息通過虛擬文件系統 vfs 返回用戶。

和 net-tools 工具包類似的命令還有 nstat、sar、iostat 等。

iproute2(ip、ss 等)

iproute2 工具包中的 ip、ss 工具也提供了查看網絡統計信息和網絡狀態的多種實用工具。但它的原理與 netstat 等工具不同,是基於 netlink 獲得信息的。它相比於 net-tools,能夠提供更加全面的網絡信息,和更好的擴展能力,但是性能相較於通過 procfs 會差一些。

netlink 是 Linux 中一種特殊的 socket 類型,用戶程序可以通過標準的 socket API 和內核進行通信。用戶程序通過 AF_NETLINK 類型的 socket 進行數據的發送和收取。內核中將會通過 socket 層來處理用戶的請求。

與其相似的命令還有 tc、conntrack、ipvsadm 等。

bcc-tools

bcc-tools 提供了多種的內核態觀測工具,包括網絡、磁盤、調度等方面。它的核心實現是基於 eBPF 計數,有着非常強的擴展性和不錯的性能,但是使用門檻相較於上述工具會更高一些。

eBPF 是 Linux 中比較年輕的技術,也是近期社區的熱門關注點之一。eBPF 是內核中的一個小型虛擬機,可以動態加載用戶自己編寫的代碼並在內核中運行,同時內核會幫助你校驗程序的安全性,確保不會因爲自定義的 eBPF 代碼導致內核出現工作異常。

在 eBPF 程序加載進內核後,它可以通過 map 來與用戶態的程序進行數據的交換。用戶進程可以通過用戶態的 bpf() 系統調用來獲得 map 中的數據,而 eBPF 程序也可以在內核中使用內核 API 來主動更新 map 數據,來完成內核與用戶進程之間的交流。

與 bcc-tools 中提供的工具相似的,還有 bpftrace、systemtap 等。

傳統工具在雲原生場景下的問題

上述的工具,通過 Linux 的不同能力提供了豐富的狀態信息,幫助我們排查系統中發生的網絡問題。但是,在雲原生容器的複雜場景下,傳統工具也有着一些侷限性:

  • 大部分工具以本機/網絡命名空間爲維度進行觀測,難以針對某個特定容器
  • 對於複雜拓撲的觀測,沒有充足的內核問題排查經驗,可能會難以下手
  • 對於偶發問題,很難實時抓到現場使用這些工具
  • 這些工具提供了大量的信息,但是信息之間的關聯並不明顯
  • 一些觀測工具自己本身同時也會帶來性能方面的問題

KubeSkoop

基於以上 Linux 網絡處理的複雜鏈路、傳統工具在雲原生容器場景下的缺陷。基於雲原生環境的網絡觀測要求,KubeSkoop 項目應運而生。

在介紹 KubeSkoop 的網絡監測部分,也就是 KubeSkoop exporter 之前,我們先來回顧一下 KubeSkoop 項目的全貌。

KubeSkoop 是一個容器網絡問題的自動診斷系統。它針對了網絡持續不通問題,如 DNS 解析異常,service 無法訪問等場景,提供了一鍵診斷的能力;針對網絡抖動問題,如延遲增高、偶發 reset、偶發丟包等場景,提供了實時監測的能力。KubeSkoop 提供了全鏈路一鍵診斷、網絡站延遲分析和網絡異常事件識別回溯的能力。

本次分享中,我們的重點在 KubeSkoop 的網絡監測能力部分。

KubeSkoop exporter 基於 eBPF、procfs、netlink 等多種數據源的容器網絡異常監控,提供了 Pod 級別的網絡監控能力,能夠提供網絡監控指標、網絡異常事件記錄和實時事件流,覆蓋驅動、netfilter、TCP 等完整協議棧和幾十種異常場景,與雲上 Prometheus、Loki 等可觀測體系對接。

KubeSkoop exporter 提供了針對內核中不同位置採集信息的探針,支持探針的熱插拔和按需加載的能力。開啓的探針會以 Prometheus 指標或是異常事件的形式透出所採集到的統計信息或網絡異常。

探針、指標和事件

針對內核中的不同模塊,KubeSkoop exporter 提供了多種探針,適用於不同的觀測需求和不同的網絡問題場景。

指標(metrics)是對網絡中關鍵信息,以 Pod 維度彙總的統計數據,如連接數、重傳數等。這些信息能夠爲用戶提供網絡狀態隨時間的變化信息,能夠更好的幫助用戶理解目前容器中的網絡狀況。

事件會在網絡異常發生的時候產生,如丟包、TCP reset、數據處理出現延遲等。相比於指標,事件能夠提供更多有關於問題現場的信息,如出現丟包的具體位置、出現延遲的詳細統計等。事件更多用來針對某一個具體的網絡異常,來進行更加深入的觀測和問題定位。

探針列表

下面將會介紹目前 KubeSkoop 所提供的探針,說明作用、適用場景、開銷以及它所提供的指標/事件。

關於探針、指標和事件的說明,也可以訪問 KubeSkoop 文檔 https://kubeskoop.io 獲取更多信息。

socketlatency

socketlatency 探針通過追蹤內核內 socket 相關以及上下游的符號,獲得用戶態從 socket 數據準備好到讀取數據,以及 socket 接收到數據,到傳遞到 TCP 層進行處理的延遲情況。該探針一般主要關注在數據到達 socket 層時,用戶態數據讀取的延遲情況。探針提供了 socket 讀取/寫入延遲的相關指標以及事件。

開銷:

適用場景:懷疑進程由於調度、處理不及時等原因,讀取數據慢的情況

常見問題:由於容器進程 CPU 超限導致的網絡抖動

sock

sock 探針的數據來源於 /proc/net/sockstat 文件,提供了 Pod 內部對於 socket 的統計指標,採集了 TCP 處於不同狀態 (inuse、orphan、tw) 的 socket 數量,以及內存的使用情況。可能由於應用邏輯、系統參數配置等問題,導致 socket、tcpmem 耗盡等情況,產生連接失敗的情況,影響併發性能。該探針開銷極小,因此也可以做爲日常狀態中連接大體狀態的觀測。

開銷:

適用場景:日常觀測連接狀態,socket 泄漏、reuse、socket 內存佔用過高等情況

常見問題:由於 socket 泄漏導致的內存佔用持續增長;連接過多、reuse、tcpmem 耗盡等導致的建連失敗/偶發RST情況

tcp/udp/tcpext

通過 /proc/net/netstat 和 /proc/net/snmp 兩個文件採集的關於 TCP/UDP 協議層的基礎信息採集,如 TCP 新建連接/成功建立連接的數量,重傳報文數,UDP 協議錯誤計數等。tcpext 同時也提供了 TCP 更加細粒度的指標,如發送 RST 報文的統計等。該指針在 TCP/UDP 連接相關的異常問題中(如負載不均、連接建立失敗、異常連接關閉)等提供關鍵信息,同時作爲基於 procfs 採集信息的探針,可以用於日常對流量狀態的觀測。

開銷:

適用場景:日常對 TCP 和 UDP 相關狀態的觀測。出現 TCP 連接異常重傳、連接建立失敗、reset 報文等情況的信息採集,出現 DNS 解析失敗等情況的信息採集

常見問題:應用連接出現異常關閉;由於重傳導致的延時抖動

tcpsummary

tcpsummary 探針通過與內核進行 netlink 消息 (SOCK_DIAG_BY_FAMILY) 的通信,獲取到 Pod 內的所有 TCP 連接信息,並聚合 TCP 連接狀態和發送/接受隊列狀態產生指標。該探針需要聚合所有連接信息得到最終統計結果,因此在連接較多的高併發場景下,可能會帶來較大的開銷。

開銷:

適用場景:偶發延遲、連接失敗等場景下提供 TCP 連接的狀態信息

常見問題:用戶態進程hang住,接收隊列堆積導致的丟包

tcpreset

tcpreset 探針通過在內核中追蹤 tcp_v4_send_reset 和 tcp_send_active_reset 的調用,在 TCP 連接中發送 RST 報文時,記錄 socket 信息和狀態,產生事件。在 tcp_receive_reset 被調用,即收到 RST 報文時,也會記錄以上信息。探針基於內核中冷路徑的追蹤,因此開銷較低。該探針只產生事件,建議在出現 tcp reset 問題時再開啓。

開銷:

適用場景:TCP 連接被異常 reset 時,追蹤內核中的 reset 位置

常見問題:由於客戶端與服務端兩端超時時間設置問題,導致的偶發連接 reset

ip

ip 探針是從 /proc/net/snmp 文件中採集到的 IP 相關的信息指標。包括由於路由目的地址不可達以及數據包長度小於 IP 頭中表示長度兩種情況的計數器,能夠對由於上述兩種原因出現丟包的情況做出判斷。探針開銷極小,也建議在日常監測場景下打開該探針。

開銷:

適用場景:日常對 IP 相關狀態的觀測。出現丟包等問題時

常見問題:由於節點上路由設置不正確,目的不可達導致的丟包

kernellatency

kernellatency 對報文接收和報文發送全過程的多個關鍵點進行時間記錄,計算報文在內核中的處理延遲。指針提供了接收和發送數據包處理出現延遲的指標,同時也提供了事件,包括了報文五元組和內核中各個點位之間的處理時間。本探針涉及所有報文的時間統計和大量的 map 查詢操作,開銷較高,因此建議僅在相關問題發生時啓用該探針。

開銷:

適用場景:連接超時,網絡抖動問題

常見問題:由於 iptables 規則過多導致的內核處理延遲高

ipvs

ipvs 探針採集了 /proc/net/ip_vs_stats 文件中的信息,提供了 IPVS 相關的統計計數。IPVS 是內核提供的 4 層負載均衡能力,在 kube-proxy 的 IPVS 模式中被使用。探針提供的指標主要包括 IPVS 的連接數、出/如數據包數和出/入數據字節數。該探針適用於日常監測中對 IPVS 統計信息的觀測,也對訪問 service IP 出現網絡抖動或連接建立失敗等情況起輔助參考作用。

開銷:

適用場景:日常對 IPVS 相關狀態的觀測

常見問題:

conntrack

conntrack 探針通過 netlink,提供用於追蹤 conntrack 模塊的統計數據。conntrack 模塊是基於內核提供的 netfilter 框架,對網絡層以上的數據流量進行連接追蹤,包括每條連接的創建時間,報文數,字節數等數據,並提供根據信息的匹配進行 nat 等上層操作的機制。探針的指標中提供了當前 conntrack 中處於各個狀態的條目的統計計數,以及 conntrack 當前條目和條目上限的數量。由於探針需要遍歷所有 conntrack 條目,因此在高併發場景下會有較大開銷。

開銷:

適用場景:連接建立失敗、丟包,conntrack 串流等問題

常見問題:由於 conntrack 溢出導致的連接建立失敗、丟包

netdev

netdev 探針通過採集 /proc/net/dev 文件,提供了網絡設備層面的統計指標,包括髮送/接收字節數、錯誤數、數據包數、丟包數。探針通常用於宏觀的發現網絡問題,在偶發 TCP 握手失敗等場景有價值。探針開銷極小,建議日常開啓。

開銷:

適用場景:日常監控。網絡抖動,設備底層丟包等情況

常見問題:網絡設備丟包導致的網絡抖動或建連失敗

qdisc

qdisc 探針通過 netlink,提供了 tc qidsc 的統計指標,包括 qdisc 上的經過的流量統計,以及 qdisc 隊列狀態的統計計數。tc qdisc 是 LInux 內核中用於對網絡設備進行流量控制的模塊,qdisc 會根據調度規則控制數據包的發送。網卡上的 qdisc 規則可能會導致數據包被丟棄,或是延遲高情況發生。探針開銷較低,建議日常開啓。

開銷:

適用場景:日常監控。網絡抖動丟包等情況

常見問題:由於 qdisc 隊列超限導致丟包,產生網絡抖動

netiftxlatency

對內核中網絡設備處理部分的關鍵點位進行追蹤並計算延遲,主要集中在 qdisc 對報文的處理時間,以及底層設備對外發送的時間,提供了兩部分延遲超過一定閾值的報文數量統計,以及包含報文五元組信息的異常事件。探針會對所有報文進行延遲的計算,因此開銷較高,建議出現延遲問題時再開啓。

開銷:

適用場景:連接超時,網絡抖動等情況

常見問題:底層網絡抖動導致延遲升高

softnet

softnet 探針的數據來源於內核的 proc 文件接口 /proc/net/softnet_stat,以 Pod 級別進行指標的聚合。softnet 探針按照 cpu 的方式對網卡收取的數據包進行整合,他表徵着數據包從網卡設備進入 Linux 內核的軟中斷處理過程的狀態,對外提供了接收和處理數據包的總覽數據。探針對出現愛你節點級別的網絡問題時能夠起到輔助作用,開銷極小,建議開啓。

開銷:

適用場景:日常監控。出現節點級別的網絡問題時能夠提供幫助

常見問題:

net_softirq

net_softirq 探針通過內核態程序,採集了與網絡相關的兩種中斷 (netif_tx、netif_rx) 的調度和執行時長,包括軟中斷髮起到開始執行,和軟中斷開始執行到執行完成的耗時,並將超過一定閾值的報文以指標或者事件的形式進行統計透出。

開銷:

適用場景:出現偶發延遲,網絡抖動常見問題:cpu 爭搶導致的軟中斷調度延遲,產生網絡抖動

virtcmdlatency

virtcmdlat 探針通過對內核態調用虛擬化指定的方法 (virtnet_send_command) 的執行時間進行計算,來獲取虛擬機執行虛擬化調用的耗時,提供了出現延遲次數的指標和事件。virtio 是比較常見的虛擬化網絡方案,由於其半虛擬化的特性,虛擬機對網卡設備驅動的操作可能會因爲底層物理機的阻塞而產生延遲。探針開銷較高,建議懷疑因宿主機原因出現網絡抖動時再將其開啓。

開銷:

適用場景:出現偶發延遲,網絡抖動

常見問題:底層物理機資源爭搶導致的網絡抖動

fd

fd 探針通過對單個 Pod 內所有進程持有的句柄進行採集,獲取 Pod 中進程打開的文件描述符及 socket 類型的文件描述符的數量。探針需要遍歷進程的所有 fd,開銷較高。

開銷:

適用場景:fd 泄漏,socket 泄漏等問題

常見問題:socket 未被用戶態程序關閉,產生泄漏導致 TCP OOM,進而導致網絡抖動

io

io 探針的數據來源於 /proc/io 提供的文件接口,用於表徵單個 Pod 進行文件系統io的速率與總量。探針提供的指標包括文件系統讀寫操作的次數以及字節數。部分網絡問題可能是由於同節點上其它進行進行大量 IO,導致用戶進程響應慢產生的,在這種情況下,可以按需開啓該探針以進行驗證,也可以用於日常對 Pod IO 的監測。

開銷:

適用場景:由於用戶進程響應慢導致的延遲增長,重傳升高

常見問題:大量文件讀寫導致的網絡抖動問題

biolatency

biolatency 追蹤了內核中塊設備讀取和寫入調用的執行時間,並將超過閾值的執行以異常事件的形式透出。設備 IO 延遲增加,可能會導致用戶進程的業務處理受到影響,進而產生網絡抖動問題,在懷疑因爲 IO 產生網絡異常時,可以開啓此探針。探針需要對所有塊設備的讀寫操作進行統計,開銷中等,建議按需開啓。

開銷:

適用場景:IO 讀寫慢導致的網絡抖動、延遲升高等

常見問題:由於塊設備讀寫延遲產生的網絡抖動

如何使用 KubeSkoop exporter

KubeSkoop exporter 適用於日常監控以及網絡異常問題發生時的排查兩種場景。這兩種場景對 KubeSkoop exporter 的使用方式有所不同,下面講簡單介紹。

日常監控

在日常監控中,推薦使用 Prometheus 收集 KubeSkoop exporter 所透出的指標,以及可選的通過 Loki 來收集異常事件的日誌。收集到的指標和日誌,可以透過 Grafana 大盤進行展示。KubeSkoo exporter 也提供了現成的 Grafana 大盤,可以直接使用。

在配置好指標收集和大盤後,還需要對 KubeSkoop exporter 本身進行一些配置。我們在日常的監控中,爲了對業務的流量造成影響,我們可以選擇性開啓一些低開銷的探針,如基於 porcfs 的大部分探針,和部分基於 netlink、eBPF 的低開銷探針。如果使用了 Loki,還需要同時配置 Loki 的服務地址,並且將其啓用。在這些準備工作結束之後,我們就可以在大盤上看到所啓用的指標和事件情況。

在日常的監控之中,需要關注一些敏感的指標的異常。比如說新建連接數的異常突增,或者是連接建立失敗數上漲,reset 報文增加等。針對這些明顯能夠代表異常的指標,我們也可以通過配置告警的形式,能夠在出現異常時,更快的介入去進行問題的排查和恢復。

異常問題排查

當我們通過日常監控、業務告警、錯誤日誌等方面發現可能存在網絡異常後,需要先對網絡異常問題的類型進行一個簡單的歸類,如 TCP 建連失敗、網絡延遲抖動等。通過簡單的歸類,能夠更好的幫助我們確立問題的排查方向。

根據問題類型不同,我們就可以根據問題類型,開啓適用於該問題的探針。比如出現了網絡延遲抖動的問題,我們就可以開啓 socketlatency 關注應用從 socket 讀數據延遲的情況,或是開啓 kernellatency 追蹤內核中延遲的情況。

開啓這些探針後,我們就可以通過已經配置好的 Grafana 來觀測探針暴露出的指標或是事件結果。同時,異常事件也可以直接通過 Pod 日誌,或是 exporter 容器中的 inspector 命令來直接觀測。如果我們這次開啓的探針結果沒有異常,或是無法針對問題根因做出結論,可以考慮開啓其它方面的探針,繼續輔助我們進行問題的定位。

根據這些所得到的指標和異常事件,我們最終會定位到問題的根因。問題的根因可能出自系統中的某一些參數的調整,或者是出現在用戶的程序之中。我們根據定位到的根因就可以進行這些系統參數調整或者是程序代碼的優化了。

未來規劃

KubeSkoop 已於上週發佈第一個正式版本 0.1.0,主要改進點包括:

診斷

  • 支持 k3s 集羣
  • 支持節點 host interface 自動選擇
  • 修復若干診斷錯誤

網絡監測

  • 支持大部分主流操作系統的 btf 自動發現
  • 優化 exporter 性能,CPU 開銷大幅下降
  • 支持探針的熱加載
  • 初步支持 flow 級別指標採集

以下是我們近幾個月的開發規劃,包括:

  • KubeSkoop exporter 代碼重構,增強擴展性與穩定性
  • 全面支持 flow 級別的 metrics 展示,快速定位問題連接
  • 支持事件透出到本地文件 /ELK 等
  • 更加友好的 UI,支持集羣內流量拓撲全覽

結語

本次分享是對 KubeSkoop 項目的網絡監測能力的重點介紹,主要介紹了 KubeSkoop exporter 所擁有的指標,以及日常使用和排查問題的一般方法,能夠幫助您更好的使用本項目,對網絡進行觀測和問題排查。

相關鏈接:

[1] Github 項目主頁

https://github.com/alibaba/kubeskoop

作者: 遐宇、溪恆

點擊立即免費試用雲產品 開啓雲上實踐之旅!

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章