Skip to content

Commit

Permalink
更新第三章内核内容
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Jun 23, 2024
1 parent 8cdb999 commit 6179385
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 20 deletions.
56 changes: 56 additions & 0 deletions network/XDP.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,62 @@ XDP 本质上是 Linux 内核网络模块中的一个 BPF Hook,能够动态挂
图 3-13 XDP 处理数据包的过程
:::

XDP 在业界最出名的一个应用场景就是 Facebook 基于 XDP 实现高效的防 DDoS 攻击,其本质上就是实现尽可能早地实现“丢包”,而不去消耗系统资源创建完整的网络栈链路。

那么,我们第一个 XDP 程序就来模拟防 DDoS 最重要的操作,丢弃所有的数据包。编写下面的代码,确保你的内核不低于 4.15,且已安装好相应的编译工具。

```c
#include <linux/bpf.h>
/*
* Comments from Linux Kernel:
* Helper macro to place programs, maps, license in
* different sections in elf_bpf file. Section names
* are interpreted by elf_bpf loader.
* End of comments
* You can either use the helper header file below
* so that you don't need to define it yourself:
* #include <bpf/bpf_helpers.h>
*/
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("xdp")
int xdp_drop_the_world(struct xdp_md *ctx) {
// drop everything
// 意思是无论什么网络数据包,都drop丢弃掉
return XDP_DROP;
}
char _license[] SEC("license") = "GPL";
```
接下来就是编译工作了,利用 clang 命令行工具配合后端编译器 LLVM 来进行操作。
```bash
$ clang -O2 -target bpf -c xdp-drop-world.c -o xdp-drop-world.o
```

加载 XDP 程序要用到 ip 这个命令行工具,它能帮助我们将程序加载到内核的 XDP Hook 上。

```bash
[root@Node1 ~]# link set dev [device name] xdp obj xdp-drop-world.o
[root@Node2 ~]# ping 192.168.1.3
PING 192.168.1.3 (192.168.1.3): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
```

上面的命令中,[device name] 是本机某个网卡设备的名称。将 XDP 程序加载到内核后,从外部 ping 名为[device name] 网卡的 IP,你将看到完全 ping 不通。

接下来,将 XDP 程序从网卡卸载,你会看到 ping 又正常了。

```bash
[root@Node1 ~]# link set dev [device name] xdp off
[root@Node2 ~]# ping 192.168.1.3
PING 192.168.1.3 (192.168.1.3): 56 data bytes
64 bytes from 192.168.1.3: icmp_seq=0 ttl=53 time=42.608 ms
64 bytes from 192.168.1.3: icmp_seq=1 ttl=53 time=43.902 ms
64 bytes from 192.168.1.3: icmp_seq=2 ttl=53 time=42.829 ms
```

## 2. XDP 应用示例

前面讲过的 conntrack 是 Netfilter 在 Linux 内核中的连接跟踪实现。换句话说,只要具备了 hook 能力,能拦截到进出主机的每个数据包,就完全可以摆脱 Netfilter,实现另外一套连接跟踪。
Expand Down
12 changes: 7 additions & 5 deletions network/linux-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

物理网络中,如果需要连接多个主机,我们会使用网桥(也可以理解为交换机)设备组成一个小型局域网。Linux 网络虚拟化系统中,也提供了网桥虚拟实现 —— Linux Bridge。

Linux Bridge 是 Linux 内核 2.2 版本开始提供的二层转发工具。Linux Bridge 创建以后,一头连着内核协议栈,另一端可以连接多个二层网络设备(Veth、TAP 等等)。
Linux Bridge 是 Linux 内核 2.2 版本开始提供的二层转发工具。Linux Bridge 创建以后,一头连着内核协议栈,另一端可以连接多个二层网络设备(Veth、TAP,宿主的物理网卡 eth0 也可以)。

注意的是,网络设备桥接到 “交换机” ,它的 IP 及 MAC 都不再可用了退化为 Linux Bridge 的一个端口了
注意的是,当网络设备桥接到 “交换机” ,它的 IP 及 MAC 都不再可用了退化为 Linux Bridge 的一个端口了。

:::center
![](../assets/linux-bridge.svg)<br/>
Expand All @@ -18,10 +18,12 @@ Linux Bridge 与物理交换机的转发行为是完全一致的,当有二层
- 地址转发表(FDB,Forwarding Database)中找不到该 MAC 地址(网桥与交换机类似,会学习 MAC 地址与端口的映射),则洪泛(Flooding)给所有接入网桥的设备,并把响应设备的接口与 MAC 地址学习到自己的 MAC 地址转发表中;
- 地址转发表中找到了 MAC 地址,则直接转发到地址表中指定的设备。

Linux Bridge 与普通物理交换机非常相似,但还是有点区别,普通的交换机只会做二层转发,**Linux Bridge 还能配置 IP**。网桥设置了 IP 地址的话,就变成 Linux 中的网络设备。Linux 中的网络设备收到数据包,不会转发到任何设备,而是直接交给内核(三层)协议栈处理。
Linux Bridge 与普通物理交换机非常相似,但还是有点区别,普通的交换机只会做二层转发,**Linux Bridge 还能配置 IP**。网桥设置了 IP 地址的话,就变成 Linux 中的网络设备。

