说明
此实验性插件允许您使用 eBPF XDP 程序在流量到达 CoreDNS 之前对其进行分析和过滤,并报告非常基本的 Prometheus 指标。CoreDNS 退出时,程序将从接口分离。
此通用解决方案作为如何将 eBPF XDP 程序与带有自定义插件的 CoreDNS 集成的示例。但由于通用性,映射条目有些隐蔽,并且必须在 Corefile 中定义指标,从而限制了其范围。在编写自己的插件时,您可以对其进行定制以与特定的 XDP 程序一起使用,例如,启用更易于阅读人类的可读数据条目或发布更多高级指标。
语法
ebpf {
elf PROGRAM
if INTERFACE
map [KEY] VALUE
metric NAME KEY POS LEN "HELP"
}
elf
PROGRAM - 要附加的 ELF 程序。请参阅下方关于程序要求的说明。if
INTERFACE - 要附加到的接口map
KEY VALUE - 要加载到 eBPF 映射中的 KEY 和 VALUE 的十六进制字符串表示。您可以指定map
选项以将多个项添加到映射中。如果未指定 KEY,则该条目将被视为数组值。若要使多字段值更易于视觉消化,可以使用点分隔 VALUE。如012345678.0000000000000000.9ABCDEF0
。这仅对 Corefile 的可读性有用;解析器将忽略 VALUE 中的任何点。当使用debug 时,写入日志的值不会分隔。metric
NAME KEY POS LEN “HELP” - 当与prometheus 插件结合使用时,注册一个 Prometheus “gauge” 指标,以将 eBPF 映射值公开为一个整数指标。该指标名为 NAME,帮助文本为 HELP。要使用的映射值由 KEY、字节位置 POS 和字节长度 LEN 确定。LEN 最多可以是 8 个字节(64 位)。该整数值应为小端序。
请注意此插件相当大的危险性。附加到接口的 XDP 程序将作用于所有进入接口的数据包 - 而不只是绑定到 CoreDNS 的数据包。
eBPF 程序和映射要求
程序必须是 XDP 程序,并且主函数名为 xdp_prog
。映射必须命名为 xdp_map
。
一些用 C 编写的示例程序包含在 https://github.com/InfobloxOpen/ebpf/tree/master/example_programs 中。
示例
如果 my_xdp_program.o
定义了一个带有 4 字节键的映射,并且将以下结构作为值 …
struct maprec {
__be32 ip4net; // ipv4 network
__be32 ip4mask; // ipv4 mask
__be32 count; // packet count
};
以下是将 my_xdp_program.o
附加到 eth0
,并将 IP 网络 10.11.0.0
、IP 掩码 255.255.0.0
和计数零(0A0B0000
、FFFF0000
和 00000000
)的数据加载到映射键 00000000
中。
. {
ebpf {
if eth0
elf my_xdp_program.o
map 00000000 0A0B0000FFFF000000000000
}
}
以下是向映射值添加点以使其更易于读取。
. {
ebpf {
if eth0
elf my_xdp_program.o
map 00000000 0A0B0000.FFFF0000.00000000
}
}
以下是启用调试以监视映射值并记录其更改时间。
. {
debug
ebpf {
if eth0
elf my_xdp_program.o
map 00000000 0A0B0000.FFFF0000.00000000
}
}
以下是添加映射项而不指定键。各映射项以数组值插入,并自动增量键。
. {
ebpf {
if eth0
elf my_xdp_program.o
map 0A0B0000.FFFF0000.00000000
map 0A0C0000.FFFF0000.00000000
map 0A0D0000.FFFF0000.00000000
}
}
以上示例等效于以下示例,但指定了键。请注意,此示例中的键采用小端顺序排列。
. {
ebpf {
if eth0
elf my_xdp_program.o
map 00000000 0A0B0000.FFFF0000.00000000
map 01000000 0A0C0000.FFFF0000.00000000
map 02000000 0A0D0000.FFFF0000.00000000
}
}
以下是公开 Prometheus 指标。此指标命名为 coredns_ebpf_example_total
,且值将反映映射项 02000000
中最右侧的 4 个字节。
. {
prometheus :9153
ebpf {
if eth0
elf my_xdp_program.o
map 00000000 0A0B0000.FFFF0000.00000000
map 01000000 0A0C0000.FFFF0000.00000000
map 02000000 0A0D0000.FFFF0000.00000000
metric example_total 02000000 8 4 "Example count."
}
}