全部產品
Search
文件中心

Container Service for Kubernetes:使用ACK Net Exporter定位網路問題

更新時間:Jul 18, 2024

ACK Net Exporter是部署在叢集內部的網路可觀測性增強組件,能夠提供容器網路相關的詳盡監控資料,協助您快速發現和定位網路問題。本文介紹Kubernetes使用ACK Net Exporter的最佳實務,協助您快速上手並解決實際問題。

前提條件

已建立ACK託管版叢集。詳細資料,請參見建立ACK託管叢集

背景資訊

ACK Net Exporter通過守護進程Pod的方式運行在節點上,藉助eBPF技術,採集節點的資訊並彙總到具體的Pod中,提供標準化的介面,實現對網路高階資訊的觀測。ACK Net Exporter的核心架構如下圖所示。

安裝與配置ACK Net Exporter組件

安裝ACK Net Exporter組件

  1. 登入Container Service管理主控台,在左側導覽列選擇市場 > 應用市場

  2. 應用市場頁面搜尋ack-net-exporter,然後單擊搜尋到的組件。

  3. ack-net-exporter組件頁面右上方單擊一鍵部署

  4. 基本資料設定精靈中選擇需要部署組件的叢集命名空間,然後單擊下一步

  5. 參數配置設定精靈中設定參數,然後單擊確定

    參數

    描述

    預設值

    name

    ACK Net Exporter組件的名稱。

    ack-net-exporter-default

    namespace

    ACK Net Exporter組件的命名空間。

    kube-system

    config.enableEventServer

    是否開啟事件追蹤服務。取值:

    • false:不開啟事件追蹤服務。

    • true:開啟事件追蹤服務。

    false

    config.enableMetricServer

    是否開啟指標採集服務。取值:

    • false:不開啟指標採集服務。

    • true:開啟指標採集服務。

    true

    config.remoteLokiAddress

    推送事件的遠端Grafana Loki服務地址

    預設為空白。

    config.metricLabelVerbose

    是否開啟指標的詳情功能。取值:

    • false:不開啟指標的詳情功能。

    • true:開啟指標的詳情功能。開啟後會額外將Pod的IP以及重要的標籤資訊作為指標的標籤資訊。

    false

    config.metricServerPort

    指標服務的連接埠,提供HTTP服務。

    9102

    config.eventServerPort

    事件服務的連接埠,提供GRPC Stream的事件流服務。

    19102

    config.metricProbes

    需要開啟的指標探針。詳細資料,請參見下文ACK Net Exporter指標列表

    預設為空白,不配置任何指標探針的情況下,會預設啟動必需探針。

    config.eventProbes

    需要開啟的事件探針。詳細資料,請參見下文ACK Net Exporter事件詳解

    預設為空白,不配置任何指標探針的情況下,會預設啟動必需探針。

配置ACK Net Exporter組件

  • 您可以執行如下命令,通過ConfigMap方式配置ACK Net Exporter組件。

    kubectl edit cm inspector-config -n kube-system
  • 您也可以通過控制台配置ACK Net Exporter組件。

    1. 登入Container Service管理主控台,在左側導覽列單擊叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇組態管理 > 配置項

    3. 配置項頁面,設定命名空間kube-system,然後搜尋kubeskoop-config,單擊kubeskoop-config右側操作列下的編輯

    4. 編輯面板配置參數,然後單擊確定

      ACK Net Exporter支援的配置項及其含義如下:

      參數

      描述

      預設值

      debugmode

      是否開啟偵錯模式。取值:

      • false:不開啟偵錯模式。

      • true:開啟偵錯模式。開啟後,支援DEBUG層級的日誌,調試介面,Go pprof和gops診斷工具。

      false

      event_config.loki_enable

      是否開啟事件向遠端Grafana Loki服務推送的功能。詳細資料,請參見下文使用Grafana Loki收集監控事件並可視化。取值:

      • false:不開啟事件向遠端Grafana Loki服務推送的功能。

      • true:開啟事件向遠端Grafana Loki服務推送的功能。

      false

      event_config.loki_address

      遠端Grafana Loki服務的地址,預設會自動探索相同命名空間下的名為grafana-loki的服務。

      預設為空白。

      event_config.probes

      需要開啟的事件探針。詳細資料,請參見下文ACK Net Exporter事件詳解

      預設為空白,不配置任何指標探針的情況下,會預設啟動必需探針。

      event_config.port

      事件服務的連接埠,提供GRPC Stream的事件流服務。

      19102

      metric_config.verbose

      是否開啟指標的詳情功能。取值:

      • false:不開啟指標的詳情功能。

      • true:開啟指標的詳情功能。開啟後會額外將Pod的IP以及重要的標籤資訊作為指標的標籤資訊。

      false

      metric_config.port

      指標服務的連接埠,提供HTTP服務。

      9102

      metric_config.probes

      需要開啟的指標探針。詳細資料,請參見下文ACK Net Exporter指標列表

      預設為空白,不配置任何指標探針的情況下,會預設啟動必需探針。

      metric_config.interval

      指標採集的事件間隔。由於指標採集存在一定效能損耗,因此ACK Net Exporter會定期採集後緩衝在記憶體中。

      5

在v0.2.3版本及更新版本的ACK Net Exporter中,已經支援了配置的熱更新,如果您使用較早期的版本,在修改配置之後需要觸發ACK Net Exporter所有容器的重建來使配置變更生效。

ACK Net Exporter使用說明

在Alinux以外的作業系統上使用ACK Net Exporter

ACK Net Exporter的部分核心功能依賴於eBPF程式進行採集。為了滿足使用不同作業系統核心的需求,ACK Net Exporter採用CO-RE的方式實現eBPF程式的分發。在啟動過程中,依賴於與作業系統核心關聯的BTF檔案(作業系統核心的調試資訊中繼資料的檔案)進行載入。如果沒有適配的BTF檔案,這部分功能將不可用。在高版本的作業系統中,一般都會內建BTF檔案的支援。關於作業系統的更多資訊,請參見BPF Type Format

