使用 K8spacket 和 Grafana 對 K8S 的 TCP 數據包流量可視化

使用 K8spacket 和 Grafana 對 K8S 的 TCP 數據包流量可視化

前言

如何知道 K8S 集羣內 Pod 之間建立了哪些 TCP 連接?集羣之間存在哪些調用關係?

使用 k8spacketGrafana,您可以可視化集羣中的 TCP 流量。瞭解工作負載如何相互通信,以及建立了多少連接,交換了多少字節,這些連接處於活動狀態的時間。

介紹

k8spacket是用 Golang 編寫的工具,它使用gopacket第三方庫來嗅探工作負載(傳入和傳出)上的 TCP 數據包。它在運行的容器網絡接口上創建 TCP 偵聽器。當 Kubernetes 創建一個新容器時,CNI 插件負責提供與其他容器進行通信的可能性。最常見的方法是用linux namespace隔離網絡並用veth pair連接隔離的 namespace 與網橋。除了bridge 類型,CNI 插件還可以使用其他類型(vlan, ipvlan,macvlan),但都爲容器創建了一個網絡接口,它是k8spacket嗅探器的主要句柄。

k8spacket有助於瞭解 Kubernetes 集羣中的 TCP 數據包流量:

  • 顯示集羣中工作負載之間的流量
  • 通知流量在集羣外路由到哪裏
  • 顯示有關連接關閉套接字的信息
  • 顯示工作負載發送/接收的字節數
  • 計算建立連接的時間
  • 顯示整個集羣中工作負載之間的網絡連接拓撲

k8spacket是一個 Kubernetes API 客戶端,可以將嗅探到的工作負載解析爲可視化上可見的集羣資源名稱(PodsServices)。它作爲DaemonSet Pod啓動,使用 hostNetwork,並監聽節點上的網絡接口。

k8spacket 收集 TCP 流、處理數據,使用 Node Graph API Grafana 數據源插件(詳情請查看 Node Graph API 插件),通過 API 展示在Grafana面板。

要安裝k8spacket,需要同時安裝 Grafana。下面將在Kind安裝的 k8s 集羣上做演示。

安裝 k8spacket

使用 Helm 安裝:

helm repo add k8spacket https://k8spacket.github.io/k8spacket-helm-chart
helm install k8spacket --namespace k8spacket k8spacket/k8spacket --create-namespace

默認安裝會使用下面的命令獲取所有需要監聽的網絡接口:

ip address | grep @ | sed -E 's/.* (\w+)@.*/\1/' | tr '\n' ',' | sed 's/.$//'

其中可能包含一些狀態爲Down的接口,此時啓動k8spacket會報錯:

2022/08/15 00:17:34 error opening pcap handle: tunl0: That device is not up

報錯中提示網絡接口tunl0狀態不是up

所以需要自定義修改values.yaml中的參數。將charts包拉取到本地,解壓之後再修改:

mkdir k8spacket
helm fecth k8spacket/k8spacket
tar -zxf k8spacket-0.1.0.tgz
cd k8spacket

修改 values.yaml 中的內容,過濾掉tunl0

k8sPacket:
  tcp:
    listener:
      interfaces:
        ## 實現容器網絡接口的命令
        command: "ip address | grep @ | grep -v tunl0 | sed -E 's/.* (\\w+)@.*/\\1/' | tr '\\n' ',' | sed 's/.$//'"
        ## 多久刷新一次要監聽的網絡接口列表
        refreshPeriod: "10s"
      ## 每 (periodDuration) 秒,刷新在過去 (closeOlderThanDuration) 秒內沒有看到活動的連接。
      flushing:
        periodDuration: "10s"
        closeOlderThanDuration: "20s"
  • refreshPeriod參數表示多久刷新一次要監聽的網絡接口列表,增加新的網絡接口監聽,移除舊網絡接口監聽。
  • periodDuration秒,刷新在過去 closeOlderThanDuration秒內沒有看到活動的連接。

安裝成功,包含以下Daemonset PodsService

