Upgrade to Pro — share decks privately, control downloads, hide ads and more …

転びながらもネットワーク処理を ソフトウェアで自作していく話

Avatar for Mabuchin Mabuchin
July 06, 2019

転びながらもネットワーク処理を ソフトウェアで自作していく話

in BCU30

Avatar for Mabuchin

Mabuchin

July 06, 2019
Tweet

More Decks by Mabuchin

Other Decks in Technology

Transcript

  1. ⾃⼰紹介 • ⾺淵 俊弥 / @raibo • 開発本部 インフラ室 ネットワーク開発グループ

    • モンスターストライク等、 事業⽤サービスネットワークの設計/運⽤/開発 • 特定⽤途向けのネットワークデータプレーン開発 今日はこっち
  2. Linux Socketの場合 NIC Rx NIC Tx NIC Kernel UserSpace Rx

    Ring Tx Ring Socket libsocket App sk_buff ProtocolStack IRQ Interrupt RSS syscall
  3. Linux Socketを使ったパケット処理 • Pros • Linuxと各種⾔語の優れた抽象化 • 開発時もネットワークのかなりの部分を意識せず使える • 成熟したプロトコルスタックを利⽤できる

    • TCP等, 複雑なプロトコルに対して先⼈達の肩に乗って利⽤できる • Cons • ネットワーク処理⽤途で10Gbps~等の⼤規模な通信処理が難しい • ネットワーク処理に適⽤すると、1台当たりの処理能⼒が低い • 処理的に遅延が乗ってしまう • TCP/IPのネットワークスタック処理を⾏うからどうしても重くなる • 多段するとより顕著に遅くなる
  4. XDP • eXpress Data Path • Linux Kernel Nativeなパケット処理機能 •

    カーネル内VMの上で動くコードを挿⼊できる機能を利⽤ (eBPF) • XDPはそのbytecodeをKernel NetworkDriverレベルの箇所に差し込む機能 • ユーザ空間からも参照/書き換えができるMAPやArrayが利⽤可能 NIC1 ELF-compiled eBPF NIC2 Management App Protocol Stack ... eBPF Map RX XDP XDP XDP_TX XDP_REDIRECT XDP_PASS r/w Queue JIT Compile UserSpace Kernel Hardware XDP_DROP r/w
  5. DPDK Data Plane Development Kit • 専⽤デバイスドライバ(PMD)と開発⽤の周辺ライブラリセット • 1CPU当たり1スレッドでPolling(CPUをPollingで専有) •

    Hugepageによって⼤きなメモリを確保 • TLBキャッシュミス削減 • 専⽤のメモリアロケータによる⾼速な割当 • 実装⽤ライブラリも多数提供 • Checksum/decap/ACL等 • Docもかなりの充実具合 • https://doc.dpdk.org/ ApplicaKon Kernel Space NIC PMD
  6. 取り組んでいるもの ステートレス実装可能なもの中⼼ • Static NAT (DPDK/XDP) • グローバル ↔ プライベートIPの静的変換NAT

    • GRE Decap Endpoint (DPDK/XDP) • ひたすらGREをDecapする • マルチクラウド環境上でのアドレスバッティング対策 • 詳細: モンスターストライクも⽀えるデータプレーン • Tap Payload cutter & sFlow Converter (XDP) • サンプリング&解析に不要なデータを削除 • sFlow変換して別NICからFlowコレクターへ⾶ばす
  7. NATの場合(XDPのパターン) • Static NAT開発 • 1:1のシンプルなIP変換 • 各NATは BPF_MAP_TYPE_PERCPU_HASH でCPU毎にテーブル管理

    • GRPCによる複数台NATテーブルの管理&Stat取得 • 1台双⽅向で12Mpps(10Gbps程度)まで処理可能 Controll Server Backbone Private default Static NAT Static NAT StaKc NAT 192.0.2.0/24 ↔ 198.51.100.0/24 MAP MAP MAP MAP MAP MAP MAP MAP MAP
  8. ペイロードカッター For pcap/sflow • Tapでトラブルシュートを⾏いつつ、必要ない情報はカットしたい • トラブルシュート時は所定のヘッダまで取れればOK • L4~L7以下のPacketのペイロードカットしてからユーザスペースへ •

    カットした部分をsFlowに変換して⾶ばす(WIP) • Flow対応してない区間でも取れる • bpf_xdp_adjust_tailでヘッドルーム縮小によってコピーしない Tap Static NAT Tap Aggregation Flow Collector .pcap XDP server Flow Dissect Payload Cutter Sampling XDP_DROP
  9. さらに沢⼭ハマる • 特定NICのVlan消失 • 数台のうち1つのNICで切りたい特定オフロードを切れなかった • オフロードをoffにできない(fixed)箇所はNIC毎に結構違う • 1週間でQueueが枯渇してパケットを送れなくなる •

    NICファームとKernel Driverの乖離が原因で 不要なパケットが溜まっていっていた... • ファームが絡むと、本当のところが明確には分からない...つらい • メニーコアマシンでXDP起動後、少しするとHang • Combinedで利⽤コアを抑制しないといけない • ⽤意できるXDP Ringの限界数は96個 • 参考: https://www.mail-archive.com/[email protected]/msg246813.html
  10. 気をつける点まとめ • サーバーのファームが⼊れ替え可能か確認しておくべし • 切り分けが相当しやすくなる • NICもサーバーのOEM提供だとファームが上げづらいことも • XDPはカーネルVerによって実装状況が結構違う •

    実⾏時警告とかほぼ無いので、普通にパケット落ちます • ソースやPatchを確認しておこう • 例: mlx5のNIC XDP_REDIRECTは4.19~ • LinuxのKernelやドライバの知識が超重要 • NAPI/ドライバ/IRQ Balancer/numa/CPU cache/RSS/RFS等、 ある程度知らないとチューニングできない
  11. テストと計測 • テスト駆動な開発 • OK/Failパターンのパケットを実装前に定義 • 実装物に関わるRFCからパケットパターンを決めて⽤意 • RFC2663, 3022,

    7857 4787, 5382, 5508... • 全部通れば機能要件を概ね満たしている • 後から追加より実装上の⼿戻りも圧倒的に少ない • CircleCIで機能単位のテストを実施 • DPDK : Gtest • XDP : xdp_prog_run def test_egress_ether_vlan_ipv4_icmp_packet(self): i_pkt = Ether()/Dot1Q(vlan=10)/IP(src=”198.18.0.1", dst=”198.19.0.1")/ICMP() o_pkt = Ether()/Dot1Q(vlan=20)/IP(src=”198.18.1.1", dst=”198.19.0.1")/ICMP() self.xdp_test(self.egress, i_pkt, o_pkt, BPF.XDP_REDIRECT) ↑こんな感じで仮想的に実⾏して結果を確認可能
  12. まとめ • XDP/DPDK等で⾼速パケット処理開発 • 使うべき箇所と選定は⾒極めてやっていきましょう • チューニングやトラブル時にLinux Kernelや コンピュータアーキテクチャの基礎な知識は必須 •

    NICが違えば全く違う機器 • 同じx86でしょ︖は通⽤しない • Linuxの抽象化の隙間に潜り込むというのはそういうこと • ハマればハマるほどLinuxの深みを知ることになる