目前我們為在Alinux2和Alinux3節點上啟動並執行ACK Net Exporter提供了適配服務。該功能需要滿足以下條件:

  • 作業系統核心為4.10以上版本。

  • 至少安裝了以下任意一項檔案。

    • 已安裝對應的kernel-debuginfo檔案(核心調試資訊的資料檔案)。

    • 具有攜帶debug資訊的vmlinux檔案(作業系統核心編譯後且未經過壓縮的原始檔案)。

    • 已安裝作業系統提供的對應的BTF檔案。

  • 更新ACK Net Exporter為0.2.9或以上版本,並在安裝時將config.enableLegacyVersion設定為false

在符合上述條件的情況下,您可以按照以下步驟使用ACK Net Exporter提供的進階功能:

  1. 將具備BTF資訊的檔案放在節點的/boot/路徑下。

    • 如果您安裝了完整的vmlinux檔案,您可以將vmlinux檔案放置到作業系統的/boot/路徑中。

    • 如果您安裝了kernel-debuginfo包,在安裝了kernel-debuginfo包之後,您可以在節點上/usr/lib/debug/lib/modules/路徑中根據對應的核心版本尋找到帶有調試資訊的vmlinux檔案,然後將其複製到/boot/路徑中。

  2. 執行以下命令,驗證是否已經具備有效BTF資訊和是否支援ACK Net Exporter的運行。

    # 您可以使用docker/podman/ctr等類似命令運行測試
    nerdctl run -it -v /boot:/boot registry.cn-hangzhou.aliyuncs.com/acs/btfhack:latest  -- btfhack discover

    如果以上測試命令成功輸出了您準備好的BTF資訊檔路徑,則已經完成了配置,您可以觸發ACK Net Exporter的重建,等待一段時間後即可查看到更多指標和事件。

ACK Net Exporter的監控指標及格式

ACK Net Exporter提供適配Prometheus格式的監控資料,在安裝完ACK Net Exporter後,您可以通過訪問任意一個ACK Net Exporter的Pod執行個體的服務連接埠擷取到全部的指標資訊:

  1. 如果您通過應用市場安裝了ACK Net Exporter,可執行如下命令擷取到所有ACK Net Exporter執行個體。

    kubectl get pod -l app=net-exporter -n kube-system -o wide

    預期輸出:

    NAME      READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE       READINESS GATES  
    anp-***   1/1     Running   0          32s   10.1.XX.XX   cn-***     <none>               <none>
  2. 執行如下命令,擷取指標資訊,需要將命令中的10.1.XX.XX替換為上一步中擷取到的ACK Net Exporter執行個體的地址。

    curl http://<10.1.XX.XX>:9102/metrics

ACK Net Exporter提供的監控指標資料格式如下:

inspector_pod_udprcvbuferrors{namespace="elastic-system",netns="ns402653****",node="iZbp179u0bgzhofjupc****",pod="elastic-operator-0"} 0 1654487977826

不同欄位代表的含義如下:

  • inspector_pod_udprcvbuferrors表示這是一個由ACK Net Exporter提供的指標,它的作用範圍是Pod(指標作用範圍包含Pod與Node,代表指標表徵的資料是Pod或者Node層級有效),它的名稱是udprcvbuferrors,表示單個Pod內出現的UDP報文因為收包隊列滿而導致的錯誤。

  • namespacepodnodenetns均為指標可用的Label,您可以使用PromQL對指標的Label進行過濾。其中namespacepod與Kubernetes中的含義一致,node是您的節點的主機名稱,一般預設為/etc/hostname檔案中儲存的主機名稱,netns是某個Pod的容器所在的Linux網路命名空間的ID,用於標記單個容器獨立的網路空間。

  • 指標後方的01654487977826分別代表指標的有效資料和指標產生的時間,時間是UNIX時間戳記的格式。

ACK Net Exporter的監控事件及格式

ACK Net Exporter支援採集節點上發生的網路相關的例外狀況事件。根據長期處理網路問題中的經驗,我們歸納了幾種常見的網路疑難問題。這些問題往往在叢集中難以無法複現,以偶然發生的方式幹擾正常的業務,缺乏有效定位手段,其中部分如下:

  • 網路資料報文被丟棄引發的串連失敗,響應逾時等問題。

  • 網路資料處理耗時久引發的偶發效能問題。

  • TCP、conntrack等狀態機器制異常引發的業務異常問題。

針對無法快速複現和難以擷取現場的網路問題,ACK Net Exporter提供了基於eBPF的作業系統核心上下文觀測能力。在問題發生的現場捕獲作業系統的即時狀態,並輸出事件記錄。關於ACK Net Exporter支援的事件和相關的探針資訊,請參見ACK Net Exporter事件詳解

在事件記錄的資訊中,可以查看到事件現場的相關資訊.。以tcp_reset探針為例,當出現Pod收到了一個訪問未知連接埠的正常報文時,ACK Net Exporter會捕獲以下事件資訊。

type=TCPRESET_NOSOCK pod=storage-monitor-5775dfdc77-fj767 namespace=kube-system protocol=TCP saddr=100.103.42.233 sport=443 daddr=10.1.17.188 dport=33488
  • type=TCPRESET_NOSOCK:出現了一次TCPRESET_NOSOCK類型的事件。這屬於tcpreset探針捕獲的一種事件,表明有訪問未知連接埠的報文被本地發送RST報文拒絕,拒絕的原因是沒有根據報文找到相應的Socket。通常在NAT失效後會發生這個事件,例如IPVS定時器逾時等原因發生後。

  • pod/namespace:ACK Net Exporter根據發送報文的網路命名空間,系統在匹配IP地址和網路裝置序號後關聯給事件的Pod元資訊。

  • saddr/sport/daddr/dport:ACK Net Exporter在核心擷取到的異常報文的資訊。隨著事件的不同擷取的異常報文資訊也會有差異,例如net_softirq探針的事件資訊中沒有IP地址,取而代之的是中斷髮生的CPU序號,產生的延遲時間長度等。

對於需要有效作業系統核心堆棧資訊的事件,ACK Net Exporter會捕獲事件發生時在作業系統核心中的堆棧上下文資訊。例如以下事件資訊。

type=PACKETLOSS pod=hostNetwork namespace=hostNetwork protocol=TCP saddr=10.1.17.172 sport=6443 daddr=10.1.17.176 dport=43018  stacktrace:skb_release_data+0xA3 __kfree_skb+0xE tcp_recvmsg+0x61D inet_recvmsg+0x58 sock_read_iter+0x92 new_sync_read+0xE8 vfs_read+0x89 ksys_read+0x5A

