转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn]
如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~
脚本
bash
#!/bin/bash
# 默认值
CONTAINER=""
MODE="once"
IFACE="wlan0"
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-f)
MODE="follow"
shift
;;
-i)
IFACE="$2"
shift 2
;;
*)
CONTAINER="$1"
shift
;;
esac
done
if [ -z "$CONTAINER" ]; then
echo "用法: $0 [-f] [-i 网卡] <容器名或ID>"
echo " -f 持续刷新模式(类似 top)"
echo " -i 指定网卡(默认: wlan0)"
echo "示例:"
echo " $0 wxedge # 单次查看,默认 wlan0"
echo " $0 -f wxedge # 持续刷新,默认 wlan0"
echo " $0 -i eth0 wxedge # 单次查看,指定 eth0"
echo " $0 -f -i eth0 wxedge # 持续刷新,指定 eth0"
exit 1
fi
PID=$(docker inspect --format '{{.State.Pid}}' "$CONTAINER" 2>/dev/null)
[ -z "$PID" ] && { echo "错误: 容器不存在"; exit 1; }
INTERVAL=2
clear_screen() { printf "\033[2J\033[H"; }
human() { [ $1 -lt 1048576 ] && echo "$(echo "scale=2;$1/1024"|bc)KB" || ([ $1 -lt 1073741824 ] && echo "$(echo "scale=2;$1/1048576"|bc)MB" || echo "$(echo "scale=2;$1/1073741824"|bc)GB"); }
show() {
local rxp=$1 txp=$2 spd=$3
total=$(sudo nsenter -t $PID -n ss -ant 2>/dev/null|tail -n +2|wc -l)
estab=$(sudo nsenter -t $PID -n ss -ant state established 2>/dev/null|tail -n +2|wc -l)
tw=$(sudo nsenter -t $PID -n ss -ant state time-wait 2>/dev/null|tail -n +2|wc -l)
listen=$(sudo nsenter -t $PID -n ss -ant state listen 2>/dev/null|tail -n +2|wc -l)
finwait=$(sudo nsenter -t $PID -n ss -ant state fin-wait-1 2>/dev/null|tail -n +2|wc -l)
synsent=$(sudo nsenter -t $PID -n ss -ant state syn-sent 2>/dev/null|tail -n +2|wc -l)
echo "=========================================="
echo "容器: $CONTAINER (PID: $PID)"
echo "=========================================="; echo ""
echo "总 TCP 连接数: $total"; echo ""
echo "按状态分布:"
printf " %-12s %s\n" "ESTAB" "$estab"
printf " %-12s %s\n" "TIME-WAIT" "$tw"
printf " %-12s %s\n" "LISTEN" "$listen"
[ "$finwait" -gt 0 ] && printf " %-12s %s ⚠️\n" "FIN-WAIT-1" "$finwait" || printf " %-12s %s\n" "FIN-WAIT-1" "$finwait"
printf " %-12s %s\n" "SYN-SENT" "$synsent"
sudo nsenter -t $PID -n ss -ant 2>/dev/null|tail -n +2|awk '{print $1}'|grep -v -E 'ESTAB|TIME-WAIT|LISTEN|FIN-WAIT-1|SYN-SENT'|sort|uniq -c|sort -rn|while read c s;do printf " %-12s %s\n" "$s" "$c";done
echo ""
echo "监听端口 (前15):"
sudo nsenter -t $PID -n ss -antlp 2>/dev/null|grep LISTEN|awk '{print $4}'|sort|uniq|head -15|while read a;do echo " $a";done
echo ""
echo "本地端口 TOP 5:"
sudo nsenter -t $PID -n ss -ant 2>/dev/null|tail -n +2|awk '{print $4}'|grep -E ':[0-9]+$'|rev|cut -d: -f1|rev|sort|uniq -c|sort -rn|head -5|while read c p;do [ -n "$p" ]&&printf " 端口 %-6s %s 连接\n" "$p" "$c";done
echo ""
echo "远程地址 TOP 5:"
sudo nsenter -t $PID -n ss -ant state established 2>/dev/null|tail -n +2|awk '{print $5}'|sed 's/:[0-9]*$//'|grep -v '^$'|sort|uniq -c|sort -rn|head -5|while read c ip;do
[ -n "$ip" ] && printf " %-20s %s 连接\n" "$ip" "$c"
done
echo ""
echo "=========================================="
echo "带宽统计 ($IFACE)"
echo "=========================================="
net=$(sudo nsenter -t $PID -n cat /proc/net/dev 2>/dev/null|grep "^[[:space:]]*$IFACE:")
[ -n "$net" ] && {
rx=$(echo "$net"|awk '{print $2}'); tx=$(echo "$net"|awk '{print $10}')
echo "总接收: $(human $rx)"; echo "总发送: $(human $tx)"
[ "$spd" = "yes" -a -n "$rxp" ] && {
echo ""; echo "实时速度:"
echo " ↓ $(echo "scale=2;($rx-$rxp)/1048576/$INTERVAL"|bc)MB/s"
echo " ↑ $(echo "scale=2;($tx-$txp)/1048576/$INTERVAL"|bc)MB/s"
}
} || echo "错误: 网卡 $IFACE 不存在"
echo ""
echo "=========================================="
echo "状态检查"
echo "=========================================="
[ "$total" -gt 1000 ] && echo "⚠️ 连接数过多: $total" || echo "✓ 连接数正常: $total"
[ "$tw" -gt "$estab" ] && echo "⚠️ TIME-WAIT($tw) > ESTAB($estab) - P2P短连接正常" || echo "✓ TIME-WAIT 正常"
[ "$finwait" -gt 10 ] && echo "⚠️ FIN-WAIT-1 过多($finwait) - 网络可能不稳定" || echo "✓ FIN-WAIT-1 正常"
}
if [ "$MODE" = "follow" ]; then
trap 'echo "";exit' INT
net=$(sudo nsenter -t $PID -n cat /proc/net/dev 2>/dev/null|grep "^[[:space:]]*$IFACE:")
rx0=$(echo "$net"|awk '{print $2}'); tx0=$(echo "$net"|awk '{print $10}')
while true; do
clear_screen; show $rx0 $tx0 "yes"
echo ""; echo "------------------------------------------"
echo "刷新: ${INTERVAL}s | 网卡: $IFACE | Ctrl+C 退出"
net=$(sudo nsenter -t $PID -n cat /proc/net/dev 2>/dev/null|grep "^[[:space:]]*$IFACE:")
rx0=$(echo "$net"|awk '{print $2}'); tx0=$(echo "$net"|awk '{print $10}')
sleep $INTERVAL
done
else
show "" "" "no"
fi
用法
参数说明
| 参数 | 说明 | 默认 |
|---|---|---|
-f |
持续刷新模式 | 关闭 |
-i 网卡 |
指定网络接口 | wlan0 |
容器名 |
Docker 容器名称或 ID | 必填 |
使用示例
bash
# 先给权限
chmod +x docker_tcp.sh
# 默认 wlan0,单次
./docker_tcp.sh wxedge
# 默认 wlan0,持续刷新
./docker_tcp.sh -f wxedge
# 指定 eth0,单次
./docker_tcp.sh -i eth0 wxedge
# 指定 eth0,持续刷新
./docker_tcp.sh -f -i eth0 wxedge
# 或
./docker_tcp.sh -i eth0 -f wxedge
输出示例
==========================================
容器: wxedge (PID: 2489)
==========================================
总 TCP 连接数: 134
按状态分布:
ESTAB 39
TIME-WAIT 46
LISTEN 0
FIN-WAIT-1 3 ⚠️
SYN-SENT 2
LAST-ACK 1
监听端口 (前15):
0.0.0.0:111
0.0.0.0:139
0.0.0.0:22
0.0.0.0:2283
0.0.0.0:24095
0.0.0.0:27409
0.0.0.0:30673
0.0.0.0:37652
0.0.0.0:42183
0.0.0.0:445
0.0.0.0:45246
0.0.0.0:46838
0.0.0.0:54219
0.0.0.0:57434
0.0.0.0:58641
本地端口 TOP 5:
端口 27479 3 连接
端口 22 3 连接
端口 9993 2 连接
端口 54219 2 连接
端口 53 2 连接
远程地址 TOP 5:
==========================================
带宽统计 (wlan0)
==========================================
总接收: 21.52GB
总发送: 2.01GB
实时速度 (采样2秒):
下载: .35MB/s
上传: .02MB/s
==========================================
状态检查
==========================================
✓ 连接数正常: 134
⚠️ TIME-WAIT(46) > ESTAB(39) - P2P短连接正常
✓ FIN-WAIT-1 正常