在 rk3588上通过网络命名空间实现 eth0/eth1 网卡隔离与程序独立部署

一、需求背景与技术原理

1.1 需求场景

RK3588 是瑞芯微推出的高性能嵌入式处理器(四核 Cortex-A76 + 四核 Cortex-A55),广泛用于边缘计算、工业控制、智能设备等场景。在实际开发中,常需让两个程序分别使用独立网卡 (如 eth0 连内网、eth1 连外网),避免网络资源冲突或实现流量隔离------这一需求可通过 Linux 内核原生的 网络命名空间(Network Namespace) 技术实现。

1.2 技术原理

网络命名空间是 Linux 提供的网络资源隔离机制,每个命名空间拥有完全独立的网络栈,包括:

  • 独立的网络接口(如 eth0/eth1);
  • 独立的 IP 地址、子网掩码、网关;
  • 独立的路由表、ARP 缓存、DNS 配置;
  • 独立的 iptables 防火墙规则。

简单来说:给 eth0 和 eth1 分别"分配"一个"专属网络环境",程序在对应环境中运行时,只能看到该环境内的网卡,从而实现"程序-网卡"的绑定隔离。

二、实现步骤(含流程图与命令解析)

2.1 整体流程

先通过流程图明确操作逻辑,再逐步拆解命令细节:
最终网络结构 仅剩lo设备 默认命名空间 ns_eth0 拥有eth0
独立网络配置 ns_eth1 拥有eth1
独立网络配置 开始 创建两个网络命名空间 处理物理网卡 将eth0移至ns_eth0 在ns_eth0中配置eth0 将eth1移至ns_eth1 在ns_eth1中配置eth1 测试网络连通性 在命名空间中运行程序

2.2 分步操作(带命令解析)

前置检查

首先确认 RK3588 系统中已存在 eth0 和 eth1 网卡,且安装了 iproute2 工具(提供 ip 命令,RK3588 主流系统如 Debian/Ubuntu、Buildroot 均预装):

bash 复制代码
# 1. 查看当前网卡列表(确认 eth0/eth1 存在)
ip link show
# 2. 确认 ip 命令可用(若提示"command not found",需安装 iproute2)
# Debian/Ubuntu 系:apt install iproute2
# RedHat/CentOS 系:yum install iproute2
步骤 1:创建网络命名空间

为 eth0 和 eth1 分别创建命名空间 ns_eth0ns_eth1(命名可自定义,建议与网卡对应,便于维护):

bash 复制代码
# 创建命名空间 ns_eth0(用于 eth0)
ip netns add ns_eth0
# 创建命名空间 ns_eth1(用于 eth1)
ip netns add ns_eth1

# 验证命名空间是否创建成功(应显示 ns_eth0 和 ns_eth1)
ip netns list

命令解析ip netns add 是创建命名空间的核心命令,创建后命名空间处于"空"状态,仅包含默认的 lo(回环接口)。

步骤 2:将物理网卡移至对应命名空间

将 eth0 和 eth1 从"根命名空间"(系统默认)移到新创建的命名空间中。

⚠️ 关键提醒 :此操作会立即断开该网卡的现有网络连接,若远程操作 RK3588,需确保操作终端不依赖待转移的网卡(如用串口或另一张网卡连接)。

bash 复制代码
# 将 eth0 移至 ns_eth0 命名空间
ip link set eth0 netns ns_eth0
# 将 eth1 移至 ns_eth1 命名空间
ip link set eth1 netns ns_eth1

# 验证转移结果(根命名空间中已看不到 eth0/eth1,仅显示 lo、wlan0 等)
ip link show
步骤 3:配置命名空间内的网卡与网络

转移后的网卡默认处于"未启用"状态,需进入对应命名空间配置 IP、路由(可选网关)、启用回环接口(lo 接口,部分程序依赖其通信)。

3.1 配置 ns_eth0(eth0 网卡)
bash 复制代码
# 1. 启用 ns_eth0 中的 lo 回环接口(必做,否则部分程序无法正常运行)
ip netns exec ns_eth0 ip link set lo up