ACK Net Exporter支援多種事件查看方式,詳細介紹,請參見下文的從ACK Net Exporter收集監控資料。

從ACK Net Exporter收集監控資料

情境一:使用Prometheus或Grafana收集監控資料並可視化

ACK Net Exporter支援輸出到Prometheus Server執行個體,如果您使用自行搭建的Prometheus Server,您可以通過添加一組scrape_config的方式來使您的Prometheus Server執行個體主動抓取ACK Net Exporter的資料,類似如下配置:

# 只包含一個要抓取的端點的抓取配置。
scrape_configs:
# "net-exporter_sample"將作為“job=<job_name>”標籤添加到從此配置中抓取的任何時間序列中。
- job_name: "net-exporter_sample"
static_configs:
  - targets: ["{kubernetes pod ip}:9102"]
                

如果您的Prometheus Server執行個體運行在ACK叢集中,您也可以通過Prometheus服務發現功能自動擷取到所有正常提供服務的ACK Net Exporter執行個體,您可以通過在Prometheus Server的配置中添加以下內容:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-server-conf
  labels:
    name: prometheus-server-conf
  namespace: kube-system
data:
  prometheus.yml: |-
          # 將以下內容添加到Promethes Server配置中。
      - job_name: 'net-exporter'
        kubernetes_sd_configs:
          - role: endpoints
        relabel_configs:
        - source_labels: [__meta_kubernetes_endpoints_name]
          regex: 'net-exporter'
          action: keep

      - job_name: 'kubernetes-pods'

        kubernetes_sd_configs:
        - role: pod

        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          regex: ([^:]+)(?::\d+)?;(\d+)
          replacement: $1:$2
          target_label: __address__
        - action: labelmap
          regex: __meta_kubernetes_pod_label_(.+)
        - source_labels: [__meta_kubernetes_namespace]
          action: replace
          target_label: kubernetes_namespace
        - source_labels: [__meta_kubernetes_pod_name]
          action: replace
          target_label: kubernetes_pod_name

添加完成後,可以在Prometheus Server的Status > Targets介面看到已經生效的ACK Net Exporter執行個體,或者在Prometheus Server的Graph介面的搜尋欄中輸入inspector,即可看到自動補全的ACK Net Exporter指標。

inspector2

您可以通過配置Grafana將Prometheus採集到的資料進行可視化操作:

  1. 開啟Grafana頁面,在左側導覽列中選擇5 > Dashboard

  2. New dashboard頁面單擊Add an empty panel

  3. 進入Edit Panel頁面,在下方Data source中輸入Prometheus,然後選擇已經完成Prometheus Server的介面地址。

  4. 單擊Metric browser, 然後輸入inspector,Grafana會自動補全ACK Net Exporter所有就緒的Metric,單擊右上方Save,在彈出框中單擊Save,然後會出現可視化的資料,效果如下:

    grafna

  5. 對於使用Grafana進行可視化圖形顯示的配置,可以參照上述的指標格式,對指標的顯示格式進行調整,例如inspector_pod_tcppassiveopens指標,表徵系統自開機或者Pod所屬的容器建立後,歸屬於這個網路命名空間內的所有TCP串連由於接受用戶端的握手請求建立的Socket總數變化,通常可以認為是表徵TCP總串連數量的增長,為了更加直觀的反應增長的速率變化,可以參考以下配置:

    // 使用PromQL提供的rate()方法配置Metrics。
    rate(inspector_pod_tcppassiveopens[1m])
    
    // 使用net-exporter提供的標籤來配置Legend,直觀顯示Metrics。
    {{namespace}}/{{pod}}/{{node}}

情境二:使用應用即時監控服務ARMS收集監控資料並可視化

ACK Net Exporter支援通過應用即時監控服務ARMS進行資料視覺效果操作,步驟如下:

  1. 步驟一:開啟阿里雲Prometheus監控

  2. 配置ACK Net Exporter自訂指標。

    1. 登入ARMS控制台,在左側導覽列中選擇Prometheus監控 > Prometheus執行個體列表

    2. 登入ARMS控制台

    3. 在頁面頂部,選擇Container ServiceACK叢集所在的地區

    4. 在左側導覽列選擇Prometheus監控 > 執行個體列表,進入可觀測監控 Prometheus 版的執行個體列表頁面。

    5. 單擊目標Prometheus執行個體名稱,進入整合中心頁面。
    6. 執行個體列表頁面,單擊目標執行個體名稱(一般是叢集名稱)進入對應執行個體頁面。

    7. 在左側導覽列中單擊服務發現,然後單擊Targets頁簽,在頁面下方的kubernetes-pods選項頁可以看到ACK Net Exporter的指標已經配置成功。服務發現

      如果沒有找到相關的Pod,則需要您在配置頁簽下手動開啟預設服務發現的選項。配置

    8. 在左側導覽列中單擊大盤列表,單擊目標大盤進入Grafana,然後單擊添加Panel,選擇Graph類型,在Data source中選擇開啟ACK Net Exporter的叢集相關的資料來源。

    9. 單擊Metric browser, 然後輸入inspector,Grafana會自動補全ACK Net Exporter所有就緒的Metric,單擊右上方Save,在彈出框中單擊Save,然後會出現可視化的資料,效果如下:81

情境三:使用Grafana Loki收集監控事件並可視化

