OpenEuler中的网络隔离与 eBPF 观测
OpenEuler中的网络隔离与 eBPF 观测
一、实验目的
- 补全网络知识体系:深入理解现代操作系统如何处理网络隔离,掌握容器网络隔离的底层原理
- 掌握无侵入式监控技术:学习使用 eBPF 技术实现对系统的无侵入式监控,无需修改应用代码
- 了解 OpenEuler eBPF 生态:熟悉 OpenEuler 操作系统在 eBPF 生态上的工具支持,特别是 gala-gopher 等特色工具的底层技术
二、实验环境
1 软件平台
-
OpenEuler 操作系统(建议 22.03 LTS 或更高版本)
-
虚拟机环境(建议内存 4GB+,磁盘 20GB+)
2 核心组件
-
Network Namespace:Linux 内核网络隔离机制
-
eBPF:extended Berkeley Packet Filter,内核可编程框架
-
工具链:iproute2、BCC、bpftrace、gala-gopher
-
开发环境:Python 3、scapy 库
3 安装命令
\# 安装 iproute2(用于 Network Namespace 操作)
sudo dnf install -y iproute
\# 安装 eBPF 工具链
sudo dnf install -y bcc bpftrace
\# 安装 gala-gopher(OpenEuler 特色 eBPF 工具)
sudo dnf install -y gala-gopher
\# 安装 Python3 和相关库
sudo dnf install -y python3 python3-pip
pip3 install scapy
\# 验证是否安装完成
python3 --version
4 验证 eBPF 支持
\# 检查内核是否支持 eBPF
sysctl kernel.bpf\_enabled
\# 查看 eBPF 挂载点
mount | grep bpf
\# 查看 gala-gopher 支持的命令
gala-gopher --help
\# 查看 TCP 连接
gala-gopher tcp
\# 查看网络连接状态
gala-gopher netstat
\# 查看 eBPF 程序加载情况
gala-gopher bpf list
三、实验内容与步骤
1 核心概念知识科普
1.1 Network Namespace 原理
Linux 系统中,每个进程都运行在一个 Network Namespace 中,每个 Network Namespace 有独立的网络接口、IP 地址空间、路由表、防火墙规则等。Network Namespace 之间默认无法通信,需要通过虚拟网络设备连接。
每个网络命名空间包含以下独立的网络资源:
| 资源类型 | 说明 |
|---|---|
| 网络接口(Network Interface) | 包括物理接口(如 eth0)、虚拟接口(如 veth、tap)及回环接口(lo)。每个命名空间的接口仅对自身可见。 |
| IPv4/IPv6 路由表 | 独立的路由规则,决定数据包的转发路径。 |
| ARP 表 | 独立的 IP-MAC 映射缓存,避免跨命名空间的 ARP 干扰。 |
| 防火墙规则 | iptables/nftables 规则、netfilter 链等,仅对命名空间内的流量生效。 |
| 套接字与端口 | TCP/UDP 端口号独立,同一端口可在不同命名空间中被重复监听。 |
| DNS 解析配置 | /etc/resolv.conf 等解析配置文件在命名空间内独立(需通过挂载隔离实现)。 |
| /proc/net 文件系统 | 如 /proc/net/tcp(TCP 连接状态)、/proc/net/route(路由表)等,内容与命名空间绑定。 |
1.2 eBPF 简介
eBPF 全称 extended Berkeley Packet Filter。一般来说,要向内核添加新功能,需要修改内核源代码或者编写内核模块来实现。而 eBPF 允许程序在不修改内核源代码,或添加额外的内核模块情况下运行。

主要特点:
-
安全:eBPF 程序在运行前会经过严格的验证,确保不会崩溃内核
-
高效:eBPF 程序运行在内核态,避免了用户态和内核态之间的上下文切换
-
灵活:可以动态加载和卸载 eBPF 程序
-
多功能:可以用于网络监控、性能分析、安全审计等多种场景
OpenEuler eBPF 生态:
-
OpenEuler 内核默认启用 eBPF 支持
-
提供了丰富的 eBPF 工具链,包括 BCC、bpftrace 等
-
集成了 gala-gopher 等基于 eBPF 的性能监控工具
2 手工构建 “网络沙盒” (Network Namespace)
2.1 实验原理
不使用 Docker,仅用 ip netns 命令创建两个独立的网络命名空间,理解容器网络隔离的底层原理。
2.2 操作步骤
1. 创建两个 Network Namespace
# 创建名为 ns1 的 Network Namespace
sudo ip netns add ns1
# 创建名为 ns2 的 Network Namespace
sudo ip netns add ns2
# 查看所有 Network Namespace
sudo ip netns list