# 2. 启用 eth0 网卡
ip netns exec ns_eth0 ip link set eth0 up

# 3. 配置 eth0 的 IP 地址(示例:192.168.1.11/24,需根据实际网段调整)
ip netns exec ns_eth0 ip addr add 192.168.1.11/24 dev eth0

# 4. (可选)配置默认网关(若需访问外网/跨网段,示例网关 192.168.1.1)
ip netns exec ns_eth0 ip route add default via 192.168.1.1 dev eth0

# 验证配置结果(查看 ns_eth0 内的网络状态)
ip netns exec ns_eth0 ip addr show
ip netns exec ns_eth0 ip route show  # 查看路由表
3.2 配置 ns_eth1(eth1 网卡)

操作逻辑与 ns_eth0 一致,仅需调整 IP (避免与 eth0 冲突):

bash 复制代码
# 1. 启用 lo 接口
ip netns exec ns_eth1 ip link set lo up

# 2. 启用 eth1 网卡
ip netns exec ns_eth1 ip link set eth1 up

# 3. 配置 IP(示例:192.168.1.12/24,与 eth0 同网段但不冲突)
ip netns exec ns_eth1 ip addr add 192.168.1.12/24 dev eth1

# 4. (可选)配置默认网关(若 eth1 连另一网段,网关需对应调整)
ip netns exec ns_eth1 ip route add default via 192.168.1.1 dev eth1

# 验证配置
ip netns exec ns_eth1 ip addr show
ip netns exec ns_eth1 ip route show

命令解析ip netns exec <命名空间> <命令> 是"进入命名空间执行命令"的核心语法,相当于在该命名空间的"独立网络环境"中操作。

三、网络验证与程序运行

3.1 验证网络连通性

配置完成后,需确认两个命名空间的网络是否独立且正常:

1. 命名空间内自验证(ping 网关/外网)
bash 复制代码
# 验证 ns_eth0 网络(ping 网关 192.168.1.1,3次包)
ip netns exec ns_eth0 ping -c 3 192.168.1.1

# 验证 ns_eth1 网络(ping 外网 DNS 8.8.8.8,需配置网关)
ip netns exec ns_eth1 ping -c 3 8.8.8.8
2. 命名空间间隔离验证(ping 对方 IP)

若需两个命名空间完全隔离,可测试是否能 ping 通对方 IP:

bash 复制代码
# 在 ns_eth0 中 ping ns_eth1 的 IP(192.168.1.12)
ip netns exec ns_eth0 ping -c 3 192.168.1.12
  • 若需"隔离":ping 不通为正常(可通过 iptables 进一步限制);
  • 若需"互通":ping 通为正常(需确保同网段且无防火墙规则拦截)。

3.2 在指定命名空间中运行程序

通过 ip netns exec 命令,让程序在对应命名空间中运行,程序将仅能使用该命名空间内的网卡(如 ns_eth0 中的程序只能用 eth0)。

示例 1:运行简单命令(如 Python 服务)
bash 复制代码
# 在 ns_eth0 中运行一个监听 eth0 IP 的 Python 服务(示例端口 8080)
ip netns exec ns_eth0 python3 -m http.server 8080 --bind 192.168.1.11 &

# 在 ns_eth1 中运行另一个服务(监听 eth1 IP,端口 8081)
ip netns exec ns_eth1 python3 -m http.server 8081 --bind 192.168.1.12 &
示例 2:运行后台服务(如 Nginx)

若需让服务默认在指定命名空间运行,可修改服务启动脚本,在启动命令前添加 ip netns exec <命名空间>

bash 复制代码
# 编辑 Nginx 启动脚本(示例路径 /etc/init.d/nginx)
# 将启动命令改为:ip netns exec ns_eth0 /usr/sbin/nginx

提醒& 符号用于将程序放入后台运行,若需前台调试可去掉;若程序需长期运行,建议结合 systemdsupervisor 管理(见下文"持久化配置")。

四、关键配置补充(DNS/持久化)

4.1 DNS 配置(解决域名解析问题)