ACK Net Exporter採集的例外狀況事件類型的資料,支援通過預先配置的Grafana Loki服務,由ACK Net Exporter向Loki進行即時推送,從而達到將分布式的例外狀況事件進行集中式的串型查看分析,使用ACK Net Exporter配合Grafana Loki的服務步驟如下:

  1. 搭建Grafana Loki服務

    說明

    服務需要位於ACK Net Exporter的Pod可以訪問的網路中,ACK Net Exporter會主動向已經配置並就緒的Grafana Loki服務推送事件記錄資訊。

  2. 在安裝ACK Net Exporter的配置頁面中,將enableEventServer配置為true,將lokiServerAddress配置為Grafana Loki服務的地址。您可以配置Grafana Loki服務的IP地址,也可以配置Grafana Loki 服務的網域名稱。命令

  3. 執行以下命令,訪問Grafana Loki的服務地址來檢驗Grafana Loki服務是否已就緒。

    curl http://[Grafana Loki執行個體的地址]:3100/ready
  4. 待Grafana Loki服務就緒後,添加Grafana Loki作為Grafana的資料來源。

    開啟Grafana頁面,在左側導覽列中選擇Data source > Loki,輸入Grafana Loki的介面地址,單擊Save&testloki

  5. 在左側導覽列單擊Explore,在頁面頂部設定資料來源為Loki,查看輸出到Grafana Loki的事件資訊。

    您可以在Label filters下拉框中選擇過濾某個Node的事件,也可以在Line containers中輸入事件相關的資訊來查看具體的事件。查看事件

    您可以單擊頁面頂部的Add to dashboard,將配置好的事件Panel添加到大盤中。

    ACK Net Exporter提供的事件根據事件的類型攜帶了不同的資訊,單擊事件的詳情後,可以查看到詳細的事件發生時的資訊。事件詳細資料

    Grafana Loki服務支援通過LogQL文法查詢資訊,詳細介紹,請參見LogQL

情境四:使用ACK Net Exporter Cli工具收集監控事件

ACK Net Exporter Cli(以下簡稱inspector-cli)是ACK容器網路團隊基於ACK Net Exporter既有的能力,提供情境化的問題排查輔助分析,擷取即時核心例外狀況事件記錄的工具,針對雲原生情境設計,協助使用者快速定位常見問題的深層次原因。

您可以通過在本地啟動容器的方式運行inspector-cli。

# 啟動臨時容器用於使用incpector-cli,您可以更換鏡像的版本來使用更新版本的特性。
docker run -it --name=inspector-cli --network=host registry.cn-hangzhou.aliyuncs.com/acs/inspector:v0.0.1-12-gff0558c-aliyun

which inspector
# /bin/inspector 是inspector-cli的執行路徑,您可以直接在容器中使用inspector-cli。

例如,您可以通過以下方式使用inspector-cli擷取到某個節點的ACK Net Exporter捕獲的事件。

# 通過‘-e’指定需要擷取事件的遠端ACK Net Exporter事件服務地址。
inspector watch -e 10.1.16.255

# 以下為結果樣本。
 INFO  TCP_RCV_RST_ESTAB Namespace=kube-system Pod=kube-proxy-worker-tbv5s Node=iZbp1jesgumdx66l8ym8j8Z Netns=4026531993 10.1.16.255:43186 -> 100.100.27.15:3128
...

您也可以選擇登入到ACK Net Exporter的inspector容器中排查問題。

# 執行命令時,需要將-n參數指定為net-exporter安裝的命名空間,同時執行需要登入的節點上的net-exporter執行個體。
kubectl exec -it -n kube-system -c inspector net-exporter-2rvfh -- sh

# 通過以下命令可以查看到當前節點上的網路資料面分布情況。
inspector list entity

# 通過以下命令可以監聽本地的網路例外狀況事件日誌及其資訊。
inspector watch -d -v
#{"time":"2023-02-03T09:01:03.402118044Z","level":"INFO","source":"/go/src/net-exporter/cmd/watch.go:63","msg":"TCPRESET_PROCESS","meta":"hostNetwork/hostNetwork node=izbp1dnsn1bwv9oyu2gaupz netns=ns0 ","event":"protocol=TCP saddr=10.1.17.113 sport=6443 daddr=10.1.17.113 dport=44226  state:TCP_OTHER "}

# 通過指定多個遠端的ACK Net Exporter執行個體,也可以觀察到不同節點上發生的時間。
inspector watch -s 10.1.17.113 -s 10.1.18.14 -d -v
            

如何使用ACK Net Exporter定位容器網路常見偶發疑難問題

以下內容提供了針對部分雲原生典型問題的排查指南,結合ACK Net Exporter,協助您快速擷取與問題有關的資訊。

DNS逾時相關問題

在雲原生環境中,DNS服務逾時問題會導致服務的訪問失敗,出現DNS訪問逾時的常見原因有:

  • DNS服務響應的速度較慢,無法在使用者程式的逾時時間到達前完成一次DNS查詢。

  • 由於發送端的問題,沒有順利或者及時發送DNS Query報文。

  • 服務端及時響應了報文,但是由於發送端本身的記憶體不足等問題出現了丟包。

您可以藉助以下幾個指標來協助排查偶發的DNS逾時問題:

指標名稱

說明

inspector_pod_udpsndbuferrors

UDP協議通過網路層方法發送時出現報錯的次數

inspector_pod_udpincsumerrors

UDP接收報文時出現CSUM校正錯誤的次數

inspector_pod_udpnoports

網路層調用__udp4_lib_rcv收包時找不到對應連接埠的Socket的次數

inspector_pod_udpinerrors

UDP接收報文時出現錯誤的次數

inspector_pod_udpoutdatagrams

UDP協議通過網路層方法成功發送報文的數量

inspector_pod_udprcvbuferrors

UDP在將應用程式層協議資料拷貝到Socket接收隊列時由於隊列不足導致的報錯次數

由於雲原生環境中很多服務依賴於CoreDNS提供網域名稱解析服務,在出現DNS問題時,如果出現問題的DNS請求與CoreDNS有關,您需要同時觀察CoreDNS相關Pod的上述指標的異常情況。

Nginx Ingress 499/502/503/504相關問題

雲原生環境下,Ingress網關或者其他擔任Proxy/Broker作用的代理服務出現偶發的異常是較為常見的疑難問題,對於Nginx Ingress及以Nginx為底座的其他代理服務中,499/502/503/504問題是最為常見的四類,他們各自表徵的含義如下:

  • 499,當請求Nginx的用戶端在Nginx沒有進行回複的時候就關閉了TCP串連,常見原因包括:

    • 用戶端串連建立之後,發送請求較晚,導致Nginx回複過程中就達到了Client Timeout,常見於Android用戶端的非同步請求架構中。

    • 服務端在串連建立後,串連的處理較慢,需要深入排查。

    • 服務端在向上遊Upstream的後端發起請求時,後端處理較慢。

  • 502,情境很多,多見於Nginx與Upstream後端之間串連層面的問題,例如串連建立失敗,或者後端異常的關閉,常見原因包括:

    • 後端配置的DNS網域名稱解析失敗,通常在使用Kubernetes Service作為後端時會出現。

    • 與Upstream之間建立串連失敗。

    • Upstream的請求或者響應過大,無法分配到記憶體等幹擾正常業務互動的現象。

  • 503,在Nginx中,用於提示用戶端,所有的Upstream均出現了停用情況,在雲原生情境下,有一些特定的含義,常見原因包括:

    • 沒有可用的後端,這種情況通常出現較少。

    • 流量過大,被Ingress的Limit Req所限制。

  • 504,用於表徵Nginx與Upstream相關的業務報文出現逾時的問題,常見原因為Upstream返回的業務報文沒有及時到達。

