《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(上)

简介: 《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(上)

netfilter框架是Linux操作系统中内置的,通过向内核模块提供对协议栈中的网络数据包进行修改和操作的能力,来实现流量过滤,网络地址转换等高级功能。

 

1) netfilter如何工作

对于网络数据报文,网络设备驱动通过将二层的以太网数据报文按照Linux内核定义的网络设备驱动规范,以sk_buff结构体的方式进行接收或者发送,即通常我们所描述的报文的最小单元skb。

 

内核通过将网络设备缓冲区环形队列中skb取出,并按照以太网层,网络层,传输层顺序处理后,将报文数据放置到对应Socket缓冲区中,通知用户程序进行读取,从而完成收包

内核为Socket缓冲区待发送数据封装为skb,经过传输层,网络层和以太网层依次填充对应报头后,调用网络设备驱动方法将skb发送到网络上,从而完成发包

 

netfilter工作的核心原理则是在网络层,通过在五个不同的内核处理skb数据包的位置,执行注册到netfilter框架中的回调函数,并根据回调函数的返回来选择下一步的处理,实现复杂的功能。

 

netfilter触发时机

 

netfilter在内核网络数据包的处理流程中,注册了5个可以触发的时机,详情如下:

/* IP Hooks */
/* After promisc drops, checksum checks. */
#define NF_IP_PRE_ROUTING0
/* If the packet is destined for this box. */
#define NF_IP_LOCAL_IN1
/* If the packet is destined for another interface. */
#define NF_IP_FORWARD2
/* Packets coming from a local process. */
#define NF_IP_LOCAL_OUT3
/* Packets about to hit the wire. */
#define NF_IP_POST_ROUTING4
#define NF_IP_NUMHOOKS5
#endif /* ! __KERNEL__ */

 

根据源代码中的定义,我们可以参考下图:

 image.png

 从上面的代码定义和示意图中可以知道,在以下几个地方会调用netfilter定义好的方法对数据包进行处理:

 

数据包从网卡进入协议栈后,所有报文都会走到NF_IP_PRE_ROUTING

数据包经过入向路由选择后,确认是由本机传输层进行处理,会进入到NF_IP_LOCAL_IN

数据包经过入向路由选择后,不是由本机处理,需要转发给其他机器,会进入到NF_IP_FORWARD

由本机传输层发出报文,都会经过NF_IP_LOCAL_OUT

经过出向路由选择后报文,会经过NF_IP_POST_ROUTING,包括从本机发出和需要本机转发的。

 

在以上五个时机,当数据包skb到达时,netfilter框架定义的回调方法就会被内核执行。

 

netfilter如何操作网络数据

使用netfilter框架的模块,需要按照netfilter定义的结构体来实现自己的行为,才能正确注册到netfilter框架中,并被内核调用,netfilter约束的注册结构体的定义如下:

struct nf_hook_ops {
    // 这是真正被内核执行的函数,会对skb进行读取和修改
    nf_hookfn*hook;
    struct net_device*dev;
    void*priv;
    u_int8_tpf;
    // hooknum定义了回调函数生效的位置,从上文可知有五个位置可以选择
    unsigned inthooknum;
    // priority定义了回调函数的优先级,通过每个hook时机都会有多个回调函数需要生效
    intpriority;
};

以ipvlan模块为例:

static const struct nf_hook_ops ipvl_nfops[] = {
  {
    .hook     = ipvlan_nf_input,
    .pf       = NFPROTO_IPV4,
    .hooknum  = NF_INET_LOCAL_IN,
    .priority = INT_MAX,
  },
#if IS_ENABLED(CONFIG_IPV6)
  {
    .hook     = ipvlan_nf_input,
    .pf       = NFPROTO_IPV6,
    .hooknum  = NF_INET_LOCAL_IN,
    .priority = INT_MAX,
  },
#endif
};

 

我们可以看到,ipvlan模块根据IP协议的版本定义了两个hook结构体,其中:

hookfn是核心处理逻辑,ipvlan模块注册了ipvlan_nf_input方法

pf是netfilter协议版本,ipvlan模块分别注册了IPv6和IPv4对应方法

hooknum定义了这个hook在netfilter中生效位置,ipvlan模块将自己回调方法注册到了NF_INET_LOCAL_IN,也就是完成路由之后,进入传输层之前

priotity定义了hook优先级

 

那么,hookfn作为真正核心的处理逻辑,他是如何工作的呢?

 

以ipvlan注册在NF_INET_LOCAL_IN上的hook方法ipvlan_nf_input为例:

 

unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
           const struct nf_hook_state *state)
{
    // 参数中可以看到,有前一个生效的hook结构体,当前处理的skb报文本身以及当前netfilter框架的上下文信息
  struct ipvl_addr *addr;
  unsigned int len;
  addr = ipvlan_skb_to_addr(skb, skb->dev);
  if (!addr)
    goto out;
  skb->dev = addr->master->dev;
  len = skb->len + ETH_HLEN;
  ipvlan_count_rx(addr->master, len, true, false);
out:
    // 这里返回了netfilter框架规定的返回码
  return NF_ACCEPT;
}

 从ipvlan_nf_input可以看到,注册到netfilter中的回调函数的核心在于两个约束:

