使用 K8spacket 和 Grafana 對 K8S 的 TCP 數據包流量可視化
前言
如何知道 K8S 集羣內 Pod 之間建立了哪些 TCP 連接?集羣之間存在哪些調用關係?
使用 k8spacket
和Grafana
,您可以可視化集羣中的 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 客戶端,可以將嗅探到的工作負載解析爲可視化上可見的集羣資源名稱(Pods
和Services
)。它作爲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 Pods
和 Service
:
# 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
包地址如下:
同樣的拉取到本地:
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多平臺發佈