前言
Kubernetes 的 服务代理实现主要基于 Linux 数据包过滤框架 netfilter 及其相关组件。本文介绍 netfilter 框架及其相关软件 iptables,以更好地理解 Kubernetes Service 代理机制。
什么是 netfilter,iptables ?
Netfilter 框架
Netfilter 是 Linux 内核中进行数据包过滤、修改,连接跟踪,网络地址转换等功能的实现框架,项目地址在 https://netfilter.org 。Netfilter 框架由多个模块组成,包括 netfilter, ip_tables, connection tracking (ip_conntrack, nf_conntrack) 和 NAT。不同 Netfilter 组件相互关系如下图所示:
该框架工作在 TCP/IP 模型中的 L2 - L5 层:
netfilter 钩子
netfilter 是 Netfilter 框架在 Linux 内核网络协议栈中定义的一组钩子(hook)。在这些钩子上可以注册回调函数来对数据包进行处理。当数据包在网络协议栈传递过程中到达钩子点时,相应的回调函数就会被触发。一共有五种钩子:
- NF_IP_PRE_ROUTING:数据包进入网络协议栈时触发
- NF_IP_LOCAL_IN:数据包发往本地时触发
- NF_IP_FORWARD:数据包需要转发到其他主机时触发
- NF_IP_LOCAL_OUT:本地数据包进入网络协议栈时触发
- NF_IP_POST_ROUTING:数据包从网络协议栈转出时触发
图片来源:https://zhuanlan.zhihu.com/p/93630586
iptables
iptables 是运行在用户空间的应用,是 Liunx 提供给用户层的命令接口。用户可以通过 iptables 添加数据包处理规则,配置防火墙,从而实现数据包的修改和过滤功能。所以 iptables 只是一个工具,真正实现功能的是 Netfilter 内核模块。除了 iptables,还有 arptables,ebtables 等工具。在大部分 Linux 发行版中,可以通过 man iptables
获取用户手册。iptables 使用的数据结构包含:表(table)、链(chain)和 规则(rule)三个层面。
表
iptables 使用表来组织规则。比如,如果有一个规则是处理网络地址转换,则这个规则应放置在 nat 表中。总共有五种类型的表,每种表对应不同类型的数据包处理流程:
- filter 表:用于过滤数据包,是默认的表
- nat 表:用于地址转换操作
- mangle 表:用于 IP 头部信息修改
- raw 表:用于连接追踪
- security 表:用于设置 SELinux 安全上下文标签
链
在 iptables 表中,规则又进一步被组织到不同的链中。链的主要用途是决定规则何时被处理。一旦链被触发,链中的规则会被逐一进行匹配,如果匹配,则执行相应的动作,如修改数据包,或者跳转。跳转可以直接接受该数据包或拒绝该数据包,也可以跳转到其他链继续进行匹配,或者从当前链返回调用者链。一个表可以有多种不同的链组成,可以是内置的链,也可以是用户定义的链。内置链有:
- PREROUTING:由 NF_IP_PRE_ROUTING 钩子触发
- INPUT:由 NF_IP_LOCAL_IN 钩子触发
- FORWARD:由 NF_IP_FORWARD 钩子触发
- OUTPUT:由 NF_IP_LOCAL_OUT 钩子触发
- POSTROUTING:由 NF_IP_POST_ROUTING 钩子触发
而用户定义的链必须通过其他链中的规则跳转进来。
规则
当链被调用,数据包会被链中每个规则检查。每个规则包含两部分匹配(match)和动作(target)。数据包与规则相匹配,就会执行对应的动作。
延伸阅读
[1] Linux: What's Netfilter, iptables, Their Differences?
[2] A Deep Dive into Iptables and Netfilter Architecture
[3] Linux 网络层收发包流程及 Netfilter 框架浅析