Skip to content

Commit

Permalink
fix typo
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Feb 4, 2025
1 parent d81c975 commit a384d16
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Observability/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ http_request_total 5
- **数据保留策略**:时序数据具有明确的生命周期(监控数据只需要保留几天)。为防止存储空间无限膨胀,时序数据库通常支持自动化的数据保留策略。比如设置基于时间的保留规则,超过 7 天就会自动删除。


Prometheus 服务端内置了强大的时序数据库(与 Prometheus 同名),“强大”并非空洞的描述,它在 DB-Engines 排行榜中常年稳居前三[^1]。该数据库提供了专为时序数据设计的查询语言 PromQL(Prometheus Query Language),可轻松实现指标的查询、聚合、过滤和计算等操作。掌握 PromQL 语法是指标可视化和告警处理的基础,笔者就不再详细介绍语法细节,具体可以参考 Prometheus 文档。
Prometheus 服务端内置了强大的时序数据库(与 Prometheus 同名),“强大”并非空洞的描述,它在 DB-Engines 排行榜中常年稳居前三[^1]。该数据库提供了专为时序数据设计的查询语言 PromQL(Prometheus Query Language),可轻松实现指标的查询、聚合、过滤和计算等操作。掌握 PromQL 语法是指标可视化和告警处理的基础,笔者就不再详细介绍其语法细节了,具体可以参考 Prometheus 文档。

## 4. 使用指标

Expand Down
35 changes: 15 additions & 20 deletions network/conntrack.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,35 @@
# 3.3.3 连接跟踪模块 conntrack

conntrack 是“连接跟踪”(connection track)的缩写。
conntrack 是“连接跟踪”(connection tracking)的缩写,顾名思义,它用于跟踪 Linux 内核中的通信连接。需要注意的是,conntrack 跟踪的“连接”不仅限于 TCP 连接,还包括 UDP、ICMP 等类型的连接。当 Linux 系统收到数据包时,conntrack 模块会为其创建一个新的连接记录,并根据数据包的类型更新连接状态,如 NEW、ESTABLISHED 等

顾名思义,Linux 内核中的 conntrack 模块是用来跟踪“连接”的。需要注意的是,conntrack 中的“连接”指的是通信双方之间的数据传输连接,不仅跟踪 TCP 连接,还可以跟踪 UDP、ICMP 这样的“连接”。当 Linux 系统收到数据包时,内核中的 conntrack 模块为其新建一个(或标识属于某个)连接记录(或称连接条目),并根据数据包类型更新连接状态(如 NEW、ESTABLISHED 等)。
TCP 三次握手为例,说明 conntrack 模块的工作原理 :

举一个 TCP 三次握手的例子:
- 首先,客户端向服务器发送一个 TCP SYN 包请求建立连接。
- Linux 系统收到 TCP SYN 包时,内核中的 conntrack 模块为其创建一个新的连接记录,并将状态标记成 NEW。
- 随后,服务器回复一个 SYN-ACK,等待客户端的 ACK 报文。一旦 TCP 握手完成,连接记录中的状态变成 ESTABLISHED。

通过命令 cat /proc/net/nf_conntrack 查看连接记录,输出了一个连接类型为 TCP,连接状态为 ESTABLISHED 的连接记录。
1. 客户端向服务器发送一个 TCP SYN 包,发起连接请求。
2. Linux 系统收到 SYN 包后,conntrack 模块为其创建新的连接记录,并将状态标记为 NEW。
3. 服务器回复 SYN-ACK 包,等待客户端的 ACK。一旦握手完成,连接状态变为 ESTABLISHED。

通过命令 cat /proc/net/nf_conntrack 查看连接记录,如下所示,输出了一个状态为 ESTABLISHED 的 TCP 连接。
```bash
$ cat /proc/net/nf_conntrack
ipv4 2 tcp 6 88 ESTABLISHED src=10.0.12.12 dst=10.0.12.14 sport=48318 dport=27017 src=10.0.12.14 dst=10.0.12.12 sport=27017 dport=48318 [ASSURED] mark=0 zone=0 use=2
```

conntrack 连接记录是 iptables 连接状态匹配的基础,也是实现 SNAT 和 DNAT 的前提。

