powershell 无法直接监控 windows 容器实时网络流量,因其原生 cmdlet 仅作用于宿主机网络层,不穿透容器命名空间;需结合 hns 网络查询、docker api 调用(/containers/{id}/stats)、docker stats 命令轮询及端口连接分析等组合方式实现有效监控。
powershell 本身不直接支持监控 windows 容器(如 docker for windows 或 windows server container)的实时网络流量,因为 windows 容器默认使用 hns(host network service)或 docker0 虚拟网桥,其网络栈由 hns(hyper-v network service)或 cnm(container network model)抽象管理,原生 powershell cmdlet(如 get-netadapter、get-counter、get-nettcpconnection)仅作用于宿主机网络层,无法穿透到容器命名空间内的接口或进程。
但你可以通过以下组合路径实现有效监控,核心思路是:利用宿主机视角关联容器网络行为 + 借助容器运行时工具暴露指标 + PowerShell 封装采集与解析:
? 确认容器网络模式与宿主机映射关系
Windows 容器常用 nat 或 transparent 模式:
-
nat模式下,容器共享宿主机 IP,出站连接经 NAT 映射,端口映射(-p)会体现在宿主机监听端口; -
transparent模式下,容器获得独立 IP(通常在 Hyper-V 虚拟交换机子网中),其流量可被宿主机网卡捕获。
先查清当前容器网络配置:
# 查看所有 HNS 网络(含 nat/transparent)
Get-HnsNetwork | Select-Object Name, Type, Subnets
# 查看正在运行的容器及其端口映射(Docker CLI)
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"
✅ 关键点:只有
transparent模式下的容器流量能被Get-Counter "\Network Interface\..."直接观测;nat模式需通过端口映射反向追踪。
? 方法一:监控宿主机上容器绑定端口的 TCP 连接活跃度
适用于 Web 服务、API 等显式暴露端口的容器(如 -p 8080:80):
# 列出所有 ESTABLISHED 连接,并筛选目标端口(如宿主机监听的 8080)
Get-NetTCPConnection -State Established |
Where-Object { $_.LocalPort -eq 8080 } |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess |
ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
Port = $_.LocalPort
RemoteIP = $_.RemoteAddress
PID = $_.OwningProcess
Process = $proc.ProcessName
CPU = if($proc) { "{0:N1}" -f $proc.CPU } else { '-' }
}
} | Sort-Object CPU -Descending
? 提示:若容器未做端口映射(如仅内部通信),此法无效,需转向方法二或三。
? 方法二:调用 Docker API 获取容器实时网络统计(推荐)
Docker Desktop for Windows 或 Docker Engine on Windows Server 提供 /containers/{id}/stats HTTP 接口,返回 JSON 格式的实时 RX/TX 字节数:
# 假设 Docker daemon 在本地监听 http://127.0.0.1:2375(需启用 insecure registry 或配置 TLS)
$containerId = (docker ps -q | Select-Object -First 1)
if ($containerId) {
$url = "http://127.0.0.1:2375/containers/$containerId/stats?stream=false"
try {
$stats = Invoke-RestMethod -Uri $url -Method Get -TimeoutSec 5
$rx = $stats.networks.eth0.rx_bytes # 或根据实际网卡名(如 'nat' 模式下可能是 'vEthernet (DockerNAT)')
$tx = $stats.networks.eth0.tx_bytes
Write-Host "Container $containerId → RX: $(('{0:N0}' -f $rx)) B, TX: $(('{0:N0}' -f $tx)) B" -ForegroundColor Green
} catch { Write-Warning "Failed to fetch stats: $($_.Exception.Message)" }
}
⚠️ 注意:需确保 Docker daemon 已启用 TCP API(默认关闭),且 PowerShell 具备网络访问权限。生产环境建议启用 TLS 认证。
? 方法三:用 PowerShell 轮询 docker stats 命令输出(轻量级替代)
无需开启 API,适合快速验证:
while ($true) {
Clear-Host
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" 2>$null
Start-Sleep -Seconds 2
}
该命令输出包含 NetIO 列(如 1.2MB / 340KB),即容器累计收发流量——虽非秒级实时速率,但可观察趋势变化。
? 补充:识别“偷跑”容器流量的典型线索
-
svchost.exe+PID对应多个容器进程?→ 检查是否为com.docker.backend.exe或dockerd.exe托管的 HNS 端点; -
Get-NetTCPConnection中大量连接指向172.x.x.x或192.168.x.x内网地址 → 极可能为容器间通信(transparent网络); -
resmon中“网络活动的进程”出现dockerd.exe或com.docker.backend.exe占比异常高 → 容器镜像拉取、日志推送或健康检查频繁触发。
不复杂但容易忽略:Windows 容器网络监控必须跳出“宿主机进程=容器进程”的思维定式——容器是隔离的用户态进程集合,其网络行为需通过运行时(Docker/HCS)暴露指标,而非直接用 Get-Process 或 Get-Counter 抓取。