● 回调函数的入参定义,可以接受协议栈中真正的报文结构体skb以及netfilter的上下文状态为参数。

● 回调函数的返回值,需要是netfilter规定好的返回值,他们的定义如下:

/* Responses from hook functions. */
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5/* Deprecated, for userspace nf_queue compatibility. */
#define NF_MAX_VERDICT NF_STOP

从以上的分析不难看出,只要满足netfilter的注册条件,就可以在回调函数中直接对数据报文skb内容进行读取和修改操作,而通过返回值的定义,则可以借助netfilter框架完成对数据包的处理,比如丢弃,接收或者传递到用户态进行处理。

 

netfilter的内核实现

在负责对所有hook方法进行遍历处理的函数中,可以看到,netfilter核心的工作流程就是在相应的触发时机调用这个时机上注册的所有方法,按照优先级进行处理,并根据每一次处理的结果进行操作,包括丢弃,传输给用户态等等:

int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
     const struct nf_hook_entries *e, unsigned int s)
{
  unsigned int verdict;
  int ret;
  for (; s < e->num_hook_entries; s++) {
        // 在这里调用对应的hook时机上的所有注册的hook回调方法,然后根据结果选择是不是继续循环
    verdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state);
    switch (verdict & NF_VERDICT_MASK) {
    case NF_ACCEPT:
      break;
    case NF_DROP:
      kfree_skb(skb);
      ret = NF_DROP_GETERR(verdict);
      if (ret == 0)
        ret = -EPERM;
      return ret;
    case NF_QUEUE:
      ret = nf_queue(skb, state, e, s, verdict);
      if (ret == 1)
        continue;
      return ret;
    default:
      /* Implicit handling for NF_STOLEN, as well as any other
       * non conventional verdicts.
       */
      return 0;
    }
  }
  return 1;

 

更多精彩内容,欢迎观看:

《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(下):https://developer.aliyun.com/article/1221729?spm=a2c6h.13148508.setting.16.15f94f0e18Oqpt

相关文章
|
4月前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
10天前
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
159 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
15天前
|
人工智能 安全 API
容器化AI模型的安全防护实战:代码示例与最佳实践
本文基于前文探讨的容器化AI模型安全威胁,通过代码示例展示如何在实际项目中实现多层次的安全防护措施。以一个基于TensorFlow的图像分类模型为例,介绍了输入验证、模型加密、API认证和日志记录的具体实现方法,并结合最佳实践,如使用安全容器镜像、限制权限、网络隔离等,帮助构建更安全的AI服务。
|
25天前
|
网络协议 安全 网络安全
应用程序中的网络协议:原理、应用与挑战
网络协议是应用程序实现流畅运行和安全通信的基石。了解不同协议的特点和应用场景,以及它们面临的挑战和应对策略,对于开发者和用户都具有重要意义。在未来,随着技术的不断发展,网络协议也将不断优化和创新,为数字世界的发展提供更强大的支持。
|
2月前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
380 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
2月前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
137 15
|
2月前
|
容灾 网络协议 数据库
云卓越架构:云上网络稳定性建设和应用稳定性治理最佳实践
本文介绍了云上网络稳定性体系建设的关键内容,包括面向失败的架构设计、可观测性与应急恢复、客户案例及阿里巴巴的核心电商架构演进。首先强调了网络稳定性的挑战及其应对策略,如责任共担模型和冗余设计。接着详细探讨了多可用区部署、弹性架构规划及跨地域容灾设计的最佳实践,特别是阿里云的产品和技术如何助力实现高可用性和快速故障恢复。最后通过具体案例展示了秒级故障转移的效果,以及同城多活架构下的实际应用。这些措施共同确保了业务在面对网络故障时的持续稳定运行。
|
2月前
|
人工智能 运维 监控
容器服务Kubernetes场景下可观测体系生产级最佳实践
阿里云容器服务团队在2024年继续蝉联Gartner亚洲唯一全球领导者象限,其可观测体系是运维的核心能力之一。该体系涵盖重保运维、大规模集群稳定性、业务异常诊断等场景,特别是在AI和GPU场景下提供了全面的观测解决方案。通过Tracing、Metric和Log等技术,阿里云增强了对容器网络、存储及多集群架构的监控能力,帮助客户实现高效运维和成本优化。未来,结合AI助手,将进一步提升问题定位和解决效率,缩短MTTR,助力构建智能运维体系。
|
3月前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
3月前
|
域名解析 网络协议 关系型数据库
【网络原理】——带你认识IP~(长文~实在不知道取啥标题了)
IP协议详解,IP协议管理地址(NAT机制),IP地址分类、组成、特殊IP地址,MAC地址,数据帧格式,DNS域名解析系统

热门文章

最新文章