在微服務架構和云原生應用廣泛采用的今天,.NET Core 應用被越來越多地部署在 Kubernetes 集群中。然而,一旦這些應用出現性能瓶頸,僅靠傳統的日志和指標可能無法定位問題的根本原因。
從 .NET Core 3 開始,微軟推出了一系列跨平臺的運行時診斷工具,比如:
-
dotnet-counters:用于查看實時性能計數器 -
dotnet-dump:抓取和分析內存轉儲 -
dotnet-trace:采集運行時事件和 CPU 棧信息 -
dotnet-gcdump:采集垃圾回收(GC)相關信息
這些工具通過 .NET Core 的 Diagnostic Server 與目標進程進行通信,在 Linux 系統中,它們通過 Unix Domain Socket 進行 IPC 交互。默認的 Socket 文件位于 /tmp 目錄下。
使用 Sidecar 模式部署診斷工具
在容器環境下部署診斷工具通常有兩種方式:
-
將工具和應用程序打包在同一個鏡像中
-
使用 sidecar 容器獨立運行診斷工具
第一種方式會導致鏡像體積變大,且工具升級不方便。因此,推薦使用 Sidecar 容器:它與主容器在同一個 Pod 中運行,共享網絡和存儲卷,適合部署監控或日志收集等輔助任務。
我們將構建一個 Sidecar 模式的診斷方案,解決以下三個關鍵問題:
-
如何從 Sidecar 容器訪問主容器內的 .NET Core 進程
-
如何共享
/tmp目錄以建立 IPC 通道 -
如何持久化診斷數據
案例演示:分析一個 ASP.NET Core Worker Service
首先,我們創建一個簡單的 Worker Service 應用,它會周期性計算某個位置的質數(模擬 CPU 密集型任務):
_logger.LogInformation("Prime number at position {position} is {value}", pos, FindPrimeNumber(pos));
然后為該應用構建鏡像并推送到容器倉庫(如 Docker Hub 或 Azure 容器注冊表)。
接著,我們構建第二個容器鏡像,下面是我們構建該 Sidecar 容器鏡像所用的 Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:5.0 as tools
# 安裝所需的 .NET 診斷工具
RUN dotnet tool install --tool-path /tools dotnet-trace
RUN dotnet tool install --tool-path /tools dotnet-dump
RUN dotnet tool install --tool-path /tools dotnet-counters
# 使用更小的運行時鏡像作為最終鏡像,減少體積
FROM mcr.microsoft.com/dotnet/runtime:5.0 AS runtime
# 將工具復制到最終鏡像中
COPY --from=tools /tools /tools
# 添加工具目錄到 PATH,確保容器啟動后可以直接調用 dotnet 工具
ENV PATH="/tools:${PATH}"
WORKDIR /tools

Kubernetes 部署設計
為了持久化診斷數據,我們需要一個掛載的共享存儲。在 Azure Kubernetes Service (AKS) 中,我們可以動態創建基于 Azure Files 的存儲卷。以下是關鍵的 YAML 片段:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
shareProcessNamespace: true
containers:
- name: toolbox
image: <your-sidecar-image>
volumeMounts:
- name: tmp
mountPath: /tmp
- name: data
mountPath: /data
- name: app
image: <your-app-image>
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
- name: data
persistentVolumeClaim:
claimName: monitor-azfiles
注意點:
-
shareProcessNamespace: true使得 Sidecar 可以看到主容器的進程 -
/tmp目錄通過emptyDir共享,建立 IPC 通道 -
Sidecar 容器的
/data目錄掛載 Azure Files 持久卷,用于存儲診斷結果 -
設置
stdin: true和tty: true保證 Sidecar 容器處于可交互狀態
部署完成后,你可以使用 kubectl exec 命令進入 Sidecar 容器:
kubectl exec -it <pod-name> -n net-worker -c toolbox -- /bin/bash
實際運行診斷工具
1. 使用 dotnet-trace 采集追蹤數據
首先獲取主容器的進程 ID:
dotnet-trace ps
然后開始采集數據并將其保存到掛載的共享目錄中:
dotnet-trace collect -p 13 --format Chromium -o /data/trace.json
下載 /data/trace.json 后,可以用 Chrome 或 Edge 瀏覽器訪問 chrome://tracing 或 edge://tracing 查看可視化結果。
2. 使用 dotnet-counters 查看性能指標
dotnet-counters collect --process-id 13 --refresh-interval 10 --output /data/counters --format json
同樣可以將 JSON 文件下載后用 VS Code 打開分析。
總結
通過將診斷工具打包進 Sidecar 容器,并結合共享的 /tmp 目錄和持久卷存儲,我們可以在 Kubernetes 中高效、靈活地為 .NET Core 應用進行性能診斷。這種方式解耦了診斷工具與主應用容器,具有良好的可維護性和擴展性。
浙公網安備 33010602011771號