1. 前言
不知道什么时候看过一些说法,Linux 这样的网络操作系统......
网络确实是Linux一个非常突出的优势,支持各种各样的网络架构、虚拟接口、软件协议,实在是令人惊叹。个人对于 Linux 网络的探索也是间歇性地进行,各种知识碎片杂乱无章。 深知知识体系的重要性,但目前积累尚浅,亦不可囫囵吞枣,遂在此记录日常经验,以备日后查阅。
2. 路由与流控
2.1 TC 流量控制
TODO
2.2 策略路由 (rule)
TODO
2.3 路由 (route)
TODO
2.4 Netfilter
2.4.1 iptables
TODO
2.4.2 nftables
TODO
参考:
- https://wiki.debian.org/nftables
- https://developers.redhat.com/blog/2016/10/28/what-comes-after-iptables-its-successor-of-course-nftables/
2.5 BPF 包过滤
2.5.1 BPF vs ePBF
TODO
2.5.2 BPF with socket
TODO
2.5.3 BPF with netfilter
TODO
2.5.4 BPFilter
TODO
2.6 硬件NAT (HNAT)
2.6.1 offload 相关
TODO
2.6.2 CTF( Cut Through Forward)
TODO
2.6.3 FastPath(SFE)
TODO
3. 网络接口与地址
3.1 IP 别名(IP Alias)
用途:给一块网卡(接口)配置多个IP地址
示例:
方案1:iproute2
1 2 3 |
ip addr add 192.168.1.123/24 dev eth0 ip addr add 192.168.1.124/24 dev eth0 ifconfig; ip addr show |
方案2: ifconfig
1 2 3 |
ifconfig ifconfig eth0:0 192.168.1.123/24 ifconfig ifconfig eth0:1 192.168.1.124 netmask 255.255.255.0 ifconfig; ip addr show |
备注:无论是使用来自 iproute2 的 ip,还是 net-tools 里面的 ifconfig 工具,都能够完成一样的工作,只是 ifconfig 的风格是增加一个新的别名接口,而 iproute2 不会增加新的虚拟接口。
3.2 虚拟局域网(VLAN)
用途:给某接口配置 VLAN tagging
示例:
方案1:iproute2
1 2 3 4 |
ip link add link eth0 name eth0.100 type vlan id 100 # 添加vlan,id=100 ip link add link eth0 name mylan101 type vlan id 101 # 添加vlan,自定义接口名,id=101 ip link add link eth0.100 name eth0.200 type vlan id 200# 添加 vlan, id=200 (over vlan 100) ip -d link show |
方案2:vconfig
1 2 3 4 |
vconfig add eth0 100 # 添加 vlan, id=100 vconfig add eth0 101 # 添加 vlan, id=101 vconfig add eth0.100 200 # 添加 vlan, id=200 (over vlan 100) ip -d link show |
备注:
- vlan 可以嵌套
- 使用 iproute2 能够自定义 vlan 接口名称
3.3 可扩展虚拟局域网(VxLAN)
TODO
3.4 bridge 接口
用途:配置桥接接口
示例:
1 2 3 4 5 |
brctl addbr br0 brctl addif br0 eth0 brctl show brctl delif br0 eth0 brctl delbr br0 |
3.5 bond 接口
用途:配置多网卡/接口绑定,实现负载均衡、冗余、增加带宽等功能
示例:(以bond0为例)
1 2 3 4 5 6 7 8 9 |
# deprecated: modprobe bonding mode=0 miimon=100 ip link add bond0 type bond mode 0 miimon 100 ---------------------------------------------------------------------- ip link set eth0 master bond0 # 设置两个接口的master接口为bond0 ip link set eth1 master bond0 ip link set bond0 up # 拉起 bond0 接口 ---------------------------------------------------------------------- ip addr flush eth0 # 清空两个接口原有的 IP 地址 ip addr flush eth1 |
备注:
- 只有 bond0 能使单个 TCP/IP 连接的包从多个端口转发出去,因此只有bond0能够让单个 TCP/IP 连接使用大于一个接口的带宽。 但是这样会造成较多数据包 out of order,导致乱序冲传,因此最终有效带宽可能达不到多个接口带宽之和,甚至低于某个接口带宽
- 内核文档表示 bond0 需要交换机将对应的端口配置好 portchannel/etherchannel/trunking 功能,实际上使用无此功能的二层交换机,bond0 也能工作。(有机会找个高端交换机对比一下结果)
- bond4,即 802.3ad 链路聚合,或者又称 LACP,需要交换机支持。比普通的port channel 优势在于协议会协商一些信息,包括一些接口的灵活增减等。但是并不能使单个 TCP/IP 连接使用大于一个接口的带宽,大概工业标准更多地考虑了效率和稳定性。
参考:
https://www.kernel.org/doc/Documentation/networking/bonding.txt
3.6 team 接口
TODO
3.7 TAP 与 TUN
TODO
3.8 veth 接口(与netns)
veth 接口成对使用,主要用于 容器/netns 场景下,在不同 net namespace 之间传输数据。向 veth 一个接口写入数据,该数据将会由内核转发,从另一个 veth 接口出来,将其放置在不同的 netns 内,就可以实现容器与外部的网络通讯。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 创建一堆 veth pair, veth-out 和 veth-in ip link add veth-out type veth peer name veth-in # 创建一个 net namespace: testns ip netns add testns # 将 veth-in 划到 testns 下 ip link set dev veth-in netns testns # 给两个接口分别配置地址 ip addr add dev veth-out 192.168.11.1/24 ip link set dev veth-out up ip netns exec testns ip addr add dev veth-in 192.168.11.2/24 ip netns exec testns ip link set dev veth-in up # 分别在 host 和 netns 中测试 ping 192.168.11.2 ip netns exec testns ping 192.168.11.1 |
此外,不同的 netns 内有隔离的路由表和策略路由规则,因此可用于一些特殊的网络测试。
比如本地的两个网络接口之间传输数据,通过 netns 隔离他们的策略路由 local 表, 即可保证其报文经过外部物理转发(交换机或双绞线直连),而不是走内核直接完成传递,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 给第一个物理接口设置 IP ip addr add dev eth0 192.168.11.1/24 ip link set dev eth0 up # 创建一个 netns ip netns add testns # 将第二个物理接口划到 netns 内,并设置 IP ip link set dev eth1 netns testns ip netns exec testns ip addr add dev eth1 192.168.11.2/24 ip netns exec testns ip link set dev eth1 up # 分别在 host 和 netns 中测试 ping 192.168.11.2 ip netns exec testns ping 192.168.11.1 |
3.9 macvlan 接口
TODO
3.10 macvtap 接口
TODO
3.11 其他接口
gre、ipip、sit、ipvlan....
4. 软件协议
4.1 iproute2
TODO