# k get pod -n k8spacket -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP             NODE                    NOMINATED NODE   READINESS GATES
k8spacket-9m4cz   1/1     Running   0          10m   192.168.16.4   k8s118-control-plane    <none>           <none>
k8spacket-b4q9k   1/1     Running   0          10m   192.168.16.6   k8s118-control-plane3   <none>           <none>
k8spacket-b5nnp   1/1     Running   0          10m   192.168.16.7   k8s118-control-plane2   <none>           <none>
k8spacket-c25jh   1/1     Running   0          10m   192.168.16.2   k8s118-worker           <none>           <none>
k8spacket-cqqxh   1/1     Running   0          10m   192.168.16.5   k8s118-worker2          <none>           <none>
k8spacket-h9hjc   1/1     Running   0          10m   192.168.16.3   k8s118-worker3          <none>           <none>

# k get svc -n k8spacket -o wide
NAME        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE   SELECTOR
k8spacket   ClusterIP   11.0.227.158   <none>        8080/TCP   31m   app.kubernetes.io/instance=k8spacket,app.kubernetes.io/name=k8spacket

k8spacket Pod 提供了 /metrics 接口暴露指標:

curl 192.168.16.4:8080/metrics

安裝 dashboards

下載k8spacket項目,並將dashboards目錄下的面板 configmaps 創建到 K8S 中:

wget https://github.com/k8spacket/k8spacket/archive/refs/heads/master.zip
unzip master.zip
cd k8spacket-master
kubectl  apply --recursive -f ./dashboards

創建了 k8spacket-logs-dashboard、k8spacket-metrics-dashboard、k8spacket-node-graph-dashboard三個面板。

其中的metrics面板公開了 Prometheus 指標,這裏不做演示。只關心node-graph面板。

安裝 grafana

使用 Helm 安裝 grafana,helm-charts 包地址如下:

https://github.com/grafana/helm-charts

同樣的拉取到本地:

helm repo add grafana https://grafana.github.io/helm-charts
helm fetch grafana/grafana
tar -zxf grafana-6.32.13.tgz
cd grafana/

charts包版本爲:6.32.13
grafana版本爲:9.0.5

修改values.yaml,將 Node Graph API 插件和數據源,以及 node-graph dashboard configmaps 添加到 Grafana。同時開啓數據持久化。例如:

persistence:
  type: pvc
  enabled: true

env:
  GF_INSTALL_PLUGINS: hamedkarbasi93-nodegraphapi-datasource

dashboardProviders:
  dashboardproviders.yaml:
    apiVersion: 1
    providers:
    - name: 'default'
      orgId: 1
      folder: ''
      type: file
      disableDeletion: false
      editable: true
      options:
        path: /var/lib/grafana/dashboards/default

dashboardsConfigMaps:
  default: k8spacket-node-graph-dashboard

datasources:
  nodegraphapi-plugin-datasource.yaml:
      apiVersion: 1
      datasources:
      - name: "Node Graph API"
        jsonData:
          url: "http://k8spacket.k8spacket.svc.cluster.local:8080"
        access: "proxy"
        basicAuth: false
        isDefault: false
        readOnly: false
        type: "hamedkarbasi93-nodegraphapi-datasource"
        typeLogoUrl: "public/plugins/hamedkarbasi93-nodegraphapi-datasource/img/logo.svg"
        typeName: "node-graph-plugin"
        orgId: 1
        version: 1

values.yaml目錄下執行創建命令:

helm install grafana -f values.yaml  ./

獲取到admin賬號的密碼:

kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

開啓臨時端口轉發,使得集羣外可以訪問grafana實例:

kubectl --namespace default port-forward service/grafana 3000:80  --address 0.0.0.0

通過http://{Kind宿主機IP}:3000打開grafana面板,並使用上面獲取到的密碼登錄,可以看到Node Graph API插件成功安裝:

node graph面板可以看到集羣中網絡連接拓撲:

使用

統計類型

  • connection:幫助瞭解工作負載之間以及與外部客戶端之間建立了多少連接。它會告訴你哪些套接字保持打開狀態並可能導致問題。
  • bytes:顯示工作負載發送或接收的字節數。
  • duration:計算連接的生命週期。

過濾器

  • by namespace:選擇一個或多個 k8s 命名空間
  • by names included:選擇工作負載名稱進行可視化
  • by names excluded:從可視化中排除工作負載名稱

交流

請關注微信公衆號【進擊雲原生】,掃碼關注,瞭解更多諮詢,更有免費資源供您學習

掃碼關注,加羣學習

本文由mdnice多平臺發佈

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