上述设计,最基本的作用是将容器内数据包发出去,笔者举个例子。假设,某个容器配置的网关为 192.168.9.1(Linux bridge 的 IP),然后构造一个目的地为 Node2 IP 的数据包。发出去的数据包先到达 Linux bridge。Linux bridge 作为网络设备将数据包送到主机协议栈
Linux 中的网络设备收到数据包,不会转发到任何设备,而是直接交给内核(三层)协议栈处理

由于目的 IP 是外网 IP,且宿主机开启了 IP forward 功能,于是数据包会通过 eth0 发送出去。
通过上述的能力,是实现容器间通信的第一步“将数据包从容器内发出去”。举个例子,假设某个容器 A 配置的网关为 192.168.9.1(Linux bridge 的 IP),容器 A 向另外一台主机发起请求。发出去的数据包先到达 Linux bridge,因为 Linux bridge 是一个网络设备,因此它收到数据包之后会送到主机协议栈。

由于目的 IP 是外网 IP,且主机开启了 IP forward 功能,最后数据包通过主机 eth0 发送出去。


4 changes: 2 additions & 2 deletions network/macvlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ MACVLAN 是介绍的最后一种虚拟设备,在介绍 MACVLAN 先学习点前

两个 VLAN 之间位于独立的广播域,是完全二层隔离的,通信就只能通过三层设备。

:::tip
本书 7.3 节《容器间通信模型》介绍 Calico(BGP)、Flannel(host-gw)这两种三层路由网络模型时,提到它们的缺点不能跨 VLAN。而 Flannel(VXLAN)、Calico(IPIP)通过构建内层虚拟网,并借助宿主机三层网络实现容器间通信,从而可以跨越 VLAN,背景就是在这里。
:::tip 本书内容关联
本书 7.3 节《容器间通信模型》介绍 Calico(BGP)、Flannel(host-gw)这两种三层路由网络模型时,提到它们的缺点不能跨 VLAN。而 Flannel(VXLAN)、Calico(IPIP)通过构建内层虚拟网,并借助主机三层网络实现容器间通信,从而可以跨越 VLAN,背景就是在这里。
:::

假设位于 VLAN-A 中的主机 A1,希望把数据包发送给 VLAN-B 中的主机 B1,由于 A、B 两个 VLAN 之间二层链路不通,因此引入了单臂路由。单臂路由不属于任何 VLAN,它与交换机之间的链路允许任何 VLAN ID 的数据包通过,交换机之间互联用的端口也被称为 TRUNK 端口。
Expand Down
4 changes: 2 additions & 2 deletions network/network-namespace.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Linux 内核源于对资源隔离的需求,从 2.4.19 版本起陆续开始支
图 3-19 网络命名空间
:::

由于每个容器都有自己的网络服务,在网络命名空间的作用下,这就使得一个主机内运行两个同时监听 80 端口的 Nginx 服务成为可能(当然,外部访问还需宿主机 NAT)。
由于每个容器都有自己的网络服务,在网络命名空间的作用下,这就使得一个主机内运行两个同时监听 80 端口的 Nginx 服务成为可能(当然,外部访问还需主机进行 NAT 操作)。

Linux ip 工具的子命令 netns 集成了网络命名空间的增删查改功能,下面使用 ip 命令进行操作演示,以便读者加深理解。