默认情况下,命名空间内无 DNS 配置,程序无法解析域名(如 ping google.com 会失败)。需为每个命名空间单独配置 DNS:

方法:创建命名空间专属 resolv.conf

Linux 系统会优先读取 /etc/netns/<命名空间>/resolv.conf 作为该命名空间的 DNS 配置,步骤如下:

bash 复制代码
# 1. 为 ns_eth0 创建 DNS 配置目录并写入 DNS 服务器
mkdir -p /etc/netns/ns_eth0
echo "nameserver 8.8.8.8" > /etc/netns/ns_eth0/resolv.conf  # 谷歌DNS
echo "nameserver 114.114.114.114" >> /etc/netns/ns_eth0/resolv.conf  # 国内DNS

# 2. 为 ns_eth1 配置 DNS(同上)
mkdir -p /etc/netns/ns_eth1
echo "nameserver 8.8.8.8" > /etc/netns/ns_eth1/resolv.conf
echo "nameserver 114.114.114.114" >> /etc/netns/ns_eth1/resolv.conf

# 验证 DNS 配置(在命名空间中解析域名)
ip netns exec ns_eth0 nslookup baidu.com

4.2 持久化配置(解决重启失效问题)

通过命令行配置的网络命名空间,在 RK3588 重启后会完全失效。需将配置命令写入系统启动脚本,实现开机自动配置。

方案 1:通过 rc.local 实现(适合无 systemd 的嵌入式系统)
  1. 检查并创建 /etc/rc.local(部分系统默认无此文件):

    bash 复制代码
    # 1. 创建 rc.local 并赋予执行权限
    touch /etc/rc.local
    chmod +x /etc/rc.local
    
    # 2. 编辑 rc.local,添加配置命令(需确保命令顺序正确)
    cat > /etc/rc.local << EOF
    #!/bin/sh
    # RK3588 网络命名空间持久化配置
    
    # 1. 清理旧命名空间(避免重复创建)
    ip netns delete ns_eth0 2>/dev/null
    ip netns delete ns_eth1 2>/dev/null
    
    # 2. 创建新命名空间
    ip netns add ns_eth0
    ip netns add ns_eth1
    
    # 3. 转移网卡
    ip link set eth0 netns ns_eth0
    ip link set eth1 netns ns_eth1
    
    # 4. 配置 ns_eth0
    ip netns exec ns_eth0 ip link set lo up
    ip netns exec ns_eth0 ip link set eth0 up
    ip netns exec ns_eth0 ip addr add 192.168.1.11/24 dev eth0
    ip netns exec ns_eth0 ip route add default via 192.168.1.1 dev eth0
    
    # 5. 配置 ns_eth1
    ip netns exec ns_eth1 ip link set lo up
    ip netns exec ns_eth1 ip link set eth1 up
    ip netns exec ns_eth1 ip addr add 192.168.1.12/24 dev eth1
    ip netns exec ns_eth1 ip route add default via 192.168.1.1 dev eth1
    
    # 6. (可选)启动命名空间内的程序
    ip netns exec ns_eth0 python3 -m http.server 8080 --bind 192.168.1.11 &
    ip netns exec ns_eth1 python3 -m http.server 8081 --bind 192.168.1.12 &
    
    exit 0
    EOF
  2. 启用 rc.local(部分系统需手动关联到启动流程):

    bash 复制代码
    # 若系统用 systemd,需创建 rc-local.service 并启用
    ln -s /etc/rc.local /etc/init.d/rc.local
    systemctl enable rc-local
    systemctl start rc-local