在遇到上述幾類問題時,您需要先收集一些通用的資訊用於界定問題發生的可能範圍與下一步排查方向:

  • Nginx提供的access_log資訊,尤其是request_timeupstream_connect_timeupstrem_response_time

  • Nginx提供的error_log資訊,在問題發生時是否有異常的報錯資訊出現。

  • 如果配置了Liveness或者Readness健全狀態檢查,可查看健全狀態檢查。

在上述資訊的基礎上,您需要按照問題的具體現象關注以下指標的變化,在可能出現串連失敗時:

指標名稱

說明

inspector_pod_tcpextlistenoverflows

當LISTEN狀態的Sock接受串連時出現半串連隊列溢出時會計數

inspector_pod_tcpextlistendrops

當LISTEN狀態的Sock建立SYN_RECV狀態的Sock失敗時會計數

inspector_pod_netdevtxdropped

網卡發送錯誤併產生丟棄的次數

inspector_pod_netdevrxdropped

網卡接收錯誤併產生丟棄的次數

inspector_pod_tcpactiveopens

單個Pod內TCP成功發起SYN初次握手的次數,不包括SYN的重傳,但是串連建立失敗也會導致這個指標上升

inspector_pod_tcppassiveopens

單個Pod內TCP完成握手並成功分配Sock的累積值,通常可以理解為成功建立串連的數量

inspector_pod_tcpretranssegs

單個Pod內重傳的總報文數,這裡已經跟據TSO進行了提前的分區計算

inspector_pod_tcpestabresets

單個Pod內異常關閉TCP串連的次數,這裡僅僅從結果層面統計

inspector_pod_tcpoutrsts

單個Pod內TCP發送的Reset報文次數

inspector_pod_conntrackinvalid

在CT建立過程中由於各種原因無法建立,但是報文並未被丟棄的次數

inspector_pod_conntrackdrop

由於CT建立過程中無法建立而丟棄報文的次數

針對出現了類似Nginx響應慢的情況時,例如雖然出現了逾時,但是Nginx的request_time很短的情況,您可以關注以下指標的變化:

指標名稱

說明

inspector_pod_tcpsummarytcpestablishedconn

當前存在的ESTABLISHED狀態的TCP串連數量

inspector_pod_tcpsummarytcptimewaitconn

當前存在的TIMEWAIT狀態的TCP串連數量

inspector_pod_tcpsummarytcptxqueue

當前處ESTABLISHED狀態的TCP串連的發送隊列中存在的資料包的Bytes總數

inspector_pod_tcpsummarytcprxqueue

當前處ESTABLISHED狀態的TCP串連的接收隊列中存在的資料包的Bytes總數

inspector_pod_tcpexttcpretransfail

重傳報文返回除了EBUSY之外的報錯時計數,說明重傳無法正常完成

在上述指標資訊的基礎上,根據指標在對應問題時間點的變化,可以縮小排查的範圍,如果憑藉指標無法定位到問題,您可以提交工單,在發起工單時提供上述的資訊,來協助客服同學快速瞭解情況,避免無效溝通。

TCP Reset報文相關問題

TCP Reset報文是TCP協議中用於對非預期情況做響應的動作,通常會對使用者程式造成以下的影響:

  • connection reset by peer報錯,通常出現在nginx等C lib依賴的業務中。

  • Broken pipe報錯,通常出現在Java或Python等封裝TCP串連的業務中。

雲原生網路環境中,出現Reset報文的常見原因有很多,這一類現象的出現也很難快速排查,以下列舉了幾種常見的Reset報文成因:

  • 服務端的異常,導致無法正常提供服務,例如配置的TCP使用的記憶體不足等原因,這一類情況通常會主動發送Reset。

  • 在使用Service或負載平衡時,由於endpoint或者Conntrack等有狀態的機制出現異常而轉寄到了非預期的後端。

  • 安全原因導致的串連釋放。

  • 在NAT環境,高並發等情境下出現防止迴繞序號(Protection Against Wrapped Sequence Numbers,以下簡稱PAWS)或者序號迴繞現象。

  • 使用TCP Keepalive進行串連保持,但是長時間沒有進行正常業務通訊的情況。

為了快速區分以上不同的根因,您可以收集一些基本的資訊指標:

  1. 梳理Reset報文產生時網路的用戶端和服務端之間的拓撲結構。

  2. 關注以下指標的變化:

    指標名稱

    說明

    inspector_pod_tcpexttcpabortontimeout

    由於keepalive/window probe/重傳的調用超過上限發送Reset時會更新此計數

    inspector_pod_tcpexttcpabortonlinger

    TCP的Linger2選項開啟後,快速回收處於FIN_WAIT2的串連時發送Reset的次數

    inspector_pod_tcpexttcpabortonclose

    狀態機器之外的原因關閉TCP串連時,仍有資料沒有讀取而發送Reset報文,則會進行指標計數

    inspector_pod_tcpexttcpabortonmemory

    在需要分配tw_sock/tcp_sock等邏輯中有由於tcp_check_oom出發記憶體不足而發送Reset結束串連的次數

    inspector_pod_tcpexttcpabortondata*

    由於Linger/Linger2選項開啟而通過Reset進行串連的快速回收時發送Reset的計數

    inspector_pod_tcpexttcpackskippedsynrecv

    在SYN_RECV狀態的Sock不回複ACK的次數

    inspector_pod_tcpexttcpackskippedpaws

    由於PAWS機制觸發校正,但是OOW限速限制了ACK報文發送的次數

    inspector_pod_tcpestabresets

    單個Pod內異常關閉TCP串連的次數,這裡僅僅從結果層面統計

    inspector_pod_tcpoutrsts

    單個Pod內TCP發送的Reset報文次數

  3. 如果Reset偶發的現象按照一定的頻率您可以參考上文開啟ACK Net Exporter的監控事件功能,採集對應的事件資訊:

    事件

    事件資訊

    TCP_SEND_RST

    發送了TCP Reset報文,排除下方兩個常見情境,其餘發送Reset報文均會出發此事件

    TCP_SEND_RST_NOSock

    由於本地沒有Sock而發送了TCP Reset報文

    TCP_SEND_RST_ACTIVE

    由於資源,使用者態關閉等原因主動發送了TCP Reset報文

    TCP_RCV_RST_SYN

    在握手階段收到了Reset報文

    TCP_RCV_RST_ESTAB

    在串連已建立狀態下收到Reset報文

    TCP_RCV_RST_TW

    在揮手階段收到了Reset報文

