説明
この*実験的な*プラグインを使用すると、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
プログラム - アタッチするELFプログラム。プログラムの要件については、以下の注記を参照してください。if
インターフェース - アタッチするインターフェースmap
キー 値 - eBPFマップにロードするエントリの**キー**と**値**の16進数文字列表現。map
オプションを複数回指定して、マップに複数のアイテムを追加できます。 **キー**が指定されていない場合、エントリは配列値として扱われます。複数フィールドの値を視覚的に理解しやすくするために、**値**はドットで区切ることができます。例:012345678.0000000000000000.9ABCDEF0
これは、Corefileの読みやすさのためだけです。 **値**内のドットはパーサーによって無視されます。 *debug*を使用する場合、ログに書き込まれる値は区切られません。metric
名前 キー 位置 長さ “ヘルプ” - *prometheus*プラグインと組み合わせて使用する場合、Prometheusの「gauge」メトリクスを登録して、eBPFマップ値を整数メトリクスとして公開します。メトリクスには、ヘルプテキスト**ヘルプ**の**名前**が付けられます。使用するマップ値は、**キー**、バイト位置**位置**、およびバイト単位の長さ**長さ**によって決定されます。 **長さ**は最大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."
}
}