Slide 1

Slide 1 text

NetKit Device Yutaro Hayakawa

Slide 2

Slide 2 text

NetKit Device ● 今年10月にLinuxに入った新しい仮想デバイス ● Isovalentのエンジニア (Daniel Borkmann, Nikolay Aleksandrov) が中心になって開発 ● Kubernetes Networkのユースケースに特化した仮想デバイス ● “veth replacement”

Slide 3

Slide 3 text

今回のお話 ● NetKit Deviceが作られた経緯 ● 機能の概観 ● Demo

Slide 4

Slide 4 text

NetKit Deviceが作られた経緯 ● 基本的にはCiliumのために作っている ● 性能向上が主なモチベーション ○ KubernetesのPod-to-Podの通信をHost-to-Host並に速くしたい ○ 具体的な数字で言えば Pod to Podの通信で100Gbps出るようにしたい ● NetKit Deviceの目的はNetwork Namespace Switchの速度向上 ○ ⚠ 当然これだけでは 100Gbpsは出ない ○ これまでも色々やってきたパフォーマンス向上 100Gbpsをマイクロベンチで達成できるというのが実際 ○ 周辺技術も合わせてチェックするのがおすすめ ● 性能向上だけでなく Kubernetesネットワーキングの分野で役立つ機能が色々盛り込まれている

Slide 5

Slide 5 text

Kubernetes Networkingのおさらい 一般的なKubernetes Networkingの構成要素 ● Node, Pod ● veth ● kube-proxy ○ iptables/ipvs (netfilter) を使って実装さ れている. ServiceとBackendの数に比 例して処理時間が長くなることが知られ ている.

Slide 6

Slide 6 text

Cilium Networkingのおさらい Ciliumの場合 ● tc-bpf ● Podの出口 (Host側vethのtc-ingress)とNodeの 入り口 (物理デバイスの tc-ingress)でeBPFのプ ログラムが走る . カーネルスタックの機能は必 要に応じて使う . ● kube-proxy-replacement ○ eBPFベースでkube-proxyを置き換え. 基 本的にはO(1).

Slide 7

Slide 7 text

ベースラインパフォーマンス 100G NICのついたサーバ2つを直結してベンチマーク Pod-to-PodとHost-to-HostのTCP Single Flowのスループットを比較 Host-to-Hostから大体22Gbpsくらいのギャップがある (Wire Rateとのギャップは76Gbpsくらい) ここからどう速くしていくか?

Slide 8

Slide 8 text

BPF Host Routing (Ingress) Nodeの物理デバイスのtc-ingressからカーネルスタックとPod側vethのBacklog Queueをバイパス してPod側の受信完了までRun to Completionでパケットを処理させる (bpf_redirect_peer)

Slide 9

Slide 9 text

BPF Host Routing (Egress) Host側のvethからカーネルスタックをバイパスして物理 NICにパケットをリダイレクト (bpf_redirect_neigh) 外のネットワークに出ていく時は ARPの解決が必要なこともあるが, それもbpf_redirect_neigh側で 面倒を見てくれる

Slide 10

Slide 10 text

BPF Host Routingの効果 ベースラインのPod-to-Podと比較して17Gbpsほどのゲイン Host-to-Hostとのギャップは4Gbps ぶっちゃけもう十分じゃない?という気もするが, 100Gbpsには程遠い

Slide 11

Slide 11 text

とりあえずMTUを上げる MTUを8264Bに上げる (ジャンボフレームの規格上は9Kまでいけるがこの数がGROとの実 装との相性がよく, 性能が出やすいらしい) Host-to-Hostはもうほぼ100Gbps出ている 残り9Gbpsをどう稼ぐか?

Slide 12

Slide 12 text

Fast Network Namespace Switching with NetKit bpf_redirect_neighでカーネルをバイパスしつつさらに Host側NetKitのBack Log Queueもバイパスできる NetKitのeBPFプログラムの中でfib_lookupやredirectをするとHost側のNetwork NamespaceのFIBやNetdevにアクセス できる bpf_redirect_neigh()

Slide 13

Slide 13 text

Backlog Queue Flame Graphで見ると違いがわかりやすい

Slide 14

Slide 14 text

NetKitの効果 Host-to-Hostと変わらないパフォーマンスを出せるように 🎉 ⚠ meta == NetKit

Slide 15

Slide 15 text

別解: BIG-TCP BIG-TCP: 基本的にはGSOだが, 512KBまでパケットを固められる (普通のGSOは64Kが上限) BIG-TCPを使えばvethでも100Gbps出る NetKitに乗り換えるにはもう少し他のメリットも欲しいところ

Slide 16

Slide 16 text

BIG-TCPを使った場合のレイテンシの対比 Vethと比較してレイテンシはアドバンテージがある この20usのゲインが必要なワークロードにはNetKitが刺さるかもしれない

Slide 17

Slide 17 text

IPVLAN Device Fast Netns SwitchingはNetKitの専売特許ではない. IPVLANデバイスも似たような特性がある. ただし, IPVLANの場合, eBPFのプログラムはPodのNetnsの中のtc-egressにアタッチする必要がある 権限の設定によってはPodがeBPFのプログラムをデタッチすることもできる また, IPVLANは1つのmaster deviceから子デバイスを生やす構成なので, 複数の物理デバイスがある場合に不便

