在Linux系统中配置容器网络,核心是利用内核提供的网络虚拟化能力,将进程的网络栈与宿主机分离,再通过虚拟网卡和桥接设备把它们连接起来。这通常涉及network_namespace、veth pair、Linux bridge以及iptables等组件。

一、理解容器网络的基础组件
容器网络并不是凭空出现的,它建立在Linux内核的几个特性之上。其中最重要的是network_namespace,它可以让一组进程拥有独立的网络栈,包括网卡、路由表、iptables规则等。两个不同的命名空间之间默认完全隔离,就像两台互不相通的机器。
为了让隔离的容器能通信,我们需要veth pair。veth是一对虚拟以太网设备,总是成对出现,从一个发出去的数据包会直接到达另一个。通常我们会把veth的一端放进容器的命名空间,另一端挂在宿主机的Linux bridge上,bridge相当于一台软件交换机,把多个容器连到同一个二层网络里。
此外,容器要访问外网,还得依靠宿主机的NAT能力。通过iptables的MASQUERADE规则,可以把容器发出的包源地址改写成宿主机地址,回来时再改回去。下面这张表列出了常见组件的作用:
| 组件 | 作用 |
|---|---|
| network_namespace | 提供隔离的网络栈 |
| veth pair | 跨命名空间传输数据 |
| Linux bridge | 连接多个容器到同一网络 |
| iptables NAT | 实现容器访问外网 |
二、手动创建并配置容器网络
下面我们一步步在Linux上手动配置一个最简单的桥接容器网络。假设宿主机上还没有任何容器工具,完全用iproute2和bridge-utils来完成。首先创建一个bridge并分配IP:
# 创建桥接设备 sudo ip link add name br0 type bridge sudo ip addr add 192.168.100.1/24 dev br0 sudo ip link set br0 up
接着我们创建一个新的network_namespace来模拟容器,并创建veth pair:
# 创建命名空间 sudo ip netns add container1 # 创建veth pair sudo ip link add veth-host type veth peer name veth-container # 将一端放入命名空间 sudo ip link set veth-container netns container1 # 宿主机端挂到桥上 sudo ip link set veth-host master br0 sudo ip link set veth-host up
然后在容器命名空间内配置IP和路由,让它把br0作为网关:
# 进入容器命名空间配置网络 sudo ip netns exec container1 ip addr add 192.168.100.2/24 dev veth-container sudo ip netns exec container1 ip link set veth-container up sudo ip netns exec container1 ip link set lo up sudo ip netns exec container1 ip route add default via 192.168.100.1
此时容器已经能和宿主机通信,但还不能上外网。我们需要在宿主机上开启IP转发并配置MASQUERADE:
# 开启转发 sudo sysctl -w net.ipv4.ip_forward=1 # 配置NAT sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE
这样container1就能通过宿主机的eth0访问互联网了。这种方式的优点是非常透明,每一步出了错都能用ip netns exec进去排查;缺点是需要手动管理生命周期,适合理解原理或做定制网络。
三、常见问题与排查思路
配置时最容易遇到容器间不通或者出不了网。先检查veth两端是否都处于up状态,以及bridge是否真的把宿主机端veth收进来了。可以用bridge link查看,如果看不到veth-host,说明master没设成功。
另一个坑是iptables规则顺序。如果宿主机本身有REJECT规则在MASQUERADE之前,容器流量可能被挡掉。建议把NAT规则放在nat表开头,并用iptables -t nat -L -n -v看命中计数。此外,若容器访问特定服务失败,要确认宿主机是否开启了反向路径过滤,可临时设net.ipv4.conf.all.rp_filter=0测试。
对于多容器场景,可以给每个容器分配独立namespace和veth,都挂到同一个br0。若需要隔离不同组容器,就建多个bridge,并利用iptables在forward链做访问控制。理解这些后,即便不用Docker的默认网络,也能按业务需求灵活组网。
四、与容器引擎默认网络的对比
Docker之类的引擎默认用的是bridge驱动,本质上也是上面这一套,只是它自动创建了docker0并写了iptables规则。手动配置的好处是你能精确控制子网、MTU和NAT策略,比如避免和公司内部网段冲突。
如果你的应用对网络性能敏感,还可以考虑用macvlan或ipvlan替代bridge,让容器直接挂载到物理网卡上,减少一层软件交换。但macvlan配置时容器不能和宿主机在同一子网直接通信,需要额外路由。选择哪种方案,取决于你是要简单隔离,还是要逼近线速转发。
掌握Linux原生网络工具,是排查一切容器网络故障的底气。无论上层用什么编排系统,往下剥开都是namespace、veth和iptables。
Linux容器网络network_namespace修改时间:2026-08-02 23:18:32