方案 2:通过 systemd 服务实现(推荐,适合有 systemd 的系统)
  1. 创建 systemd 服务文件 /etc/systemd/system/netns-setup.service

    ini 复制代码
    [Unit]
    Description=RK3588 Network Namespace Setup for eth0/eth1
    After=network.target  # 确保网络服务启动后再执行
    
    [Service]
    Type=oneshot  # 一次性执行(配置完成后退出)
    ExecStart=/bin/bash -c "
        # 清理旧命名空间
        ip netns delete ns_eth0 2>/dev/null;
        ip netns delete ns_eth1 2>/dev/null;
        # 创建命名空间
        ip netns add ns_eth0;
        ip netns add ns_eth1;
        # 转移网卡
        ip link set eth0 netns ns_eth0;
        ip link set eth1 netns ns_eth1;
        # 配置 ns_eth0
        ip netns exec ns_eth0 ip link set lo up;
        ip netns exec ns_eth0 ip link set eth0 up;
        ip netns exec ns_eth0 ip addr add 192.168.1.11/24 dev eth0;
        ip netns exec ns_eth0 ip route add default via 192.168.1.1 dev eth0;
        # 配置 ns_eth1
        ip netns exec ns_eth1 ip link set lo up;
        ip netns exec ns_eth1 ip link set eth1 up;
        ip netns exec ns_eth1 ip addr add 192.168.1.12/24 dev eth1;
        ip netns exec ns_eth1 ip route add default via 192.168.1.1 dev eth1;
        # 启动程序(可选)
        ip netns exec ns_eth0 python3 -m http.server 8080 --bind 192.168.1.11 &;
        ip netns exec ns_eth1 python3 -m http.server 8081 --bind 192.168.1.12 &;
    "
    
    [Install]
    WantedBy=multi-user.target  # 多用户模式下启用
  2. 启用并启动服务:

    bash 复制代码
    # 重新加载 systemd 配置
    systemctl daemon-reload
    # 设置开机自启
    systemctl enable netns-setup.service
    # 立即执行配置
    systemctl start netns-setup.service

五、恢复默认配置与风险提示

5.1 临时恢复(不重启)

若需暂时取消隔离,将网卡移回根命名空间:

bash 复制代码
# 1. 将 eth0 从 ns_eth0 移回根命名空间(根命名空间的 PID 为 1)
ip netns exec ns_eth0 ip link set eth0 netns 1
# 2. 将 eth1 从 ns_eth1 移回根命名空间
ip netns exec ns_eth1 ip link set eth1 netns 1
# 3. 删除旧命名空间
ip netns delete ns_eth0
ip netns delete ns_eth1
# 4. (可选)重新配置根命名空间的网卡
ip link set eth0 up
ip addr add 192.168.1.200/24 dev eth0  # 根命名空间的 IP

5.2 风险提示

  1. 网卡丢失风险:若直接删除命名空间而未移回网卡,网卡会被"隐藏"(需重启系统恢复),操作前务必确认网卡转移命令;
  2. 远程操作风险:若通过 eth0/eth1 远程连接 RK3588,转移该网卡会导致连接断开,建议通过串口或备用网卡操作;
  3. IP 冲突风险:命名空间内的 IP 需与所在网段无冲突,且两个命名空间的 IP 不可重复。

六、常见问题排查

问题现象 可能原因 排查命令
命名空间内 ping 不通网关 1. 网卡未启用;2. 路由未配置;3. 网关不可达 ip addr show(看网卡状态)、ip route show(看路由)、ping 网关IP(测试网关)
程序无法解析域名 DNS 未配置 cat /etc/netns/<命名空间>/resolv.conf(检查 DNS)、nslookup baidu.com(测试解析)
重启后配置失效 未做持久化配置 检查 rc.local 权限或 systemd 服务是否启用(systemctl is-enabled netns-setup
转移网卡后根命名空间无网卡 网卡已移至命名空间(正常现象) ip netns exec <命名空间> ip addr 查看网卡
两个命名空间无法互通 iptables 规则拦截或路由未配置 ip netns exec <命名空间> iptables -L(查看规则)、ip route show(确认路由)

七、总结

通过网络命名空间技术,可在 RK3588 上轻松实现 eth0/eth1 的隔离与程序绑定,核心步骤为"创建命名空间→转移网卡→配置网络→运行程序"。实际应用中,需结合 DNS 配置和持久化方案,确保服务稳定运行;若遇到问题,可通过本文"常见问题排查"部分快速定位原因。

若需进一步实现更精细的网络控制(如流量限制、端口转发),可在命名空间内结合 iptablestc(流量控制)工具扩展功能。

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334663 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
网络研究院3 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展