2. 创建虚拟网线 (veth pair)
\# 创建 veth pair,命名为 veth0 和 veth1
sudo ip link add veth0 type veth peer name veth1
3. 将虚拟网卡分配给 Network Namespace
\# 将 veth1 分配给 ns1
sudo ip link set veth1 netns ns1
\# 将 veth0 分配给 ns2
sudo ip link set veth0 netns ns2
4. 配置 IP 地址
\# 配置 ns1 中 veth1 的 IP 地址
sudo ip netns exec ns1 ip addr add 192.168.100.1/24 dev veth1
\# 配置 ns2 中 veth0 的 IP 地址
sudo ip netns exec ns2 ip addr add 192.168.100.2/24 dev veth0
\# 启动网卡
sudo ip netns exec ns1 ip link set dev veth1 up
sudo ip netns exec ns2 ip link set dev veth0 up
5. 测试网络连通性
# 在 ns1 中 ping ns2
sudo ip netns exec ns1 ping -c 3 192.168.100.2
# 在 ns2 中 ping ns1
sudo ip netns exec ns2 ping -c 3 192.168.100.1

6. 在 Network Namespace 中运行命令

\# 在 ns1 中运行 ip a 命令,查看网络配置
sudo ip netns exec ns1 ip a
\# 在 ns1 中运行 route 命令,查看路由表
sudo ip netns exec ns1 route
7. 清理环境
\# 删除 Network Namespace
sudo ip netns delete ns1
sudo ip netns delete ns2
2.3 实验结果分析
- 成功创建了两个独立的 Network Namespace
- 通过 veth pair 实现了两个 Namespace 之间的网络连通
- 每个 Namespace 有独立的 IP 地址和网络配置
- 验证了 Network Namespace 实现网络隔离的原理
2.4 思考题
思考题 (1)
在本实验中,我们使用 veth pair 直接连接了两个命名空间。如果我们需要连接 10 个命名空间并实现它们之间的互通,继续使用 veth pair 两两相连会有什么问题?工业界(如 Docker/Kubernetes)通常采用什么组件来解决这个问题?
思考题 (2)
当你在主命名空间(Root Namespace)执行 ip link delete veth0 时,分配在 ns1 中的 veth1 会发生什么?为什么?
3 网络透视镜 (eBPF TCP Trace)
3.1 实验原理
eBPF 就像一个内核 “沙箱”,你可以在其中运行经过验证的程序,对内核事件进行监控、过滤和修改。这些程序运行在内核态,拥有极高的性能,同时又受到严格的安全限制,避免对系统造成破坏。
3.2 操作步骤
1. 创建高延迟网络请求模拟脚本
创建文件 high_latency_server.py:
#!/usr/bin/env python3
import socket
import time
# 创建 TCP 服务器
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("0.0.0.0", 9000))
sock.listen(5)
print("高延迟服务器启动,监听 9000 端口...")
while True:
conn, addr = sock.accept()
print(f"接收到来自 {addr} 的连接")
# 模拟高延迟
time.sleep(2)
# 发送响应
conn.send(b"Hello from high latency server!\n")
conn.close()
创建文件 client.py:
#!/usr/bin/env python3
import socket
import time
# 创建 TCP 客户端
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
start_time = time.time()
sock.connect(("127.0.0.1", 9000))
connect_time = time.time()
response = sock.recv(1024)
recv_time = time.time()
print(f"响应内容: {response.decode()}")
print(f"连接耗时: {connect_time - start_time:.3f} 秒")
print(f"接收响应耗时: {recv_time - connect_time:.3f} 秒")
print(f"总耗时: {recv_time - start_time:.3f} 秒")
sock.close()
2. 运行高延迟服务器
python3 high_latency_server.py &
3. 使用 BCC 工具监控 TCP 连接
# 使用 BCC 的 tcpconnect 工具监控 TCP 连接
sudo /usr/share/bcc/tools/tcpconnect
4. 运行客户端脚本
在另一个终端中运行:
在另一个终端中运行:
python3 client.py
5. 查看 eBPF 监控结果
在运行 tcpconnect 工具的终端中,可以看到类似以下输出:
PID COMM IP SADDR DADDR DPORT
12345 python3 4 127.0.0.1 127.0.0.1 9000

6. 使用 bpftrace 监控 TCP 连接
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_connect
{
$sa = (struct sockaddr *)args->uservaddr;
if ($sa->sa_family == 2) { // 2 == AF_INET
$sin = (uint32 *)($sa + 1); // sin_addr
$port = *(uint16 *)((uint8 *)$sin + 4); // sin_port
printf("connect: %-16s -> %s:%d\n",
comm, ntop(2, *$sin), bswap($port));
}
}'

