文章目录
Network Namespace
提供了与网络相关的系统资源的隔离,包括网络设备、协议栈、路由表、防火墙规则等。Linux网络虚拟化 - Network Namespace 实践中介绍了如何创建netns并使用虚拟网卡设备veth使其连接互联网的方式,然而由于这种方式不便于扩展,因此目前的容器如lxc
、docker
并没有采取这种方式,而是使用桥设备bridge与虚拟网卡配合nat技术,从而实现容器内的网络连接,这也是本文的内容。参考文章:
iptables_man_page,network namespace_man_page,
Linux虚拟网络设备之bridge(桥)
注:本文中的命令全都在Ubuntu18.04-x64server中运行通过,文中绝大多数命令需要root用户执行
步骤实现
- 创建
netns
、一对虚拟网卡设备、桥设备 - 配置桥设备、虚拟网卡设备
- 将其中一个虚拟网卡设备加入
netns
,并配置网关为桥设备 - 配置
nat
实现netns
的网络连接并启用ip_forward
最终创建的网络结构如下图所示,接下来将逐步介绍具体操作。
创建 Network Namespace、虚拟网卡设备veth与桥设备bridge
ip netns、ip link命令简介
Linuxip netns
命令提供了创建、删除netns
、在netns
中执行程序等命令。如下所示:
ip netns add netns_name # 创建 netns
ip netns del netns_name # “删除” netns,仅 umount 对 /var/run/netns 下的 bind mount
ip netns exec netns_name cmd # 在 netns_name 中执行 cmd
ip link
命令提供了添加、删除以及配置网络设备等命令:
link add veth1 type veth peer name veth2 # 添加一对虚拟网卡设备
link add br_name type bridge # 添加一个桥设备
ip link set veth1 netns netns_name # 将虚拟网卡设备添加到netns中
ip
命令非常强大,此处只列出需要用到的一些,感兴趣的可以查阅帮助手册man ip
。
创建netns、veth、bridge
命令如下:
ip link add veth233 type veth peer name veth666 # 创建相连的 veth233 和 veth666
ip link add br0 type bridge # 创建bridge设备 br0
ip netns add netns1 # 创建 netns1
ip link set veth666 netns netns1 # 将 veth666 添加到 netns1 中
配置桥设备、虚拟网卡设备
ifconfig
命令常用来查看、配置设备的网络信息route
命令用来配置不同netns中的路由表brctl
命令可以用来配置桥设备,ip
命令也提供了配置桥设备的命令
配置网络可以使用的命令比较多,这里使用ifconfig
命令配置ip,使用route
命令配置veth666的路由表,使用brctl
命令将虚拟网卡设备添加到br0.
ifconfig br0 192.168.9.1/24 up # 配置桥设备 br0 的ip
brctl addif br0 veth233 # 将 veth233 添加到 br0 上
# veth233无ip,只起到数据传作用
ifconfig veth233 up # 启用 veth233
ip netns exec netns1 ifconfig lo up # 启用 netns1 中的本地环回,非必须
ip netns exec netns1 ifconfig veth666 192.168.9.2/24 up # 启用并配置 netns1 中 veth666 的ip
ip netns exec netns1 route add default gw 192.168.9.1 # 配置 netns1 的默认网关为 br0 的ip
配置好之后,netns1中的数据就可以发送到桥设备br0上了,但由于还没有配置nat,因此桥设备上的数据吧无法发送出去。
配置 nat
iptables 简介
配置nat
要用到iptables
命令,该命令用来配置、维护、监控Linux内核中的ipv4/6数据包过滤(即防火墙)规则表。每个表包含一些内置的或由用户定义的规则链(chaind),每个链的含义不同。每一个规则都定义了一个条件(criteria)和目标(target)。如果数据包(packet)与条件不匹配,则继续查看该链中的下一条规则;如果匹配,则要么执行目标定义的下一条规则,要么执行特殊行为 - ACCETP, DROP 和 RETURN。iptables
命令指令较为复杂,这里简单介绍几个常用的功能,详细介绍参考帮助手册man iptables
或IPTABLES(8)在线手册。
nat表中包含如下四个内置chain:
- PREROUTING
控制收到的数据包 - INPUT
控制发到本地socket(local sockets)的数据包 - OUTPUT
控制本地产生的数据包 - POSTROUTING
控制即将发出去的数据包
nat 表中三个(部分)可用的内置target
- MASQUERADE,用于POSTROUTING
对于匹配的数据包,自动转换ip - SNAT,用于POSTROUTING
转换发送数据包的源地址 - DNAT,用于PREROUTING
转换接收的数据包的目的地址
iptables命令的选项,只能指定其中一个
-t
指定表,包括filter
(默认)、nat
、mangle
、raw
以及security
五个表-A
,--append
chain_name rule,在指定的chain中添加一条规则-D
,--delete
chain_name rule,删除一条规则,其中rule可以为序号(从1开始)-L
,--list
[chain_name],列出表(默认filter)中的所有(或规则链中的)规则,多于与-n
使用,显示ip地址(默认显示主机名)
定义rule时可用的选项
-s
,--source
address[/mask],指定要匹配的数据包的源地址-d
,--destination
address[/mask],同上,指定目的地址-j
,--jump
target,指定数据包匹配时的target(要执行的动作)
使用iptables命令配置nat并启用IP_FORWARD
如下为所需的命令:
iptables -t nat -A POSTROUTING -s 192.168.9.0/24 ! -d 192.168.9.0/24 -j MASQUERADE
# 自动转换所有源地址为 192.168.9.xxx
# 目的地址不是 192.168.9.xxx 的数据包的地址
echo 1 > /proc/sys/net/ipv4/ip_forward # 启用 IP_FORWARD
执行完之后,netns1中应该就可以访问互联网了,可以通过ip netns exec netns1 ping www.baidu.com
验证。需要注意的是,两个命令在计算机重启后都会失效,关于如何永久配置nat与IP_FORWARD的请参考其它文章。
总结
Linux中的Network Namespace
提供了网络资源的隔离,但是默认情况下一个新netns
下是不包含任何网络设备的,因此需要用到较多的网络相关命令进行配置。由于网络配置命令繁多,规则复杂,因此最好先作深入了解再配置。最后,欢迎评论~