偶髮網絡延遲抖動相關問題

網路偶發延遲抖動類問題是雲原生環境中最為常見和最難以定位的一類問題,成因的現象極多,同時出現延遲可能會導致上述的三種問題的產生,容器網路情境下,節點內部出現的網路延遲通常包含以下幾種原因:

  • 出現某個RT調度器管理的即時進程執行時間過久,導致使用者業務進程或網路核心線程出現排隊較長或者處理較慢的現象。

  • 使用者進程本身出現了偶發外部調用耗時久的現象,如雲端硬碟響應慢,RDS的RTT偶發增加等常見原因,導致請求處理較慢。

  • 節點本身配置問題導致節點內不同CPU/不同NUMA Node之間負載不均,高負載的系統出現卡頓。

  • 核心的有狀態機器制引發的延遲,如Conntrack的Confirm操作,大量Orphan Socket影響了正常的Socket尋找等。

面對此類問題,儘管表現為網路問題,其最終的原因通常是由於OS的其他原因導致,您可以關注以下指標來縮小排查的範圍:

指標名稱

說明

inspector_pod_netsoftirqshed

從非強制中斷發起到ksoftirqd進程開始執行之間的耗時分布

inspector_pod_netsoftirq

從ksoftirqd開始執行非強制中斷內容到執行完成進入offcpu狀態的耗時分布

inspector_pod_ioioreadsyscall

進程進行檔案系統讀操作,如read,pread的次數

inspector_pod_ioiowritesyscall

進程進行檔案系統寫操作,如write,pwrite的次數

inspector_pod_ioioreadbytes

進程從檔案系統,通常是塊裝置中讀取的Bytes數量

inspector_pod_ioiowritebyres

進程向檔案系統進行寫入的Bytes數量

inspector_pod_virtsendcmdlat

網卡操作虛擬化調用的耗時分布

inspector_pod_tcpexttcptimeouts

CA狀態並未進入recovery/loss/disorder時觸發,當SYN報文未得到回複時進行重傳會計數

inspector_pod_tcpsummarytcpestablishedconn

當前存在的ESTABLISHED狀態的TCP串連數量

inspector_pod_tcpsummarytcptimewaitconn

當前存在的TIMEWAIT狀態的TCP串連數量

inspector_pod_tcpsummarytcptxqueue

當前處ESTABLISHED狀態的TCP串連的發送隊列中存在的資料包的Bytes總數

inspector_pod_tcpsummarytcprxqueue

當前處ESTABLISHED狀態的TCP串連的接收隊列中存在的資料包的Bytes總數

inspector_pod_softnetprocessed

單個Pod內所有CPU處理的從網卡放入CPU的Backlog的報文數量

inspector_pod_softnettimesqueeze

單個Pod內所有CPU處理的單次收包沒有全部擷取或者出現逾時的次數

客戶案例分析

以下為部分容器網路客戶藉助ACK Net Exporter進行疑難問題排查分析的案例,您可以比對現象進行參考。

案例一:某客戶偶發DNS Timeout問題

客戶現象

客戶A發起工單,現象為有偶發的DNS解析逾時,使用者業務採用PHP,DNS服務為配置CoreDNS。

排查過程

  1. 根據客戶描述,與客戶溝通後擷取客戶監控中的DNS相關資料。

  2. 分析客戶報錯時間點內資料,發現以下問題。

    • 報錯時間內inspector_pod_udpnoports增加1,指標整體較小。

    • inspector_pod_packetloss中出現了符號__udp4_lib_rcv的丟包加1,這個符號的丟包數變化較少。

  3. 客戶回函配置的DNS地址為公網某服務商地址,結合監控資訊,判斷客戶報錯根因為DNS請求返回較慢,使用者態逾時返回後,DNS回包到達。

案例二:某客戶Java應用偶發串連失敗問題

客戶現象

客戶B發起工單,現象為出現偶發的Tomcat不可用,每次出現期間約為5~10s。

排查過程

  1. 經過日誌分析,確認現象發生時,客戶的Java Runtime進行中GC操作。

  2. ACK Net Exporter監控部署後發現客戶在問題的時間點inspector_pod_tcpextlistendrops指標有明顯的上升。

  3. 經過分析後得出結論,客戶的Java Runtime進行GC操作時,處理請求的速度變慢,導致請求的釋放變慢,但是請求的建立並沒有被限制,因此產生了大量的連結,將Listen Socket的Backlog打滿後產生溢出,導致inspector_pod_tcpextlistendrops上升。

  4. 此問題中,客戶的串連堆積期間短,且本身處理能力沒有問題,因此建議客戶調整Tomcat相關參數後,解決了客戶問題。

案例三:某客戶偶髮網絡延遲抖動問題

客戶現象

客戶C發起工單,現象為客戶應用於Redis之間的請求出現了偶發的RTT增高導致業務逾時,但是無法複現。

排查過程

  1. 經過日誌分析,客戶出現了偶發的Redis請求超過300ms的總回應時間的情況。

  2. ACK Net Exporter部署後,從監控中發現了inspector_node_virtsendcmdlat指標在問題發生時有增長,增長的le(Prometheus監控中的Level)為18與15。經過換算得知此時出現過兩次延遲較高的虛擬化調用,其中le為15的產生了36ms以上的延遲,而le為18的產生了200ms以上的延遲。

  3. 由於核心的虛擬化調用執行時會佔據CPU,無法被搶佔,因此客戶的偶發延遲是由於Pod的批量增刪過程中有一些虛擬化調用執行過久導致。