Slide 18

Slide 18 text

NetKit Primary & Peer NetKit Deviceのペアにはvethにはない非対称な関係がある (PrimaryとPeer) PrimaryとPeerが違うNetnsにいてもPrimary側を経由してPeer側にeBPFのプログラムをアタッチできる Peer側のデバイスはPrimary側からアタッチされたeBPFプログラムをデタッチすることはできない eBPFプログラムをアタッチするためだけにPodに強い権限を持たせる必要がない Primary Peer BPF_LINK_CREATE expected_attach_type = BPF_NETKIT_PEER Pod Netns Host

Slide 19

Slide 19 text

NetKit Primary & Peer

Slide 20

Slide 20 text

その他の機能 ● L2 / L3 Mode ○ L2モードは普通のEthernetデバイスと同じ ○ L3モードはIPIPデバイスやVRFのようなモード (ARPが飛ばない, Ethernetヘッダがつかない) ○ NetKitのデフォルトはL3モード ● Multi-Attach (bpf_mprog) ○ 一箇所のフックに複数のeBPFプログラムをアタッチでき, さらにプログラムの前後関係を明示的に指定できる (e.g. Program Aより前, Program Bより後) ○ NetKitは最初からこれをサポートしている ○ ちなみにTCX (TC Express, XDPより後, 普通のTCより前) という新しいフックを使えば普通のNetwork Deviceでも同 じようにMulti Attachできる ● Default Forwarding Policy ○ eBPFプログラムがアタッチされていない時の挙動を制御 ○ Drop (全部落とす) か Forward (全部通す)

Slide 21

Slide 21 text

各種ツール, ライブラリのサポート状況 ● iproute2のコマンドはまだUpstreamされていない, Danielのforkには一応使えるものがある ○ https://github.com/borkmann/iproute2/tree/pr/netkit ○ `ip link add nk0 type netkit mode l3 peer name nk1` ● libbpfにはすでにサポートあり, cilium/ebpfはまだ ○ NetKitはNetKit用の新しいeBPFのフックを作ったので, 新しいAttachのやり方が必要 (eBPF プログラム自体はtcと互換性がある)

Slide 22

Slide 22 text

Demo Client Primary Peer veth veth nk nk 10.0.0.0/24 10.0.1.0/24 .2 .1 .1 .2 ClientからPeerにping. 以下のシナリオでpwruを使って関数トレースをとってみる. Scenario 1: nkのpolicyをforwardにして普通にPing. この場合vethとnetkitに違いはない. Scenario 2: PeerのnkとPrimaryのvethにeBPFをattachしてBPF Host Routing相当のことをやる. 1に比 べると関数トレース上ショートカットできているのが観測できるはず . bpf_redirect_peer bpf_redirect_neigh

Slide 23

Slide 23 text

Scenario1 Scenario2

Slide 24

Slide 24 text

Client Namespace => Client veth xmit => Primary veth recv

Slide 25

Slide 25 text

bpf_redirect_peer

Slide 26

Slide 26 text

この時点ですでに PeerのNamespace にいる PrimaryのNamespace内 でIP Forwarding

Slide 27

Slide 27 text

Primary Namespace => Primary NetKit xmit => Peer NetKit recv ここでパケットがbacklog queueに入る

Slide 28

Slide 28 text

Peerの受信処理 ICMP Reply開始

Slide 29

Slide 29 text

Peerの送信処理

Slide 30

Slide 30 text

Peerの送信処理 Cont.

Slide 31

Slide 31 text

bpf_redirect_neigh

Slide 32

Slide 32 text

PeerのKernel Stackを Bypass, 直接Neighサブ システムに飛ぶ PeerのKernel StackでIP Forwarding skb_orphan ここでSocketの Referenceが落ちる. TCPの場合はここでセグ メントがホストから出て 行った扱いになる. これ がかなりTCPのスルー プットに悪いらしい. ここでパケットがbacklog queueに入る

Slide 33

Slide 33 text

??? skb_orphan SocketのReferenceがここ まで保持されている . 実際の 物理NICの場合だとNICのメ モリに実際にパケットを積ん だ段階でSocketの Referenceを落とす? (調べていない)

Slide 34

Slide 34 text

??? Clientの受信処理

Slide 35

Slide 35 text

Future Work: Single Device Mode ● ペアではなくて単一のデバイスとして動かすモード ● (多分) Custom Tunnel DeviceなんかをeBPFで作れるよということ ● “eBPF Programmable Device” らしい機能ではあるがユースケースは今の所出てきていない

Slide 36

Slide 36 text

参考文献 ● bpfconf (May 2 - May 4, 2022) ● LPC 2022 (Sep 12 - Sep 14, 2022) ● FOSDEM 2023 (Feb 4 - Feb 5, 2023) ● bpfconf 2023 (May 8 - May 10, 2023) ● Patch Set (Oct 24, 2023) ● LWN (Nov 6, 2023) ● KubeCon NA 2023 (Nov 8, 2023) ● LPC 2023 (Nov 24, 2023) おすすめ 全体感を把握したい => KubeCon NA 2023 パフォーマンスのことを知りたい => FOSDEM 2023 実装を詳しく知りたい => LPC 2023