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

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

Mabuchin
July 06, 2019

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

in BCU30

Mabuchin

July 06, 2019
Tweet

More Decks by Mabuchin

Other Decks in Technology

Transcript

  1. ながらもネットワーク処理を
    ソフトウェアで⾃作していく話
    2019.07.06
    Toshiya Mabuchi
    開発本部 インフラ室 ネットワーク開発グループ


    View full-size slide

  2. ⾃⼰紹介
    • ⾺淵 俊弥 / @raibo
    • 開発本部 インフラ室 ネットワーク開発グループ
    • モンスターストライク等、
    事業⽤サービスネットワークの設計/運⽤/開発
    • 特定⽤途向けのネットワークデータプレーン開発
    今日はこっち

    View full-size slide

  3. パケット処理、好きですか︖
    1. だいすき
    2. 興味ない

    View full-size slide

  4. ⾃社でパケット処理機能を
    ⾃作してる話

    View full-size slide

  5. ⾃社で開発するモチベーション
    1. 汎⽤的な機器でネットワークを構築
    • x86なLinuxサーバーで動く(すぐに交換/使いまわせる)
    2. 冗⻑性の⾼さを保つ
    • アプライアンス+自作で冗長性の確保
    3. シンプルな機能は⾃分たちで設計したい
    • 特定の事業にのみにフォーカスする機能は
    小回りを効かせたい

    View full-size slide

  6. Linux Socketの場合
    NIC Rx NIC Tx
    NIC
    Kernel
    UserSpace
    Rx Ring Tx Ring
    Socket
    libsocket
    App
    sk_buff
    ProtocolStack
    IRQ
    Interrupt
    RSS
    syscall

    View full-size slide

  7. Linux Socketを使ったパケット処理
    • Pros
    • Linuxと各種⾔語の優れた抽象化
    • 開発時もネットワークのかなりの部分を意識せず使える
    • 成熟したプロトコルスタックを利⽤できる
    • TCP等, 複雑なプロトコルに対して先⼈達の肩に乗って利⽤できる
    • Cons
    • ネットワーク処理⽤途で10Gbps~等の⼤規模な通信処理が難しい
    • ネットワーク処理に適⽤すると、1台当たりの処理能⼒が低い
    • 処理的に遅延が乗ってしまう
    • TCP/IPのネットワークスタック処理を⾏うからどうしても重くなる
    • 多段するとより顕著に遅くなる

    View full-size slide

  8. なぜパフォーマンスが出ない︖遅延が乗る︖
    • メモリコピーによるオーバーヘッド
    • 受信パケットをskbに変換し、ユーザスペースにコピーする段階等で
    メモリコピーが行われる
    • Linuxプロトコルスタック処理の重さ
    • IP/TCPレイヤの解釈にはそれなりの負荷がかかる
    ⽤途によっては、賢いプロトコルスタックは使わなくてもOK
    メモリコピーも最⼤限減らして、パケットのFowardに特化したい
    XDP, DPDK等の利用

    View full-size slide

  9. ⾼速パケット処理技術の概要

    View full-size slide

  10. ⾼速パケット処理はF1

    View full-size slide

  11. 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

    View full-size slide

  12. 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

    View full-size slide

  13. ⾃社の取り組み

    View full-size slide

  14. 取り組んでいるもの
    ステートレス実装可能なもの中⼼
    • Static NAT (DPDK/XDP)
    • グローバル ↔ プライベートIPの静的変換NAT
    • GRE Decap Endpoint (DPDK/XDP)
    • ひたすらGREをDecapする
    • マルチクラウド環境上でのアドレスバッティング対策
    • 詳細: モンスターストライクも⽀えるデータプレーン
    • Tap Payload cutter & sFlow Converter (XDP)
    • サンプリング&解析に不要なデータを削除
    • sFlow変換して別NICからFlowコレクターへ⾶ばす

    View full-size slide

  15. 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

    View full-size slide

  16. ペイロードカッター 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

    View full-size slide

  17. 作りはシンプル
    パケット処理部は200⾏いかない
    でも...考慮すべき点は結構ある

    View full-size slide

  18. トラブルや課題

    View full-size slide

  19. NAT実装時トラブル
    謎のパケットロス
    • ある⽇パケットがロスし始めた
    ログを仕込んでも異常が観測されない
    • NICのFirmwareかドライバ周り?
    • でも試験では⼤丈夫だったけど....
    ...テストサーバーとデプロイ⽤でドライバ違う...︕︕
    • 試験 : ixgbe , 本番 : i40e
    同じメーカーでもドライバ/ファームが違えば別機器と思うべし
    適切な期間の性能試験を必ず実施しましょう

    View full-size slide

  20. さらに沢⼭ハマる
    • 特定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

    View full-size slide

  21. 事前にも気を配る点は沢⼭
    • 可能な限りロックを少なくしてる︖
    • ロックレスなアーキテクチャを⽬指していこう
    • GlobalSharedな領域は減らしていこう
    • Affinityを意識して動かしているか︖
    • NumaNodeを考慮したCPU割当してる?
    • CPU L2 cacheを意識した構成で使えている︖

    View full-size slide

  22. 気をつける点まとめ
    • サーバーのファームが⼊れ替え可能か確認しておくべし
    • 切り分けが相当しやすくなる
    • NICもサーバーのOEM提供だとファームが上げづらいことも
    • XDPはカーネルVerによって実装状況が結構違う
    • 実⾏時警告とかほぼ無いので、普通にパケット落ちます
    • ソースやPatchを確認しておこう
    • 例: mlx5のNIC XDP_REDIRECTは4.19~
    • LinuxのKernelやドライバの知識が超重要
    • NAPI/ドライバ/IRQ Balancer/numa/CPU cache/RSS/RFS等、
    ある程度知らないとチューニングできない

    View full-size slide

  23. まあ、様々な問題が起こるんです

    View full-size slide

  24. カーネルという最高の抽象化を跨ぐには
    こういった問題とも向き合うことが必要

    View full-size slide

  25. 転ばぬ先の杖

    View full-size slide

  26. テストと計測
    • テスト駆動な開発
    • 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)
    ↑こんな感じで仮想的に実⾏して結果を確認可能

    View full-size slide

  27. テストと計測
    • 性能試験: T-Rex
    • Python APIを使ってシナリオ作成
    • リリース毎(PR毎)に性能評価を試験
    • ⾃動レポートして性能を⽐較
    駄⽬な実装もこれで分かる!

    View full-size slide

  28. 1. 適切な利用シーン
    2. 保守するというチームでの覚悟
    3. リターンが見込めるケースでの利用
    プロダクションに使うには、それなりのコスト(メンテ等)を支払うことになる
    自社で開発するからといって必ず安く済むとは限らない
    でやっていかないと爆死しちゃいます
    最後に...

    View full-size slide

  29. まとめ
    • XDP/DPDK等で⾼速パケット処理開発
    • 使うべき箇所と選定は⾒極めてやっていきましょう
    • チューニングやトラブル時にLinux Kernelや
    コンピュータアーキテクチャの基礎な知識は必須
    • NICが違えば全く違う機器
    • 同じx86でしょ︖は通⽤しない
    • Linuxの抽象化の隙間に潜り込むというのはそういうこと
    • ハマればハマるほどLinuxの深みを知ることになる

    View full-size slide