案例四:某客戶Ingress Nginx偶發健全狀態檢查失敗問題

客戶現象

客戶D發起工單,現象為客戶的Ingress機器有偶發的健全狀態檢查失敗並伴隨著業務請求失敗的問題。

排查過程

  1. ACK Net Exporter部署監控後發現客戶出現問題是多個指標有異常的變化。

    1. inspector_pod_tcpsummarytcprxqueueinspector_pod_tcpsummarytcptxqueue均出現了上升。

    2. inspector_pod_tcpexttcptimeouts出現了上升。

    3. inspector_pod_tcpsummarytcptimewaitconn下降,inspector_pod_tcpsummarytcpestablishedconn上升。

  2. 經過分析後確認在問題發生的時間點,核心工作正常,串連的建立正常,但是使用者進程的運行出現了異常,包括處理收取Socket中的報文以及實際執行報文的發送操作,推測此時使用者進程存在調度問題或者限制問題。

  3. 建議使用者查看Cgroup的監控後發現客戶在問題時間點出現了CPU Throttled現象,證明此時出現了偶發的使用者進程由於Cgroup原因無法得到調度的現象。

  4. 按照文檔CPU Burst效能最佳化策略,為Ingress配置CPU Burst功能後,解決了這一類問題。

相關內容

ACK Net Exporter指標列表

在ACK Net Exporter更新過程中指標會有新增或變更,詳細資料請參考應用市場組件頁面的說明。除net_softirq/virtcmdlat等與Pod本身無關的邏輯外,所有的指標與事件均提供Pod粒度的詳細資料。

指標名稱

描述

探針名稱

inspector_pod_netdevrxbytes

網卡裝置接收的總位元組數。

netdev

inspector_pod_netdevtxbytes

網卡裝置發送的總位元組數。

netdev

inspector_pod_netdevtxerrors

網卡裝置出現發送錯誤的次數。

netdev

inspector_pod_netdevrxerrors

網卡裝置出現接受錯誤的次數。

netdev

inspector_pod_netdevtxdropped

網卡發送錯誤併產生丟棄的次數。

netdev

inspector_pod_netdevrxdropped

網卡接收錯誤併產生丟棄的次數。

netdev

inspector_pod_netdevtxpackets

網卡發送成功的報文數。

netdev

inspector_pod_netdevrxpackets

網卡接受成功的報文數。

netdev

inspector_pod_softnetprocessed

單個Pod內所有CPU處理的從網卡放入CPU的backlog的報文數量。

softnet

inspector_pod_softnetdropped

單個Pod內所有CPU處理的從網卡放入CPU的backlog失敗並丟棄報文數量。

softnet

inspector_pod_softnettimesqueeze

單個Pod內所有CPU處理的單次收包沒有全部擷取或者出現逾時的次數。

softnet

inspector_pod_tcpactiveopens

單個Pod內TCP成功發起SYN初次握手的次數,不包括SYN的重傳,但是串連建立失敗也會導致這個指標上升。

tcp

inspector_pod_tcppassiveopens

單個Pod內TCP完成握手並成功分配sock的累積值,通常可以理解為成功建立串連的數量。

tcp

inspector_pod_tcpretranssegs

單個Pod內重傳的總報文數,這裡已經跟據tso進行了提前的分區計算。

tcp

inspector_pod_tcpestabresets

單個Pod內異常關閉TCP串連的次數,這裡僅僅從結果層面統計。

tcp

inspector_pod_tcpoutrsts

單個Pod內TCP發送的reset報文次數。

tcp

inspector_pod_tcpcurrestab

單個Pod內TCP當前存在的活躍串連數。

tcp

inspector_pod_tcpexttcpabortontimeout

由於keepalive/window probe/重傳的調用超過上限發送reset時會更新此計數。

tcpext

inspector_pod_tcpexttcpabortonlinger

tcp的linger2選項開啟後,快速回收處於FIN_WAIT2的串連時發送reset的次數。

tcpext

inspector_pod_tcpexttcpabortonclose

狀態機器之外的原因關閉TCP串連時,仍有資料沒有讀取而發送reset報文,則會進行指標計數。

tcpext

inspector_pod_tcpexttcpabortonmemory

在需要分配tw_sock/tcp_sock等邏輯中有由於tcp_check_oom出發記憶體不足而發送reset結束串連的次數。

tcpext

inspector_pod_tcpexttcpabortondata*

由於linger/linger2選項開啟而通過reset進行串連的快速回收時發送reset的計數。

tcpext

inspector_pod_tcpextlistenoverflows

當LISTEN狀態的sock接受串連時出現半串連隊列溢出時會計數。

tcpext

inspector_pod_tcpextlistendrops

LISTEN狀態的sock建立SYN_RECV狀態的sock失敗時會計數。

tcpext

inspector_pod_tcpexttcpackskippedsynrecv

在SYN_RECV狀態的sock不回複ACK的次數。

tcpext

inspector_pod_tcpexttcpackskippedpaws

由於paws機制觸發校正,但是oow限速限制了ACK報文發送的次數。

tcpext

inspector_pod_tcpexttcpackskippedseq

由於序號在視窗外觸發較正,但是被oow限速限制了ACK報文發送的次數。

tcpext

inspector_pod_tcpexttcpackskippedchallenge

在需要發送challenge ack(通常用於確認reset報文)時被oow限速的次數。

tcpext

inspector_pod_tcpexttcpackskippedtimewait

在fin_wait_2狀態下,對於oow報文發送ack,但是因為限速而忽略發送的次數。

tcpext

inspector_pod_tcpexttcpackskippedfinwait2

在fin_wait_2狀態下,對於oow報文發送ack,但是因為限速而忽略發送的次數。

tcpext

inspector_pod_tcpextpawsestabrejected*

TCP入方向的報文因為PAWS防迴繞機制被丟棄的次數。

tcpext

inspector_pod_tcpexttcprcvqdrop

當TCP的recv隊列出現堆積,並且無法正常分配到記憶體時,會進行這項計數。

tcpext