3.3 实验结果分析
- 成功使用 eBPF 程序监控 TCP 连接
- 实时抓取了 TCP 包的源 IP、目的 IP 和处理耗时
- 无需修改应用代码、无需重启进程,实现了无侵入式监控
- 验证了 eBPF 在网络性能分析中的作用
3.4 思考题
思考题 (3)
eBPF 能够实现"无侵入式"监控。请结合实验步骤说明,为什么我们不需要修改 high\_latency\_server.py 的代码,就能观察到它的系统调用耗时?
思考题 (4)
实验中提到 eBPF 程序运行在内核态。如果开发者编写了一个死循环程序并加载到 eBPF 中,会导致 openEuler 系统卡死吗?内核是如何防止这种情况的?
4 实验三:OpenEuler gala-gopher 工具使用
4.1 实验原理
Gala-Gopher 旨在通过融合大数据分析、机器学习、人工智能等前沿技术,打造一个全方位、智能化的运维平台。它专注于对 IT 系统的实时监测、故障预测、性能优化以及自动化运维。
4.2 操作步骤
1. 安装 gala-gopher
sudo dnf install -y gala-gopher
2. 启动 gala-gopher 服务
sudo systemctl start gala-gopher
3. 查看 gala-gopher 状态

sudo systemctl status gala-gopher
4. 使用 gala-gopher 监控网络性能
# 查看 gala-gopher 提供的监控指标
#(列出当前所有指标(含 network))
sudo gala-gopher info
#(只看网络类探针是否加载)
sudo gala-gopher info | grep -i network
# 监控 TCP 连接数
# 一次性拉全部
curl -s http://127.0.0.1:8888/metrics | grep tcp_connections
5. 使用 gala-gopher 生成网络性能报告
# 安装jq工具
sudo dnf install -y jq
# 10 秒内每秒采一次,结果追加到 network_report.json
for i in {1..10}; do
curl -s http://127.0.0.1:8888/metrics | \
jq -c 'select(.name | test("tcp|netdev|network"))' \
>> network_report.json
sleep 1
done
4.3 实验结果分析
- 了解了 OpenEuler 特色 eBPF 工具 gala-gopher 的使用方法
- 掌握了使用 gala-gopher 监控网络性能的技巧
- 验证了 OpenEuler 在 eBPF 生态上的工具支持
4.4 思考题
思考题 (5)
传统工具(如 netstat 或 tcpdump)在处理万兆网卡的高并发流量时往往会导致显著的 CPU 开销,而 gala-gopher 却能保持较低负载。请简述原因。
5 OpenEuler 网络支持的特点
5.1 完整的 eBPF 生态支持
-
内核默认启用 eBPF 支持
-
提供了丰富的 eBPF 工具链
-
集成了特色 eBPF 工具 gala-gopher
5.2 强大的网络隔离能力
-
支持 Network Namespace 等多种网络隔离技术
-
提供了丰富的网络工具,如 iproute2
-
支持容器网络等高级网络功能
5.3 优秀的网络性能
-
优化了网络栈,提高了网络传输性能
-
支持多种网络加速技术
-
提供了丰富的网络性能监控工具
6 实验总结
通过本次实验,我们学习了 OpenEuler 操作系统中网络隔离与 eBPF 观测的基本方法,掌握了以下知识点:
6.1 Network Namespace 原理和使用
-
创建和管理 Network Namespace
-
使用 veth pair 连接不同的 Network Namespace
-
配置 IP 地址和测试网络连通性
-
理解容器网络隔离的底层原理
6.2 eBPF 技术的应用
-
eBPF 的基本概念和原理
-
使用 BCC 和 bpftrace 等工具监控网络
-
编写自定义 eBPF 程序,实现 TCP 延迟监控
-
无需手动编译 eBPF 程序,自动处理所有依赖和类型定义
-
无侵入式监控的实现方法
6.3 OpenEuler 特色工具的使用
-
gala-gopher 工具的安装和使用
-
使用 gala-gopher 监控网络性能
-
生成网络性能报告
6.4 网络性能分析方法
-
模拟高延迟网络请求
-
使用 eBPF 工具分析网络性能
-
识别网络瓶颈和优化方向
6.5 思考题
思考题 (6)
通过本次实验,你认为一个完整的"容器网络"至少需要哪三个关键组件协作?
- 点赞
- 收藏
- 关注作者
评论(0)