1. 概述
Linux 网络命名空间是 Linux 内核提供的一种网络隔离机制,它允许创建完全独立的网络栈实例。每个网络命名空间都有自己的网络设备、IP 地址、路由表、防火墙规则等网络资源。这项技术是容器化技术(如 Docker)和虚拟化的基础。
2. 环境准备
2.1 系统要求
- Linux 内核 2.6.24 或更高版本
- iproute2 工具包
- root 权限或 sudo 权限
2.2 检查系统支持
创建检查脚本 check_system.sh:
bash
#!/bin/bash
# 文件名: check_system.sh
echo "=== 系统检查开始 ==="
# 检查内核版本
echo "1. 检查内核版本:"
uname -r
# 检查网络命名空间支持
echo -e "\n2. 检查网络命名空间支持:"
if [ -e /proc/self/ns/net ]; then
echo "✓ 系统支持网络命名空间"
else
echo "✗ 系统不支持网络命名空间"
exit 1
fi
# 检查 iproute2 工具
echo -e "\n3. 检查 iproute2 工具:"
if command -v ip > /dev/null 2>&1; then
echo "✓ iproute2 已安装"
ip -Version
else
echo "✗ iproute2 未安装,请安装: sudo apt-get install iproute2"
exit 1
fi
# 检查用户权限
echo -e "\n4. 检查用户权限:"
if [ "$EUID" -eq 0 ]; then
echo "✓ 当前为 root 用户"
else
echo "⚠ 当前为非 root 用户,部分操作可能需要 sudo"
fi
echo -e "\n=== 系统检查完成 ==="
运行检查脚本:
bash
chmod +x check_system.sh
./check_system.sh
3. 基础网络命名空间操作
3.1 创建和删除网络命名空间
创建基础操作脚本 basic_namespace_operations.sh:
bash
#!/bin/bash
# 文件名: basic_namespace_operations.sh
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 打印带颜色的消息
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 创建网络命名空间
create_namespace() {
local ns_name=$1
print_info "创建网络命名空间: $ns_name"
ip netns add $ns_name
# 验证创建
if ip netns list | grep -q "$ns_name"; then
print_info "✓ 命名空间 $ns_name 创建成功"
else
print_error "✗ 命名空间 $ns_name 创建失败"
exit 1
fi
}
# 在命名空间中执行命令
exec_in_namespace() {
local ns_name=$1
local command=$2
print_info "在命名空间 $ns_name 中执行: $command"
ip netns exec $ns_name $command
}
# 显示命名空间网络信息
show_namespace_network() {
local ns_name=$1
print_info "=== 命名空间 $ns_name 的网络信息 ==="
echo "网络接口:"
exec_in_namespace $ns_name "ip link show"
echo -e "\nIP 地址:"
exec_in_namespace $ns_name "ip addr show"
echo -e "\n路由表:"
exec_in_namespace $ns_name "ip route show"
}
# 删除网络命名空间
delete_namespace() {
local ns_name=$1
print_info "删除网络命名空间: $ns_name"
ip netns delete $ns_name
# 验证删除
if ! ip netns list | grep -q "$ns_name"; then
print_info "✓ 命名空间 $ns_name 删除成功"
else
print_error "✗ 命名空间 $ns_name 删除失败"
fi
}
# 主函数
main() {
print_info "开始基础网络命名空间操作演示"
# 创建两个测试命名空间
create_namespace "ns1"
create_namespace "ns2"
echo -e "\n"
print_info "当前所有网络命名空间:"
ip netns list
echo -e "\n"
# 显示默认命名空间信息
print_info "=== 默认命名空间网络信息 ==="
ip link show
echo -e "\n"
ip addr show
echo -e "\n"
ip route show
echo -e "\n"
# 显示新创建的命名空间信息
show_namespace_network "ns1"
echo -e "\n"
show_namespace_network "ns2"
# 清理
echo -e "\n"
delete_namespace "ns1"
delete_namespace "ns2"
print_info "基础网络命名空间操作演示完成"
}
# 执行主函数
main "$@"
运行基础操作脚本:
bash
chmod +x basic_namespace_operations.sh
sudo ./basic_namespace_operations.sh
4. 创建虚拟网络设备
4.1 创建 veth pair
veth(虚拟以太网设备)总是成对出现,用于连接不同的网络命名空间。
创建 veth 配置脚本 create_veth_network.sh:
bash
#!/bin/bash
# 文件名: create_veth_network.sh
set -e
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
# 清理函数
cleanup() {
print_info "执行清理操作..."
# 删除命名空间(如果存在)
for ns in ns1 ns2; do
if ip netns list | grep -q "$ns"; then
ip netns delete $ns 2>/dev/null || true
fi
done
# 删除 veth 设备(如果存在)
ip link delete veth1 2>/dev/null || true
ip link delete veth1-br 2>/dev/null || true
ip link delete veth2 2>/dev/null || true
ip link delete veth2-br 2>/dev/null || true
ip link delete br0 2>/dev/null || true
}
# 捕获退出信号
trap cleanup EXIT
main() {
print_info "开始创建虚拟网络..."
# 步骤1: 创建网络命名空间
print_step "1. 创建网络命名空间"
ip netns add ns1
ip netns add ns2
print_info "✓ 创建命名空间: ns1, ns2"
# 步骤2: 创建第一对 veth
print_step "2. 创建 veth pair: veth1 <-> veth1-br"
ip link add veth1 type veth peer name veth1-br
print_info "✓ 创建 veth pair: veth1 <-> veth1-br"
# 步骤3: 创建第二对 veth
print_step "3. 创建 veth pair: veth2 <-> veth2-br"
ip link add veth2 type veth peer name veth2-br
print_info "✓ 创建 veth pair: veth2 <-> veth2-br"
# 步骤4: 将 veth 设备移动到对应的命名空间
print_step "4. 移动 veth 设备到命名空间"
ip link set veth1 netns ns1
ip link set veth2 netns ns2
print_info "✓ veth1 移动到 ns1"
print_info "✓ veth2 移动到 ns2"
# 步骤5: 在命名空间中配置网络接口
print_step "5. 配置命名空间中的网络接口"
# 配置 ns1 中的 veth1
ip netns exec ns1 ip link set lo up
ip netns exec ns1 ip link set veth1 up
ip netns exec ns1 ip addr add 10.0.1.10/24 dev veth1
print_info "✓ ns1: veth1 配置 IP 10.0.1.10/24"
# 配置 ns2 中的 veth2
ip netns exec ns2 ip link set lo up
ip netns exec ns2 ip link set veth2 up
ip netns exec ns2 ip addr add 10.0.1.20/24 dev veth2
print_info "✓ ns2: veth2 配置 IP 10.0.1.20/24"
# 步骤6: 测试连通性
print_step "6. 测试直接连通性"
# 由于没有桥接,此时应该无法连通
print_info "测试 ns1 -> ns2 连通性:"
if ip netns exec ns1 ping -c 2 -W 1 10.0.1.20 >/dev/null 2>&1; then
print_info "✓ ns1 可以 ping 通 ns2"
else
print_warning "✗ ns1 无法 ping 通 ns2 (正常,因为尚未桥接)"
fi
# 显示网络配置
print_step "7. 显示当前网络配置"
echo -e "\n默认命名空间接口:"
ip link show | grep -E "(veth|br)"
echo -e "\nns1 网络配置:"
ip netns exec ns1 ip addr show
echo -e "\nns2 网络配置:"
ip netns exec ns2 ip addr show
print_info "虚拟网络创建完成!"
print_warning "注意: 由于没有桥接设备,命名空间之间目前无法通信"
}
main "$@"
运行 veth 创建脚本:
bash
chmod +x create_veth_network.sh
sudo ./create_veth_network.sh
5. 构建完整虚拟网络
5.1 使用 Linux 网桥连接多个命名空间
创建完整的虚拟网络脚本 create_complete_network.sh:
bash
#!/bin/bash
# 文件名: create_complete_network.sh
set -e
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'
print_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 网络配置
BRIDGE_NAME="br0"
BRIDGE_IP="10.0.1.1/24"
NS1_IP="10.0.1.10/24"
NS2_IP="10.0.1.20/24"
NS3_IP="10.0.1.30/24"
# 清理函数
cleanup() {
print_info "执行清理操作..."
# 删除命名空间
for ns in ns1 ns2 ns3; do
if ip netns list | grep -q "$ns"; then
ip netns delete $ns 2>/dev/null || true
fi
done
# 删除网络接口
for iface in veth1 veth1-br veth2 veth2-br veth3 veth3-br $BRIDGE_NAME; do
if ip link show $iface >/dev/null 2>&1; then
ip link delete $iface 2>/dev/null || true
fi
done
# 清理 iptables 规则
iptables -t nat -D POSTROUTING -s 10.0.1.0/24 -j MASQUERADE 2>/dev/null || true
}
trap cleanup EXIT
# 测试连通性
test_connectivity() {
local source_ns=$1
local target_ip=$2
local test_name=$3
print_info "测试 $test_name: $source_ns -> $target_ip"
if ip netns exec $source_ns ping -c 2 -W 1 $target_ip >/dev/null 2>&1; then
print_info "✓ $test_name 成功"
return 0
else
print_error "✗ $test_name 失败"
return 1
fi
}
main() {
print_info "开始创建完整虚拟网络..."
# 步骤1: 创建网络命名空间
print_step "1. 创建三个网络命名空间"
for ns in ns1 ns2 ns3; do
ip netns add $ns
print_info "✓ 创建命名空间: $ns"
done
# 步骤2: 创建 Linux 网桥
print_step "2. 创建 Linux 网桥: $BRIDGE_NAME"
ip link add name $BRIDGE_NAME type bridge
ip link set $BRIDGE_NAME up
ip addr add $BRIDGE_IP dev $BRIDGE_NAME
print_info "✓ 网桥 $BRIDGE_NAME 创建并启动,IP: $BRIDGE_IP"
# 步骤3: 创建并配置 veth pair
print_step "3. 创建和配置 veth pair"
for i in 1 2 3; do
# 创建 veth pair
ip link add veth$i type veth peer name veth$i-br
print_info "✓ 创建 veth pair: veth$i <-> veth$i-br"
# 将 veth 一端移动到命名空间
ip link set veth$i netns ns$i
print_info "✓ veth$i 移动到 ns$i"
# 将 veth 另一端连接到网桥
ip link set veth$i-br master $BRIDGE_NAME
ip link set veth$i-br up
print_info "✓ veth$i-br 连接到网桥 $BRIDGE_NAME"
# 配置命名空间中的网络
ip netns exec ns$i ip link set lo up
ip netns exec ns$i ip link set veth$i up
# 分配 IP 地址
case $i in
1) ip netns exec ns$i ip addr add $NS1_IP dev veth$i ;;
2) ip netns exec ns$i ip addr add $NS2_IP dev veth$i ;;
3) ip netns exec ns$i ip addr add $NS3_IP dev veth$i ;;
esac
print_info "✓ ns$i: veth$i 配置完成"
done
# 步骤4: 配置默认网关
print_step "4. 配置默认网关"
for i in 1 2 3; do
ip netns exec ns$i ip route add default via 10.0.1.1 dev veth$i
print_info "✓ ns$i 默认网关: 10.0.1.1"
done
# 步骤5: 启用 IP 转发和 NAT
print_step "5. 配置系统网络设置"
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j MASQUERADE
print_info "✓ 启用 IPv4 转发"
print_info "✓ 配置 NAT MASQUERADE"
# 步骤6: 测试网络连通性
print_step "6. 测试网络连通性"
# 测试网桥内部通信
test_connectivity "ns1" "10.0.1.20" "内部通信 ns1->ns2"
test_connectivity "ns1" "10.0.1.30" "内部通信 ns1->ns3"
test_connectivity "ns2" "10.0.1.10" "内部通信 ns2->ns1"
test_connectivity "ns3" "10.0.1.10" "内部通信 ns3->ns1"
# 测试网关可达性
test_connectivity "ns1" "10.0.1.1" "网关可达性"
# 步骤7: 显示网络拓扑信息
print_step "7. 显示网络拓扑信息"
echo -e "\n${BLUE}=== 网络拓扑摘要 ===${NC}"
echo "网桥: $BRIDGE_NAME (IP: $BRIDGE_IP)"
echo "命名空间:"
echo " ns1: veth1 (IP: $NS1_IP)"
echo " ns2: veth2 (IP: $NS2_IP)"
echo " ns3: veth3 (IP: $NS3_IP)"
echo -e "\n${BLUE}=== 网桥信息 ===${NC}"
brctl show $BRIDGE_NAME
echo -e "\n${BLUE}=== 详细接口信息 ===${NC}"
for ns in ns1 ns2 ns3; do
echo -e "\n命名空间 $ns:"
ip netns exec $ns ip addr show | grep -E "(inet|veth)"
echo "路由表:"
ip netns exec $ns ip route show
done
print_info "完整虚拟网络创建成功!"
print_warning "输入 'sudo ./cleanup_network.sh' 来清理网络"
}
main "$@"
运行完整网络创建脚本:
bash
chmod +x create_complete_network.sh
sudo ./create_complete_network.sh
5.2 网络拓扑可视化
创建网络拓扑图生成脚本 generate_network_diagram.sh:
bash
#!/bin/bash
# 文件名: generate_network_diagram.sh
cat > network_topology.md << 'EOF'
# 虚拟网络拓扑图
```mermaid
graph TB
%% 样式定义
classDef default fill:#1e1e1e,stroke:#666,stroke-width:2px,color:#fff;
classDef namespace fill:#2d5a78,stroke:#4ca1cf,stroke-width:2px,color:#fff;
classDef bridge fill:#5d3a6a,stroke:#b57edc,stroke-width:2px,color:#fff;
classDef veth fill:#356635,stroke:#6bc36b,stroke-width:2px,color:#fff;
%% 网桥
br0[br0<br/>10.0.1.1/24]:::bridge
%% 命名空间1
subgraph ns1[网络命名空间 ns1]
veth1_ns[veth1<br/>10.0.1.10/24]:::veth
end
%% 命名空间2
subgraph ns2[网络命名空间 ns2]
veth2_ns[veth2<br/>10.0.1.20/24]:::veth
end
%% 命名空间3
subgraph ns3[网络命名空间 ns3]
veth3_ns[veth3<br/>10.0.1.30/24]:::veth
end
%% 连接关系
veth1_ns -.->|veth pair| veth1_br
veth2_ns -.->|veth pair| veth2_br
veth3_ns -.->|veth pair| veth3_br
veth1_br --> br0
veth2_br --> br0
veth3_br --> br0
%% 隐藏的桥接端
veth1_br:::veth
veth2_br:::veth
veth3_br:::veth
%% 样式应用
class ns1,ns2,ns3 namespace;
数据流路径
flowchart TD
A[外部网络] <--> B[物理接口 eth0]
B <--> C[Linux 主机路由]
C <--> D{NAT 转换iptables}
D <--> E[网桥 br0 10.0.1.1/24]
E <--> F[veth1-br]
F <-.-> G[veth1 10.0.1.10/24]
G <--> H[ns1 应用]
E <--> I[veth2-br]
I <-.-> J[veth2 10.0.1.20/24]
J <--> K[ns2 应用]
E <--> L[veth3-br]
L <-.-> M[veth3 10.0.1.30/24]
M <--> N[ns3 应用]
EOF
echo "网络拓扑图已生成到 network_topology.md" echo "可以使用支持 Mermaid 的 Markdown 查看器查看图表"
运行拓扑图生成脚本:
bash
chmod +x generate_network_diagram.sh
./generate_network_diagram.sh
6. 高级网络配置
6.1 VLAN 隔离配置
创建 VLAN 配置脚本 configure_vlan.sh:
bash
#!/bin/bash
# 文件名: configure_vlan.sh
set -e
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
print_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
cleanup() {
print_info "清理 VLAN 配置..."
# 删除命名空间
for ns in vlan10-ns1 vlan10-ns2 vlan20-ns1 vlan20-ns2; do
if ip netns list | grep -q "$ns"; then
ip netns delete $ns 2>/dev/null || true
fi
done
# 删除 VLAN 接口和网桥
for br in br-vlan10 br-vlan20; do
if ip link show $br >/dev/null 2>&1; then
ip link set $br down
ip link delete $br 2>/dev/null || true
fi
done
# 删除物理接口上的 VLAN
for vlan in 10 20; do
if ip link show eth0.$vlan >/dev/null 2>&1; then
ip link delete eth0.$vlan 2>/dev/null || true
fi
done
}
trap cleanup EXIT
main() {
print_info "开始配置 VLAN 网络..."
# 步骤1: 创建命名空间
print_step "1. 创建 VLAN 命名空间"
for ns in vlan10-ns1 vlan10-ns2 vlan20-ns1 vlan20-ns2; do
ip netns add $ns
print_info "✓ 创建命名空间: $ns"
done
# 步骤2: 创建 VLAN 网桥
print_step "2. 创建 VLAN 网桥"
ip link add name br-vlan10 type bridge
ip link add name br-vlan20 type bridge
ip link set br-vlan10 up
ip link set br-vlan20 up
print_info "✓ 创建网桥: br-vlan10, br-vlan20"
# 步骤3: 配置 VLAN 接口 (如果物理接口存在)
print_step "3. 配置 VLAN 接口"
PHYSICAL_IFACE=$(ip route | grep default | awk '{print $5}' | head -1)
if [ -n "$PHYSICAL_IFACE" ] && [ "$PHYSICAL_IFACE" != "br0" ]; then
# 创建 VLAN 子接口
ip link add link $PHYSICAL_IFACE name $PHYSICAL_IFACE.10 type vlan id 10
ip link add link $PHYSICAL_IFACE name $PHYSICAL_IFACE.20 type vlan id 20
ip link set $PHYSICAL_IFACE.10 up
ip link set $PHYSICAL_IFACE.20 up
# 将 VLAN 接口连接到对应的网桥
ip link set $PHYSICAL_IFACE.10 master br-vlan10
ip link set $PHYSICAL_IFACE.20 master br-vlan20
print_info "✓ 在 $PHYSICAL_IFACE 上创建 VLAN 10 和 VLAN 20"
else
print_info "⚠ 未找到合适的物理接口,仅配置内部 VLAN"
fi
# 步骤4: 创建并配置 veth pair
print_step "4. 配置 veth pair 和 VLAN 连接"
# VLAN 10 的命名空间
for i in 1 2; do
# 创建 veth pair
ip link add veth-vlan10-$i type veth peer name veth-vlan10-$i-br
# 配置命名空间端
ip link set veth-vlan10-$i netns vlan10-ns$i
ip netns exec vlan10-ns$i ip link set lo up
ip netns exec vlan10-ns$i ip link set veth-vlan10-$i up
ip netns exec vlan10-ns$i ip addr add 10.10.10.$i$i/24 dev veth-vlan10-$i
# 配置网桥端
ip link set veth-vlan10-$i-br master br-vlan10
ip link set veth-vlan10-$i-br up
print_info "✓ 配置 VLAN10: vlan10-ns$i -> 10.10.10.$i$i"
done
# VLAN 20 的命名空间
for i in 1 2; do
# 创建 veth pair
ip link add veth-vlan20-$i type veth peer name veth-vlan20-$i-br
# 配置命名空间端
ip link set veth-vlan20-$i netns vlan20-ns$i
ip netns exec vlan20-ns$i ip link set lo up
ip netns exec vlan20-ns$i ip link set veth-vlan20-$i up
ip netns exec vlan20-ns$i ip addr add 10.10.20.$i$i/24 dev veth-vlan20-$i
# 配置网桥端
ip link set veth-vlan20-$i-br master br-vlan20
ip link set veth-vlan20-$i-br up
print_info "✓ 配置 VLAN20: vlan20-ns$i -> 10.10.20.$i$i"
done
# 步骤5: 配置网桥 IP
print_step "5. 配置网桥管理 IP"
ip addr add 10.10.10.1/24 dev br-vlan10 2>/dev/null || true
ip addr add 10.10.20.1/24 dev br-vlan20 2>/dev/null || true
# 步骤6: 测试连通性
print_step "6. 测试 VLAN 连通性"
echo -e "\n测试 VLAN10 内部通信:"
if ip netns exec vlan10-ns1 ping -c 2 -W 1 10.10.10.22 >/dev/null 2>&1; then
print_info "✓ VLAN10 内部通信正常"
else
print_info "✗ VLAN10 内部通信失败"
fi
echo -e "\n测试 VLAN20 内部通信:"
if ip netns exec vlan20-ns1 ping -c 2 -W 1 10.10.20.22 >/dev/null 2>&1; then
print_info "✓ VLAN20 内部通信正常"
else
print_info "✗ VLAN20 内部通信失败"
fi
echo -e "\n测试 VLAN 间隔离:"
if ip netns exec vlan10-ns1 ping -c 2 -W 1 10.10.20.11 >/dev/null 2>&1; then
print_info "✗ VLAN 隔离失败 (异常)"
else
print_info "✓ VLAN 隔离正常"
fi
# 步骤7: 显示配置信息
print_step "7. 显示 VLAN 配置信息"
echo -e "\n网桥信息:"
for br in br-vlan10 br-vlan20; do
echo -e "\n$br:"
bridge link show dev $br 2>/dev/null || brctl show $br 2>/dev/null || echo "无法获取网桥信息"
done
echo -e "\nVLAN 接口:"
ip link show | grep -E "vlan|br-vlan"
print_info "VLAN 配置完成!"
}
main "$@"
运行 VLAN 配置脚本:
bash
chmod +x configure_vlan.sh
sudo ./configure_vlan.sh
7. 网络监控和诊断
7.1 网络状态监控脚本
创建网络监控脚本 network_monitor.sh:
bash
#!/bin/bash
# 文件名: network_monitor.sh
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
print_header() {
echo -e "${BLUE}=== $1 ===${NC}"
}
print_success() {
echo -e "${GREEN}✓ $1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠ $1${NC}"
}
print_error() {
echo -e "${RED}✗ $1${NC}"
}
# 监控函数
monitor_namespaces() {
print_header "网络命名空间状态"
local namespaces=$(ip netns list)
if [ -z "$namespaces" ]; then
print_warning "没有找到网络命名空间"
return
fi
echo "$namespaces" | while read ns; do
echo -e "\n命名空间: $ns"
echo "接口状态:"
ip netns exec $ns ip -o link show | awk '{print " " $2 " " $3 " " $9}'
echo "IP 地址:"
ip netns exec $ns ip -o addr show | grep -v "inet6" | awk '{print " " $2 " " $4}'
echo "路由表:"
ip netns exec $ns ip route show | sed 's/^/ /'
done
}
monitor_bridges() {
print_header "网桥状态"
# 尝试使用 bridge 命令
if command -v bridge > /dev/null 2>&1; then
bridge link show
else
# 回退到 brctl
if command -v brctl > /dev/null 2>&1; then
brctl show
else
print_warning "未找到 bridge-utils 或 iproute2 bridge 工具"
fi
fi
}
monitor_connections() {
print_header "活跃连接测试"
# 测试本地回环
if ping -c 1 -W 1 127.0.0.1 >/dev/null 2>&1; then
print_success "本地回环正常"
else
print_error "本地回环异常"
fi
# 测试网关连接(如果有默认网关)
local gateway=$(ip route | grep default | awk '{print $3}' | head -1)
if [ -n "$gateway" ]; then
if ping -c 1 -W 1 $gateway >/dev/null 2>&1; then
print_success "网关 $gateway 可达"
else
print_warning "网关 $gateway 不可达"
fi
fi
}
monitor_iptables() {
print_header "防火墙规则"
for table in filter nat mangle; do
echo -e "\n表: $table"
iptables -t $table -L -n 2>/dev/null | head -20
done
}
monitor_system_stats() {
print_header "系统网络统计"
echo -e "\n网络接口统计:"
ip -s link show
echo -e "\n连接统计:"
ss -s
}
# 持续监控模式
continuous_monitor() {
local interval=${1:-5}
while true; do
clear
print_header "网络监控 - $(date)"
monitor_namespaces
monitor_bridges
monitor_connections
echo -e "\n${YELLOW}按 Ctrl+C 退出监控...${NC}"
sleep $interval
done
}
# 主函数
main() {
case "${1:-}" in
"continuous"|"cont"|"c")
continuous_monitor "${2:-5}"
;;
"help"|"-h"|"--help")
echo "用法: $0 [mode]"
echo "模式:"
echo " continuous [interval] 持续监控模式,可指定间隔(秒)"
echo " help 显示此帮助信息"
echo " 无参数 单次监控快照"
;;
*)
print_header "网络监控快照 - $(date)"
monitor_namespaces
monitor_bridges
monitor_connections
monitor_iptables
monitor_system_stats
;;
esac
}
main "$@"
运行网络监控:
bash
chmod +x network_monitor.sh
# 单次监控
sudo ./network_monitor.sh
# 持续监控(每5秒刷新)
sudo ./network_monitor.sh continuous 5
8. 清理脚本
创建网络清理脚本 cleanup_network.sh:
bash
#!/bin/bash
# 文件名: cleanup_network.sh
set -e
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
print_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
confirm_cleanup() {
read -p "确定要清理所有虚拟网络配置吗?(y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "取消清理操作"
exit 0
fi
}
cleanup_namespaces() {
print_info "清理网络命名空间..."
local namespaces=$(ip netns list | awk '{print $1}')
if [ -z "$namespaces" ]; then
print_info "没有找到需要清理的命名空间"
return
fi
for ns in $namespaces; do
print_info "删除命名空间: $ns"
ip netns delete $ns
done
}
cleanup_bridges() {
print_info "清理网桥..."
# 获取所有网桥
local bridges=$(ip link show type bridge | grep -o "br[^:]*" || true)
for br in $bridges; do
# 跳过一些系统网桥
case $br in
"docker0"|"virbr0")
print_warning "跳过系统网桥: $br"
continue
;;
esac
print_info "删除网桥: $br"
ip link set $br down
ip link delete $br
done
}
cleanup_veth_pairs() {
print_info "清理 veth pair..."
# 查找所有 veth 设备
local veth_devices=$(ip link show | grep -o "veth[^@]*" | uniq || true)
for dev in $veth_devices; do
print_info "删除 veth 设备: $dev"
ip link delete $dev 2>/dev/null || true
done
}
cleanup_vlan_interfaces() {
print_info "清理 VLAN 接口..."
# 查找 VLAN 子接口
local vlan_ifaces=$(ip link show | grep -o "[^ ]*\.[0-9]*@[^:]*" | cut -d'@' -f1 | uniq || true)
for iface in $vlan_ifaces; do
print_info "删除 VLAN 接口: $iface"
ip link delete $iface 2>/dev/null || true
done
}
cleanup_iptables_rules() {
print_info "清理 iptables 规则..."
# 清理 NAT 规则
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
print_info "✓ iptables 规则已清理"
}
reset_network_settings() {
print_info "重置网络设置..."
# 禁用 IP 转发
echo 0 > /proc/sys/net/ipv4/ip_forward
# 刷新路由缓存
ip route flush cache
print_info "✓ 网络设置已重置"
}
show_remaining_objects() {
print_info "检查剩余网络对象..."
echo -e "\n剩余网络命名空间:"
ip netns list
echo -e "\n剩余网桥:"
ip link show type bridge 2>/dev/null || echo "无"
echo -e "\n剩余 veth 设备:"
ip link show | grep "veth" || echo "无"
}
main() {
echo "=== 虚拟网络清理工具 ==="
# 请求确认
confirm_cleanup
# 执行清理操作
cleanup_namespaces
cleanup_bridges
cleanup_veth_pairs
cleanup_vlan_interfaces
cleanup_iptables_rules
reset_network_settings
echo -e "\n"
show_remaining_objects
print_info "虚拟网络清理完成!"
}
# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
print_error "请使用 root 权限运行此脚本: sudo $0"
exit 1
fi
main "$@"
运行清理脚本:
bash
chmod +x cleanup_network.sh
sudo ./cleanup_network.sh
9. 总结
通过本教程,我们深入学习了 Linux 网络命名空间的各个方面:
- 基础概念:理解了网络命名空间的隔离机制
- 实际操作:掌握了创建、配置和管理网络命名空间的技能
- 网络构建:学会了使用 veth pair 和网桥构建复杂虚拟网络
- 高级特性:了解了 VLAN 配置和网络隔离
- 监控诊断:掌握了网络状态监控和故障诊断方法
这些技能为理解容器网络、虚拟化技术和云原生基础设施打下了坚实基础。网络命名空间是现代 Linux 网络虚拟化的核心技术,掌握它对于系统管理员、网络工程师和 DevOps 工程师都至关重要。