ebpf

ソースコード ホーム

有効化方法
ebpf:github.com/InfobloxOpen/ebpf

ebpf - 指定されたインターフェースにeBPF XDPプログラムをアタッチします。

説明

この*実験的な*プラグインを使用すると、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.oeth0にアタッチし、IPネットワーク10.11.0.0、IPマスク255.255.0.0、およびカウントゼロ(それぞれ0A0B0000FFFF0000、および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."
  }
}