inspector_pod_tcpexttcpretransfail

重傳報文返回除了EBUSY之外的報錯時計數,說明重傳無法正常完成。

tcpext

inspector_pod_tcpexttcpsynretrans

重傳的SYN報文次數。

tcpext

inspector_pod_tcpexttcpfastretrans

CA狀態部位loss時進行的重傳均會進行計數。

tcpext

inspector_pod_tcpexttcptimeouts

CA狀態並未進入recovery/loss/disorder時觸發,當SYN報文未得到回複時進行重傳會計數。

tcpext

inspector_pod_tcpsummarytcpestablishedconn

當前存在的ESTABLISHED狀態的TCP串連數量。

tcpsummary

inspector_pod_tcpsummarytcptimewaitconn

當前存在的TIMEWAIT狀態的TCP串連數量。

tcpsummary

inspector_pod_tcpsummarytcptxqueue

當前處ESTABLISHED狀態的TCP串連的發送隊列中存在的資料包的bytes總數。

tcpsummary

inspector_pod_tcpsummarytcprxqueue

當前處ESTABLISHED狀態的TCP串連的接收隊列中存在的資料包的bytes總數。

tcpsummary

inspector_pod_udpindatagrams

UDP成功接收報文的數量。

udp

inspector_pod_udpsndbuferrors

UDP協議通過網路層方法發送時出現報錯的次數。

udp

inspector_pod_udpincsumerrors

UDP接收報文時出現csum校正錯誤的次數。

udp

inspector_pod_udpignoredmulti

UDP忽略的多播報文的數量。

udp

inspector_pod_udpnoports

網路層調用__udp4_lib_rcv收包時找不到對應連接埠的socket的次數。

udp

inspector_pod_udpinerrors

UDP接收報文時出現錯誤的次數。

udp

inspector_pod_udpoutdatagrams

UDP協議通過網路層方法成功發送報文的數量。

udp

inspector_pod_udprcvbuferrors

UDP在將應用程式層協議資料拷貝到socket接收隊列時由於隊列不足導致的報錯次數。

udp

inspector_pod_conntrackentries*

這個指標表徵當前存在的entry的數量。

conntrack

inspector_pod_conntrackfound

成功尋找到ct記錄的次數。

conntrack

inspector_pod_conntrackinsert

目前不會計數。

conntrack

inspector_pod_conntrackinvalid

在ct建立過程中由於各種原因無法建立,但是報文並未被丟棄的次數。

conntrack

inspector_pod_conntrackignore

由於ct已經建立或者協議不需要維護ct而跳過的次數。

conntrack

inspector_pod_conntrackinsertfailed

目前不會計數。

conntrack

inspector_pod_conntrackdrop

由於ct建立過程中無法建立而丟棄報文的次數。

conntrack

inspector_pod_conntrackearlydrop

目前不會計數。

conntrack

inspector_pod_conntracksearchrestart

尋找ct過程中由於尋找失敗而進行重試的次數。

conntrack

inspector_pod_fdopenfd

單個Pod內所有進程的檔案描述符數量之和。

fd

inspector_pod_fdopensocket

單個Pod內socket類型的檔案描述符之和。

fd

inspector_pod_slabtcpslabobjperslab

TCP slab中單個page所包含的object數量。

slab

inspector_pod_slabtcpslabpagesperslab

TCP slab中的總page數量。

slab

inspector_pod_slabtcpslabobjactive

TCP slab中活躍狀態的object數量。

slab

inspector_pod_slabtcpslabobjnum

TCP slab中的object數量。

slab

inspector_pod_slabtcpslabobjsize

TCP slab中的object的大小,不同的核心版本會有差異。

slab

inspector_pod_ioioreadsyscall

進程進行檔案系統讀操作,如read,pread的次數。

io

inspector_pod_ioiowritesyscall

進程進行檔案系統寫操作,如write,pwrite的次數。

io

inspector_pod_ioioreadbytes

進程從檔案系統,通常是塊裝置中讀取的bytes數量。

io

inspector_pod_ioiowritebyres

進程向檔案系統進行寫入的bytes數量。

io

inspector_pod_net_softirq_schedslow100ms

網路非強制中斷出發後等待調度的時間超過100ms的次數。

net_softirq

inspector_pod_net_softirq_excuteslow100ms

網路軟中段執行時間超過100ms的次數。

net_softirq

inspector_pod_abnormalloss(inspector_pod_packetloss_abnormal)

核心丟棄報文,並且丟棄的報文是正常報文,即沒有出現報文完整性,校正失敗等情況的次數。

packetloss

inspector_pod_totalloss(inspector_pod_packetloss_total)

核心總丟包數量。

packetloss

inspector_pod_virtcmdlatency100ms

網卡操作虛擬化訊息通訊執行超過100ms的次數。

virtcmdlat

inspector_pod_socketlatencyread100ms

使用者程式操作讀取網路socket檔案中的內容,耗時超過100ms的情況統計。

socketlatency

inspector_pod_socketlatencywrite100ms

使用者程式操作寫入網路socket檔案中後,超過100ms沒有產生網路報文的情況統計。

socketlatency

kernellatency_rxslow100ms

作業系統核心在接收網路報文過程中耗時超過100ms的情況統計。

kernellatency

kernellatency_txslow100ms

作業系統核心在發送網路報文過程中耗時超過100ms的情況統計。

kernellatency

ACK Net Exporter事件詳解

ACK Net Exporter當前最新版本支援即時捕獲以下作業系統網路相關的例外狀況事件。

探針名稱

描述

netiftxlat

探測網路資料包發送時在tc qdisc等待延遲高的事件。

packetloss

作業系統核心丟棄正常的網路資料包的事件。

net_softirq

作業系統非強制中斷核心進程關於NET_RX/NET_TX中斷下半部的調度或執行延遲高的事件。

socketlatency

Pod中的進程進行socket相關的讀寫操作的耗時久的事件。

kernellatency

核心在網路層處理報文耗時久的事件。

virtcmdlatency

Virtio-net與宿主機通訊耗時久的事件。

tcpreset

接收或發出TCP協議中帶有RST標記的報文的事件。

tcptwrcv

TCP協議在TIMEWAIT狀態下收到了報文並處理的事件。

推薦使用的Grafana設定檔