Expand Down Expand Up @@ -42,6 +42,6 @@ Chain OUTPUT (policy ACCEPT)
target prot opt source destination
```

由于不同的命名空间之间相互隔离,所以同一个宿主机之内的命名空间并不能直接通信**如果想与外界(譬如其他网络命名空间、宿主机)进行通信,就需要在命名空间里面插入虚拟网卡/网线(Veth-Pair**,然后再把网线的另一头桥接到 Linux Bridge。
由于不同的命名空间之间相互隔离,所以同一个主机之内的命名空间并不能直接通信**如果想与外界(其他网络命名空间、主机)进行通信,就需要在命名空间里面插入虚拟网卡/网线(veth-pair**,然后再把网线的另一头桥接到 Linux Bridge。

没错,这些操作完全和物理环境中的局域网配置一样,只不过全部是虚拟的、用软件实现的而已。
12 changes: 5 additions & 7 deletions network/virtual-nic.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@

TUN/TAP 不是一个设备,而是两个相对独立的虚拟网络设备:
- 其中 TAP 模拟了以太网设备,操作的是数据帧,工作在 L2;
- TUN 则模拟了网络层设备,操作的是 IP 报文
- TUN 则模拟了网络层设备,操作的是 IP 数据包,工作在 L3

我们可以把 TUN/TAP 理解为一端连着网络协议栈,另一端连着用户态程序,这种能力可以将 TCP/IP 协议栈处理好的网络包发送给任何一个使用 TUN/TAP 驱动的用户进程。**协议栈中的数据包原本被发送到 eth0 设备或者其他借口,现在转发到用户态程序,用户态程序对它加工处理,从而实现数据压缩、流量加密、透明代理等功能**

如图 3-20 示例,应用程序通过 TUN 发送数据包,TUN 设备发现另一端被 VPN 程序关联,便会通过字符设备发送给 VPN,VPN 收到数据包,修改报文,然后作为报文 payload,封装到另一个发送给 B 地址的新报文中。
如图 3-20 示例,应用程序通过 TUN 发送数据包,TUN 设备发现另一端被 VPN 程序关联,便会通过字符设备发送给 VPN,VPN 收到数据包之后修改内容,然后封装到另一个发送给 B 地址的新报文中。

:::center
![](../assets/tun.svg)<br/>
图 3-20 VPN 中数据流动示意图
:::



:::tip <a/>
这种将一个数据包封装到另一个数据包的处理方式被称为 “隧道”。隧道技术是构建虚拟逻辑网络的经典做法,OpenVPN、Vtun、Flannel UDP 模式 等都是基于 TUN/TAP 实现隧道封装的。
:::
Expand All @@ -31,21 +29,21 @@ Veth 是另一种主流的虚拟网卡方案,在 Linux Kernel 2.6 版本支持

**简单理解 Veth 就是一根带两个 Ethernet 网卡的`网线`,从一头发数据,另一头收数据,如果 veth-1 和 veth-2 是一对 Veth 设备,veth-1 发送的数据会由 veth-2 收到,反之亦然**

所以严格来说 Veth 也是一对设备,因而也常被称作 Veth-Pair
所以严格来说 Veth 也是一对设备,因而也常被称作 veth-pair

:::center
![](../assets/veth.svg)<br/>
图 3-21 Veth 设备对
:::

因为 Veth 这个特性,它常常充当着一个桥梁,连接着宿主机内的虚拟网络,典型的例子像两个隔离的网络命名空间之间的连接、Linux Bridge 和 OVS (Open vSwitch)之间的连接等,通过这种方式,从而构建出复杂的虚拟网络拓扑架构。
因为 Veth 这个特性,它常常充当着一个桥梁,连接着同主机内的虚拟网络,典型的例子像两个隔离的网络命名空间之间的连接、Linux Bridge 和 OVS (Open vSwitch)之间的连接等,通过这种方式,从而构建出复杂的虚拟网络拓扑架构。

:::center
![](../assets/cni0.svg)<br/>
图 3-22 Pod 通过 Veth 互联以及桥接到 Linux Bridge
:::

我们在 Kubernetes 宿主机中查看网卡设备,总能看到一堆 Veth 开头的网卡设备信息,这些就是为不同 Pod 之间通信而创建的虚拟网卡。
我们在 Kubernetes 主机中查看网卡设备,总能看到一堆 Veth 开头的网卡设备信息,这些就是为不同 Pod 之间通信而创建的虚拟网卡。

```plain
$ ip addr
Expand Down
6 changes: 2 additions & 4 deletions network/vxlan.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 3.5.4 VXLAN

有了各类虚拟设备之后,下一步就是要使用这些设备组成网络,由于跨主机的通信绝大多数都是 overlay 网络,所以本节内容,笔者以 VXLAN 为例介绍 overlay 网络原理。
有了各类虚拟设备之后,下一步就是要使用这些设备组成网络,由于跨主机的通信绝大多数都是 overlay 网络,所以本节内容,我将以 VXLAN 为例介绍 overlay 网络原理。

:::tip 什么是 overlay 网络
overlay 网络是通过封装技术将数据包封装在另一个数据包中,从而在现有网络(underlay 网络)之上创建一个逻辑网络。overlay 网络在虚拟化环境中非常有用,它可以连接分布在不同物理位置的虚拟机、容器、节点等,使它们在一个局域网内一样通信。下面即将介绍的 VXLAN、负载均衡章节中的 IPIP 都属于 overlay 网络。
Expand Down Expand Up @@ -45,8 +45,6 @@ VXLAN 的通信原理如图 3-26 所示,源服务器发出的原始数据帧
图 3-26 VXLAN 通信概览
:::

VXLAN 对网络基础设施的要求很低,不需要专门的硬件只要三层可达的网络就可以部署 VXLAN。

Linux 对 VXLAN 协议的支持时间并不久,2012 年 Stephen Hemminger 把相关的工作合并到 kernel 中,并最终出现在 kernel 3.7.0 版本。 到了 kernel 3.12 版本,Linux 对 VXLAN 的支持已经完备,支持单播和组播,IPv4 和 IPv6。

VXLAN 带来了很高的灵活性、扩展性和可管理性,已经成为当前构建数据中心的主流技术,绝大多数的公有云的 VPC 都是用 VXLAN 来作为数据转发层面。
VXLAN 对网络基础设施的要求很低,不需要专门的硬件只要三层可达的网络就可以部署 VXLAN,具有很高的灵活性、扩展性和可管理性,已经成为当前构建数据中心的主流技术,绝大多数的公有云的 VPC 都是用 VXLAN 来作为数据转发层面。

0 comments on commit 6179385

Please sign in to comment.