我们知道 Kubernetes 的核心组件 kube-proxy,作用是负责处理集群中的服务(Service)网络流量。它的本质其实是个反向代理(也就是 NAT)。当外部请求访问 Service 时,请求被 DNAT 成 PodIP:Port,响应时再经过 SNAT。

举一个具体的例子,客户端向 my-service(IP 10.0.0.10 )发送 HTTP 请求,端口 80。
conntrack 连接记录是 iptables 连接状态匹配的基础,也是实现 SNAT 和 DNAT 的前提。我们知道 Kubernetes 的核心组件 kube-proxy,它作用是负责处理集群中的服务(Service)网络流量。它本质上是一个反向代理(即 NAT),当外部请求访问 Service 时,流量会被 DNAT 转发到 PodIP:Port,响应则经过 SNAT 处理。

- 节点中的 kube-proxy 收到请求后,执行 DNAT 操作,将请求包的目标地址 10.0.0.10:80 转换为某个 Pod 的 IP 和端口 192.168.1.2:8080。
- Pod 处理请求,并返回响应,kube-proxy 执行 SNAT 操作,将响应包的源地址 192.168.1.2:8080 转换为 Service IP 10.0.0.10:80。
举一个具体的例子说明。假设客户端向 my-service(IP 10.0.0.10,端口 80)发送 HTTP 请求,流程如下:
- 节点中的 kube-proxy 收到请求后,执行 DNAT 操作,将目标地址从 10.0.0.10:80 转换为某个 Pod 的 IP 和端口(如 192.168.1.2:8080)。
- Pod 处理请求并返回响应,kube-proxy 执行 SNAT 操作,将响应包的源地址从 192.168.1.2:8080 转换为 Service IP 10.0.0.10:80。

conntrack 模块维护的连接记录包含了从客户端到 Pod 的 DNAT 映射(10.0.0.10:80 到 192.168.1.2:8080)以及从 Pod 到客户端的 SNAT 映射(192.168.1.2:8080 到 10.0.0.10:80)。这样有来有回,是一条完整的 NAT 映射关系。但如果发起请求的客户端和处理请求的 Pod 在同一个主机内(图 3-5),问题来了
- 发起请求时,数据包经过网络层时,内核中的 conntrack 模块根据 iptables 规则,判断是否需要进行 DNAT;
- 返回响应时,如果 Linux 网桥检测到目的 IP 位于同一网桥上,则直接通过链路层转发,并没有触发网络层的 conntrack 模块,也就是不进行 SNAT。
conntrack 模块维护的连接记录包含了从客户端到 Pod 的 DNAT 映射、从 Pod 到客户端的 SNAT 映射。这样有来有回,是一条完整的 NAT 映射关系。但是,如果客户端与 Pod 在同一主机上(如图 3-5),则会出现以下问题
- 客户端发起请求时,数据包经过网络层,conntrack 模块根据 iptables 规则判断是否需要进行 DNAT;
- 返回响应时,Linux 网桥发现目标 IP 位于同一网桥上,会直接通过链路层转发数据包,而不会触发网络层的 conntrack 模块,导致 SNAT 操作没有执行

因此,通信双方不在同一“频道”上,NAT 相关的连接记录不完整,进而影响容器间通信,产生各类异常
因此,通信双方不在同一“频道”上,NAT 映射关系不完整,进而影响容器间通信,产生各种异常

:::center
![](../assets/bridge-call-iptables.svg)<br/>
图 3-5 请求和响应不在一个“频道”上,双方通信失败
:::

针对上述问题,Linux 内核开放了 bridge-nf-call-iptables 配置,决定 Linux 网桥中的数据包是否触发 iptables 匹配规则。也就是处理 NAT 保证 conntrack 连接记录的完整性。这也解释了为什么部署 Kubernetes 集群时,务必开启 Linux 系统配置 bridge-nf-call-iptables(设置为 1)的原因
为了解决上述问题,Linux 内核引入了 bridge-nf-call-iptables 配置,决定是否在网桥中触发 iptables 匹配规则,从而保证 NAT 处理时 conntrack 连接记录的完整性。这也解释了为什么在部署 Kubernetes 集群时,必须将该配置设置为 1

0 comments on commit a384d16

Please sign in to comment.