OVSでSRv6を使ってみる

OVS(Open vSwitch) 3.2でSRv6がサポートされた 1 ので使ってみる。 その使い方を端的にいうと以下のように type=srv6 としたポートを作成すれば良い。 VXLANやGeneveなど既存のトンネリングと同様のフレームワークを使って実装されているので、 options:remote_ipやoptions:local_ip でトンネルの両端(SRv6では双方のSIDに相当)を指定する。 それらに加えてSRv6では中継するルータをSegment Listとして設定できるよう特別なオプション options:srv6_segs が存在する。 ちなみにInner PacketとしてはIPv4、IPv6両方をサポートしている。 ovs-vsctl add-br br0 ovs-vsctl add-port br0 srv6_0 -- \ set int srv6_0 type=srv6 \ options:remote_ip=fc00:100::1 \ options:srv6_segs="fc00:100::1,fc00:200::1,fc00:300::1" OVSでは主にkernelspaceとuserspaceの2種類のデータパスが存在しているが、 SRv6はuserspaceのみ対応している 2。 つまりDPDKやAFXDP 3 のような仕組みを使ってデプロイする必要がある。 Feature Linux upstream Linux OVS tree Userspace GRE 3.11 1.0 2.4 VXLAN 3.12 1.10 2.4 Geneve 3.18 2.4 2.4 … … … … SRv6 NO NO 3.2 さてどうやって動かすのか。 mininetのスクリプト 4 をベースとしてそれをシンプルなコマンド列に落とし込んだ。 以下のような構成で動かしてみる。...

March 29, 2024

MininetでSRv6 L3VPNを動かす

Mininet 1 の中でSRv6 L3VPNを動かす実験をやってみた。 スクリプトはこちら。 ひとまず図のような小さな構成で動かすことができたのでここで紹介したい。 2台のルータ(r1とr2)がSRv6によるEncap/Decapを担当しており、 r1-r2間でL3VPNに関する情報をeBGPで交換する。 r1とr2はそれぞれ2つのVRF(vrf10とvrf20)を持っており、 VRFごとにテナントが分けられている(Tenant10とTenant20)。 もちろんテナントごとにL3の疎通性はなくIPレンジの重複は許されているので、 ここでは同じPrefixを割り当てている。 r1とr2ではBGPデーモンとしてFRRを使っている。設定の一部を抜粋するとこんな感じ。 FRRの設定ファイル(frr.conf)全体についてはmininetlab 2 に記載している。 FRR本体のテストコード 3 が非常に簡潔で綺麗にまとまっているので、それを参考にした。 FRRではSRv6 L3VPNの開発は活発に行われているので、できれば新しいバージョンをおすすめする。 ここではFRR 8.5を使った。 mininet> r1 vtysh -c "show running-config" # 一部抜粋 router bgp 65001 bgp router-id 203.0.113.1 bgp default ipv4-vpn bgp default ipv6-unicast bgp bestpath as-path multipath-relax no bgp network import-check neighbor r1-eth0 interface remote-as external ! segment-routing srv6 locator default exit exit ! router bgp 65001 vrf vrf10 bgp router-id 203....

July 7, 2023

TRexのラッパーを作ってみた

まずはTRexの紹介から。 TRex 1 はソフトウェア実装のトラフィックジェネレータで、 Stateful/Stateless の2モードをサポートしている。 Statelessは状態を持たない対象DUT(Device Under Test)宛に パケット列を生成するためのモードで、 スイッチングやルーティングの性能計測ツールとして利用できる。 TRexは多機能ではあるが、個人的なニーズとしては単純なTCP/IPのパケット列を そのサイズを変えながら生成したいことが多いのでTRexのラッパーとしてautotrex 2 を作ってみた。 autotrexは自動的にベンチマークの実行・集計をするためのもので、 例えば成果物として下記のような図を簡単に生成できる。 ここでは簡単に使い方を記録しておく。 autotrex では trex_cfg.yaml (TRexの世界でよく使われる設定ファイル)に記載した2つのポートのうち、 1つ目のポートが送信、2つ目のポートが受信を担当する。 送信・受信それぞれのパケット数をカウントし、その誤差がある閾値 (例えば0.01%)以下であるような最大のパケットレート (Packet Per Second、PPS)を二分探索で求める。 もちろん生成したいパケット列は自分で下記のように自由に設定できる。 私がよく使うものはautotrexリポジトリ同梱されていて 3、 簡単に使えるようになっている。 # tcp_1pkt.py から抜粋 pkt=Ether()/IP(src="16.0.0.1", dst="48.0.0.1") / TCP(dport=12, sport=1025)/(payload_size*'x') ./run.sh tcp_1pkt.py のようにパケット列を記載したPythonファイル tcp_1pkt.py を 引数に与えて run.sh コマンドを発行すると、自動的にサイズを 変えながらパケット生成が行われる。 一連のベンチマーク実行が完了すると、成果物としてパケットレート、L1・L2のスループットを表すcsvファイルとpngファイルが出力される。 どのようなパケットが生成されるかについては./simulate.sh tcp_1pkt.pyコマンドで 事前に知ることができる。 独自にパケットを生成したい場合には便利かもしれない。 性能が欲しい環境では下記のように trex_cfg.yaml でCPU情報を設定する。 経験的にmaster_thread_id、latency_thread_id、threads にはユニークなCPUを 割り当てた方が高い性能を得られる。詳しくはドキュメント 4 に説明がある。 platform: master_thread_id: 0 latency_thread_id: 5 dual_if: - socket: 0 threads: [1, 2, 3, 4] 以上、個人的に使っているツールの紹介。おしまい。...

June 9, 2023

Open vSwitch AF_XDPの背景と使い方

最近、OVS(Open vSwitch)がAF_XDPに対応したとの話を聞いたのでどういう背景があったのか、そしてどうのように使えば良いのか調べてみた。 OVSは、カーネルモジュールとユーザスペースプロセスから構成されている。 その構成の部分で、以下のような課題が見えてきた1ので、最近AF_XDPを使った実装に置き換えが進められているようだ。 カーネル本体の更新やシステム全体のリスタートを要求する修正がある カーネル開発者の方針や実装に影響を受ける DPDKで速度面で劣る バックポートが多すぎる ディストリビューションのサポートが受けられなくなることがある どれも構成変更を推し進めるには妥当な理由に思う。 下図は、バックポートと新規機能それぞれに起因する差分をコード行数によって比較したもの。 バックポートにかかるコストが読み取れる。 ちなみに、カーネルモジュールを使った実装は2022年4月にリリース予定のOVS 2.18で廃止される予定2になっている。 出典:Revisiting the Open vSwitch Dataplane Ten Years Later それならユーザスペースでデータプレーンを実装したDPDK(Data Plane Development Kit)で良いじゃないかいうと、 それはそれで課題がある。 ipコマンドなどカーネルネットワークスタック向けのツールと相性が良くない 特定のNICやCPUを占有してしまう この辺りの課題を解決するアプローチとしてAF_XDPの導入が進められている。AF_XDPを使うと、XDPのフックポイントに小さなeBPFプログラムを仕組んでおき、カーネルネットワークスタックをバイパスした上で、ユーザプロセスへとパケットを転送することができる。 安定した仕様を持つので、将来のカーネルリリースでも継続して使えるはず。 既存ツールとも相性が良い。DPDKからAF_XDPを使おうという話 3 もあるが、DPDKとOVSの間のメンテナンスコストが残る。というわけで、OVS本体でAF_XDPをサポートしようということになったようだ。 ところでAF_XDPを使うとどのようにパケットが転送されるのだろうか。 AF_XDP は fill リングと competion リングの2つのリングを持つ。 その各要素はディスクリプタとなっていて、umem 領域を指している。 パケット受信時の流れを図中の番号に沿って見ていく。 まずアプリケーションはfillリングに空きディスクリプタを登録する カーネルは fill リングからそのディスクリプタを取り出す umem領域にパケット本体を書き込む そのumem領域を指すようなディスクリプタを completion リングに登録する アプリケーションは completion リングからディスクリプタを取り出す そのディスクリプタの指す umem 領域からパケット本体を取り出す 出典:Revisiting the Open vSwitch Dataplane Ten Years Later 性能はどうだろう。25G NICで64バイトショートパケットを流した時のスループットとCPU使用率についてのデータがあった。 仮想マシンを経由するPVPのシナリオでは、vhostuser の採用によってCPU使用率は差し置いたままで、 スループットが向上する。 ただ、DPDKには届かない。コンテナを経由するPCPのシナリオでは、ユーザ・カーネル間のデータコピーを省略できるため、AF_XDPがベストチョイスかと思う。 向き不向きがあるので、シナリオによって選び方が変わるだろう。...

December 7, 2021

Understanding Linux Network Internal 1~2部 読書メモ

このブログではネットワークに関する比較的新しい技術について触れてきたが、たまには古きを温めるのも良いだろうということで読んでみた。Linuxカーネルは今後も長きにわたって使われるはずで、カンペキな理解でなくとも、取っ掛かりだけでも掴んでいる意味は大きいと思う。この本は1,000頁超えで、1~7部から構成されているので、一気に読むのはモチベーション維持が難しいと思う。この記事ではとりあえず現時点で読んだところまでをまとめたい。カーネルバージョン 2.6.39 のソースコードを手元に置いて、読み進めていった。ビルド方法などは前回の記事 1 のとおり。 1部 ネットワークに関する重要なデータ構造として struct sk_buff と struct net_device がある。まずはこの2つのデータ構造を掴むことが肝要だと思う。struct sk_buff は(フラグメンテーション云々の話を抜きにすると)1つのパケットに対応する。しばしばそのインスタンスは skb という名前が付けられる。skb->data が処理を担当しているネットワークレイヤのヘッダを指している。例えば、L2の処理を行っている際にはskb->data はL2ヘッダ の先頭を指している。処理の進行に伴って、このポインタは移動していく。実データの前後に余白が設けられている。 +------------+ skb->mac skb->nh | | | | | head-----------> +------------+ | | | | | headroom | v v | data-----------> +------------+ +---------+---------+---------+--- | | | | | L2 | L3 | L4 | | tail | | Data | | header | header | header | ... | | | | | +---------+---------+---------+--- | end | | | | ^ ^ | | +----------> +------------+ | | | | | | tailroom | | | | +-------------> +------------+ +---------+ | | skb->data +------------+ struct sk_buff この構造体にどんなメンバがいるか見ていく。users が参照カウンタに対応していて、sk_getやkfree_skbで操作できる。mac_header など各レイヤに対応するポインタもある。cbはコントロールバッファの略で、48バイトの領域を各レイヤの中でプライベート(他のレイヤを意識せず)に使える。struct sk_buffは双方向リストで管理されていて、リスト全体は struct sk_buff_head に対応する。デバッガを使って、中身を見ていく。送信を担当する関数にアタッチしてみると、struct sk_buff内部に保持されたIPヘッダ の中身を見ることができる。...

August 26, 2021

Cloud Native Data Center Networking 読書メモ

気になるところだけつまみ読みした。よく纏っていて手元においておきたい一冊。 全体を通して KISS(Keep it simple, stupid) の重要性が主張されているように思う。 物理面 Leaf・Spine間に複数のリンクを繋がない。ルーティングの観点から見た時、あるリンク障害となった時に別のリンクが生きていることから、障害前と同量のトラフィックが流れてきてしまう。あるリンクが障害となっていることため期待する帯域を確保できずパフォーマンスが劣化する。代わりにスイッチを増やすほうが良い。 Spineをただの経由デバイスとして扱う。あるSpineを特殊な用途(例えば外部接続)として使ってしまうと、そのSpineにトラフィックが集中してしまう。Border LeafやExit Leafをおけば解決する。例外を排除する。単純さことが強さ。 3層のClosトポロジが望ましい。層の数というよりは巨大かつ高機能なスイッチを使うことが適切でない。仮にSpineスイッチに巨大なスイッチを採用することで無理やり2層のClosネットワークを構築すると、高機能なためにトラブルシュートが複雑になってしまう。LinkedInやDropboxでは、chassis-switchからfixed-form-factorスイッチへ切り替えた(要出典)。 スイッチ障害時に即座に交換できるようスペアを用意する。わざわざサポートに交換を依頼すべきでは無い。 ケーブルやトランシーバーにはNOSベンダでテスト済みのものを使う。 機能リストを比較して選定すべきでは無い。ミニマニストになるべき。 BGP周り 本書のASN番号の割り当てモデルに従う。 Leaf-Spine-SuperSpineの3層構成 Leaf-Spineの集合をPodと呼ぶ LeafはユニークなASN Pod内の全てのSpineは同一のASN(Podごとに別のASN) SuperSpineは同一のASN Unnumbered BGPを使う。 ループバックIPアドレスが正当で、正しく広報されていることを確認する。 マルチパスを有効にする。 複数のアドレスファミリーの到達性に対し、同一のeBGPセッションを使う。 BFDを使う。 不正なPrefixを受け取らないようroute mapを設定する。 Leaf以外ではルートを集約しない。 即時反映のためにBGPの advertisement interval timer を0秒とする。 keepalive timerを3秒、hold timerを9秒、connect timerを10秒とする。 設定を最小化する。大事。 EVPN周り Distributed Symmetric Routingモデルを採用する。 アンダーレイのrouted multicastを避ける。 BUMパケットを使わない。 設定を最小化する。繰り返しになるが大事。 自動化まわり 単純なところから手をつける。ループバックIPアドレスを割り当てるなど。 コードとデータを分ける。 実際に設定を適用する前にバリデーションを設ける。 Gitを使う。 ローリングでアップデートする。Closトポロジでは影響範囲をコントロールできる。 言語やツールを統一する。AnsibleとChef、RubyとPythonを混ぜない。 Ansibleなど巨大なコミュニティを持つツールを使う。

May 28, 2021

EVPN in the Data Center 読書メモ

EVPN in the Data Center を読んだので、 メモを残しておく。 メールアドレスなどを登録するとNVIDIAのページからPDFを 無料でダウンロードできる。 あくまでも調査中の個人的なメモなので間違いも含まれている。 イントロ Closトポロジで構成されたL3ネットワーク上で、L2を前提とするアプリケーションをどのようにデプロイすれば良いか。 例えば、L2のマルチキャストやブロードキャストを使って死活監視やメンバの検出を実現するようなアプリケーションがこれに該当する。 Ethernet VPN(EVPN)は、この課題に対して、L3ネットワークの上にオーバレイによって仮想的なL2ネットワークを提供することで解決する。 ここで、EVPNのコントロールプレーンにはBorder Gateway Protocol(BGP)が使われる。 EVPNとMultiprotocol Lable Switching(MPLS)の組み合わせで成熟した技術であるが、Virtual Extensibe LAN(VXLAN)への応用ができるようになった。 端的に言うと、EVPNはコントローラベースのVXLANに対する新たなアプローチとみなせる。 EVPNはサービスプロバイダの世界を起源に持つので、データセンタネットワークの世界から見ると、馴染みの薄い用語が多く理解しづらい。 この本では、OSSであるFRRを設定例として使いつつ説明していく。 ネットワーク仮想化 仮想ネットワークにおいては、あるユーザは、まるで別のユーザ(あるいはテナント)が存在しないかのようにネットワークを占有できる。 パケットがどの仮想ネットワークに紐づいているかは、多くの場合、パケットヘッダのVirtual Network Identifier(VNI)によって判断する。 VLANやL3VPN、VXLANはこれに該当する。 VLANはインライン仮想ネットワーク、VXLANはオーバレイ仮想ネットワークであり、後者の方がスケーラビリティや運用のしやすさの面で優れている。 なぜなら、上流のスイッチは仮想ネットワークについてのフォワーディングテーブルを持つ必要がなく、管理すべき状態が少なくてすむため。 さらに、仮想ネットワークの追加・削除に伴う影響は、エッジスイッチだけに限定されるため、短時間でユーザへ提供できる。 オーバレイ仮想ネットワークでは、 トンネルのエンドポイント(カプセル化したり、カプセル化をほどいたりするノード)をNetwork Virtualization Edge(NVE)と呼ぶ。 主なL3のトンネリング技術には、VXLANやGRE (IP Generic Routing Encapsulation)、MPLSがある。 VXLANではエンドポイントをVXLAN Tunnel end Point(VTEP)と呼ぶ。 オーバーレイ仮想ネットワークはさらに2つに分類できる。 1つのエンドポイントが唯一のエンドポイントとのみトンネルを張る。L3VPN+MPLSがこれに該当する。 1つのエンドポイントが複数のエンドポイントとトンネルを張る。Virtual Private LAN Switching(VPLS)がこれに該当する。 パケットがトンネル化されていたとしても、アンダーレイのノードはトンネルヘッダしか見ない。 そのため、すべてのパケットは同一の送信元・送信先をもつとみなされ、同一のパスを通ってしまう。 そこで、VXLANやその他のプロトコルでは、UDPのソースポートを書き換えることによって、5タプルのハッシュ値を変更し、別のパスを通すことができる。 サーバノードでは、NICでのTCPセグメントオフロードやチェックサムオフロードによって、 パケット処理にかかるCPUサイクルを削減できる。 しかし、トンネル化されているときにはこれと相性が悪い。 もちろん、VXLANヘッダを理解するNICも存在するが、この相性問題から、 多くの場合サーバノードではなくネットワークノード側でVXLANのカプセリング操作を行っている。 また、トンネル化はヘッダの追加によって実現するので、MTUサイズに気をつける必要がある。 コントロールプレーンは以下を担当する。 パケットの送信先を見て、適切なNVEを見つけ出す。VXLANでは、VNIとMACの組みを見て、NVEのIPアドレスを見つけ出すことに対応する。 全てのNVEに対して、そのNVEに関係する仮想ネットワークの一覧を提供する スイッチのチップは、各社独自のASICから、マーチャントシリコンへと移り変わっている。 本書の執筆時点では、トンネルヘッダとしてIPv6を使うことは多くの場合難しい。 Broadcom Trident2 でVXLANをサポート。Trident2+とTrident3でVXLANのルーティングをサポート Mellanox SpectrumチップはVXLANのブリッジングとルーティングをサポート 他にもCariumやBarefoot NetworksのチップがVXLANのブリッジングとルーティングをサポート ソフトウェア側について見てみると、LinuxのVXLANサポートは随分前からあり、VRFのサポートは2015年にCumulus Networksによって追加された。 カーネル4....

May 12, 2021

MininetでFRR(BGP Unnumbered)を動かす

https://github.com/bobuhiro11/mininetlab の紹介。 Mininet を使うと単一のマシン上でいくつかのスイッチとホストを動作させることができる。 これを使って仮想的にホストを2つ立ち上げ、その間をFRRパッケージに含まれるBGP(Unnumbered)で接続してみる。 Mininetでは以下のようにPythonでトポロジや各ホストにおけるコマンド実行について記述できる。 一見複雑にみえるFRRもdaemons、vtysh.conf、frr.confの3つのファイルを正しく配置しておけば、 frrinit.sh startで簡単に起動できる。 ホストごとにnetnsは分割されているが、mountns は分割されていない(要確認)ため、 /etc/frrや/var/run/frrが2つのホスト間で衝突してしまいFRRが正常に起動できなかった。 これはprivateDirs = ['/etc/frr', '/var/run/frr'] によって回避できる。 #!/usr/bin/env python from mininet.net import Mininet from mininet.log import setLogLevel import time frr_conf = ''' hostname {name} password zebra ! router bgp {asnum} bgp router-id {router_id} bgp bestpath as-path multipath-relax neighbor h1-eth0 interface remote-as external neighbor h2-eth0 interface remote-as external address-family ipv4 unicast network {router_id}/32 network {network} exit-address-family ! line vty ! end ''' vtysh_conf = ''' service integrated-vtysh-config ''' daemons = ''' bgpd=yes vtysh_enable=yes zebra_options=" -A 127....

May 8, 2021

Running BGP in Data Centers at Scale

NSDI 2021 でのFacebookの論文 1 を読んでみて、間違いをおそれず自分の言葉でまとめてみる。 概要 FacebookのBGPをベースとしたデーターセンターネットワークについてまとめもの。AS番号の割り当て、経路集約、BGPポリシー、独自のBGP実装に対するテストやデプロイ手法など実践的な内容となっている。終盤には実際に過去2年間の運用において経験した事故についても触れられている。 1 イントロ Facebookはいくつかのデータセンターを展開しているが、それらのデータセンターでは共通するAS番号の割り当てスキーマを持っている。つまり、データセンターAのスイッチに相当するデータセンターBのスイッチも同じプライベートAS番号を持つことになる。大量のスイッチでBGPエージェントを動かし全体として階層的な構造を持つClosトポロジーを採用しているが、その全てのレイヤで経路集約を行っており、ハードウェアのFIBを最小限に保っている。BGPはもともとインターネットで使われていた技術で、その歴史の中で収束上の問題、経路の不安定さ、設定ミスによる事故を経験してきたが、データセンターに応用する場合には運用者が全てのスイッチを管理・運用できるため、これらの問題に柔軟に対応することができる。例えば、通信障害に対しては、事前にバックアップ経路を入れておくことで、例えリンクあるいはスイッチに障害が発生したとしても、その障害を伝播させる範囲を限定することで、、迅速に収束させることができる。さらに、ベンダ製BGPエージェントよりも高速な開発スパンを持つミニマムな実装を目指して、Facebook社内で独自にBGPエージェントを開発している。 2 ルーティング設計 スケールするネットワークの構築が目的だが、同時に短期間に構築する必要がある。また、どんなに可用性を追求しようとも事故は起きるので、その影響範囲を設計として縮小したい。当時、中央集権のSDNを開発することに比べ、BGPを使ったルーティング設計を展開する方がスピードと実績の両面で優位にあった。もともとベンダ製スイッチとそのBGP実装を使っていたが、後に独自にハードウェアとBGPエージェント実装を行うようになった。 ルーティングプロトコルとしてOSPFやISISのようなIGPも検討したが、スケール性能が不透明で経路の伝播を制御できそうになった。BGPとIGPを組み合わせたハイブリットなルーティング設計も考えたが運用コストが高くなるので、最終的にBGPを唯一のルーティングプロトコルとして採用することにした。 2.1 トポロジ設計 サーバポッドと呼ばれるラックの集合をモジュールとしてまとめ、それをSpine Planeがまとめ上げる形でデータセンターを設計する。トポロジについては下図から読み取れるが、ここでは言葉でも書いておく。1つのサーバポッドは48個のサーバラックから構成され、16個のFSWに接続される。サーバポッド間は、複数のSpine Planeを経由することで、相互に接続される。Spine Plane自体の数は、1つのサーバポッドの中に展開されるFSWの数と等しい(下図では青黄緑紫の4つ)。Spine Planeとサーバポッド間でリンクを増やすことによって帯域を増大できる。つまり、サーバポッドの追加によってコンピュートリソースを、SSWの追加によってネットワークリソースを増大できる。 出典: Running BGP in Data Centers at Scale 2.2 ルーティング設計の指針 同一性と単純さを求めるというのが2つの大きな柱となる。これらを達成するために、BGPで利用するFeature Setを最小限にし、複数のスイッチへできるだけ同一の設定を適用しようと取り組んでいる。同じTier(RSW、FSW、SWW)の中では、OriginateするプレフィックスやBGPピアアドレスを除いて、同じ設定を投入している。また、ベンダ依存を取り払うために、特定のプラットフォームに依存しない形で、ネットワークトポロジデータを作っている。このデータには、ポートマップ、IPアドレス割り当て、BGPの設定、ルーティングポリシーが含まれる。Robotron 2 と呼ばれるシステムによって自動的にプラットフォームごとの設定へと変換している。 2.3 BGPピアリングと負荷分散 ピアリングは直接繋がれた1ホップのeBGPセッションでのみ行う。マルチホップは使わない。スイッチに複数のリンクがあった場合には、それぞれ個別のeBGPセッションとして扱う。負荷分散はECMPによって実現する。後述する経路集約やルーティングポリシーの仕組みによって、障害発生時・復旧時に発生するネクストホップの追加・削除に伴うFIBの更新は軽量で、運用は簡潔になった。単純さを理由に、経路ごとの重み付けは行なっていない。 2.4 AS割り当て AS割り当ては全てのデータセンターで同一である。例えば、あるデータセンターで1つ目のSSWにAS65001を割り当てたとすると、別のデータセンターでも同じAS番号が再利用される。サーバポッドには、それ自身を示すAS番号が割り当てられ、そのサーバポッドの外からはこのAS番号によって識別される。つまり、サーバポッド内のスイッチ(RSW、FSW)のAS番号はそのサーバポッド内に閉じることになる。この性質から、RSWとFSWのAS番号は全てのサーバポッドで再利用される。Spine Planeにはデータセンター内でユニークなAS番号が割り当てられる。Spine Planeは複数のSSWから構成されるが、それらSSWは同一のAS番号を持つ(SSW間でピアを張ることはないので共通化できる)。 出典: Running BGP in Data Centers at Scale 2.5 経路集約 階層的に全てのTierにおいて、経路集約を行なっている。例えば、RSWは配下のサーバのIPを集約し、FSWは配下のRSWの経路を集約する。経路集約によって、数十万経路から数千経路へと大幅に削減できる。 3 ルーティングポリシー BGPを使うことで、ベストパス選択による高可用性の恩恵を受けることができる。さらに、経路広報に介入できることから、伝播を高精度に操作できる。 3.1 ポリシーのゴール 信頼性、保守性、スケーラビリティ、サービス到達性の4項目を達成したい。 信頼性 経路伝播のスコープを制限し、事前にバックアップ経路を定義していく。バックアップ経路はFSW1->RSW2->FSW2->RSW1のようなもので、BGPコミュニティタグをつけた上で、あらかじめサーバポッドに閉じたスコープで伝播させておく。バックアップ経路があることで、あるリンクがダウンしても、サービスを継続できる。伝播がサーバポッドに閉じるという性質から、収束までの時間が短く、別のサーバポッドへの影響がない。また、実際にはバックアップ経路はECMPによって複数存在することになるので負荷は分散される。 保守性 スイッチにはアップ・ダウンのような2種類の状態ではなく、LIVE・DRAINED・WARMという3種類の状態を持つ。WARMはRIBやFIBが準備完了だが、トラフィックは流れていない状態に対応する。この3状態を持つことで、一日あたり平均242回のオペレーションを行なっているが、パケットドロップは発生していない。 スケーラビリティ FSWではラックレベルのプレフィックスを集約するため、サーバポッド追加による経路数の増加が小さくスケールする。 サービス到達性 サービスはVIPを経由して提供され、そのVIPは複数のインスタンスからBGPによって広報される。広報のため、インスタンスはRSWに対して直接BGPセッションを張っている。 出典: Running BGP in Data Centers at Scale...

April 21, 2021

Use of BGP for Routing in Large-Scale Data Centers

RFC7938を読んだのでメモしておく。 ちょっとかじった程度の話なので、言葉づかいは不適切かもしれない。 概要 サーバが10万台を超えるラージスケールなインフラにおいて、単純かつ高安定性なネットワーク設計手法についてまとめる。BGPを唯一のルーティングプロトコルとして採用する。 イントロ Web検索エンジンのような大規模な分散システムのインフラを、単純かつ高安定性なネットワークによって少ない人数で運用したい。 ネットワーク要件 帯域と遅延が重要な要素。伝統的な木構造のネットワークはnorth-southのトラフィックに対しては対応できる。ただ最近Hadoopのようなサーバ間のトラフィックパターンが増えたことから、east-westのトラフィックが増えることになり、伝統的な木構造のネットワークで対応するには、ポート密度など物理的な制約から難しくなってきた。 データセンタの設備投資額についてみると、データセンタ全体の10~15%をネットワークが占める。削減にあたって、2つのアプローチがある。1つ目は、同一のハードウェアやデバイスを使うなど、全てのネットワーク機器を統合するということ。まとめて購入することで購入コストや管理コストの削減につながる。2つ目は、ネットワークベンダ間で価格を競争させるということ。もしベンダを分散させるなら、ソフトウェア要件を最小にして、柔軟性を持たせることが重要になる。 オペレーションについてみると、L2ネットワークではブロードキャストやユニキャストのストームがそのドメインで大規模なパフォーマンス上の問題や稼働率の低下を引き起こす。これはL3ルーティングを組み込んだ設計を行うと、その影響範囲を縮小できる。一方で、L3ルーティングでは、コントロールプレーンの分散に起因する障害を考慮する必要が出てくる。これはルーティングプロトコルの種類の削減することで対応する。 アプリケーションのロードバランシングも重要な観点になる。これまでは経路上に専用のデバイスを置くことで実現したが、トラフィックの増大へは対応しづらい。そこで、複数台のローバランシング専用ノードを並べることで、水平にスケールできる構成が望ましい。これはAnycast Prefix AdvertisementとEqual Cost Multipath(ECMP) によって実現できる。 要件をまとめると、 REQ1: デバイスのアップグレードではなく、同種のデバイス追加によって、水平にスケールする構成が望ましい REQ2: ソフトウェアのfeatureやprotocolを最小化したい REQ3: 運用コストが小さくてシンプルな実装を持つルーティングプロトコルが良い REQ4: 機器やプロトコル起因の障害範囲を小さくしたい REQ5: プロトコルのfeatureによってトラフィックエンジニアリングを実現したい データセンタトポロジ トラディショナルなtree-basedなトポロジと、Clos-basedなトポロジを比較してみる。前者は、下図のように3層のスイッチ(Coreレイヤ、Aggregation/Distributionレイヤ、Accessレイヤ)から構成され、上位の層では帯域を確保するために、ポート密度や帯域容量を上げることになる。この構成では前述したように、Tier 2を増やしたときに、それを格納できるほどまでTier 1のポート密度を上げることができない。つまり、各スイッチの次数(グラフのある頂点から出る辺の数)の制約でスケールしない。 +------+ +------+ | | | | | |--| | Tier 1 | | | | +------+ +------+ | | | | +---------+ | | +----------+ | +-------+--+------+--+-------+ | | | | | | | | | +----+ +----+ +----+ +----+ | | | | | | | | | |-----| | | |-----| | Tier 2 | | | | | | | | +----+ +----+ +----+ +----+ | | | | | | | | | +-----+ | | +-----+ | +-| |-+ +-| |-+ Tier 3 +-----+ +-----+ | | | | | | <- Servers -> <- Servers -> Figure 1: Typical DC Network Topology 後者のfolded Closトポロジ(fat treeとも呼ばれる)は水平スケールのためのアプローチである。奇数台のステージ(次元とも呼ばれる)を一様な要素で構成する。この構成はLeaf・Spine構成とも呼ばれる。SpineがTier 1、LeafがTier 2に対応する。...

April 13, 2021

SRv6のLinux Kernel実装

SRv6とは SRv6はIPv6拡張の一つでSource Routingを実現するもの。Source Routingは、データ送信者がその宛先だけでなく、経路についても指定することを意味する。 経由するノードをSID(Segment Identifier)によって識別し、そのリストをパケットヘッダに含めることで、経路を自由に制御できる。SRv6では、IPv6アドレスがSIDに対応する。 SRv6は、EITF(Internet Engineering Task Force)を中心に仕様の策定が進められている 1 。 2020年3月にはRFC8754 2 として公開された。 SRv6で使われるIPv6ヘッダのSRH(Segment Routing Header)について詳しく見ていく。 まず、Routing TypeはSegment Routingではマジックナンバー4になる。 Segment List[0] ~ Segment list[n] のエントリに、最後のセグメントから降順に経由させたいセグメント一覧を列挙していく。 次のセグメントへの番号をSegments Left、最後のSegmentの番号をLast Entryに格納する。 セキュリティ機構であるHMACなど付加情報がある場合には、TLV(Type Length Value)として追加する。 Routing headers are defined in [RFC8200]. The Segment Routing Header (SRH) has a new Routing Type (4). The SRH is defined as follows: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Header | Hdr Ext Len | Routing Type | Segments Left | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Last Entry | Flags | Tag | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Segment List[0] (128-bit IPv6 address) | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | ....

January 17, 2021

mTLS(Mutual TLS)メモ

mTLSとは mutual TLSやTLS相互認証と呼ばれているもの。 きれいにまとまっている記事 1 を読んだので、正確な言い回しができるか自信がないけれど、自分の言葉でメモしておく。 そもそもTLSとは、ネットワーク上で何らかの通信を行う際に用いられる暗号化のためのプロトコルである。 ウェブラウジング、電子メール、Voice over IPなどで利用される。 特にウェブブラウジングにおいては、アドレスバーの左側に鍵マークが表されるので馴染みがある。 TLSは、PKI(Public Key Infrastructure)とX.509証明書から構成される。 X.509は証明書のフォーマットの標準で、httpsの基幹となるTLS/SSLで採用されている。 オンラインだけでなく、オフラインでも電子署名などの用途で使われることもある。 X.509は、公開鍵といくつかのアイデンティティ(ホスト名、組織情報など)から構成され、自分自身あるいは認証局によって署名される。 デフォルトではTLSはクライアントがサーバの身元を検証するだけに使われるため、サーバがクライアントを検証するしくみはアプリケーション側で実装する必要があった。 そこで、コンシューマ向けウェブサービスよりもさらに高いセキュア要件のあるビジネス用途において、サーバ・クライアントが相互に認証できる仕組みとして mTLS が使われることになった。 実行例 単純に動作を知りたいだけなので、curl(クライアント)とNode.js(サーバ)を使って、動作を試してみる。 まず、クライアントとサーバ双方の認証局 CA を作る。 -new -x509が、自身で署名したルートCA用X.509証明書の作成リクエストに対応する。 また、-nodes (No DES)が秘密鍵にパスワードの設定しないことに対応する。 ca.crt の内容を確認すると、SubjectとIssuerが同じ値 example-ca を持っていることがわかる。 つまり、このCAは自身で署名されたということである。 CA:Trueとなっているため、他の証明書に署名することができる。 # 認証局の作成 # 成果物は ca.key と ca.crt # どちらもPEMフォーマット(base64化された秘密鍵とX.509証明書)
$ openssl req -new -x509 -nodes -days 365 -subj '/CN=example-ca' -keyout ca.key -out ca.crt # 証明書の確認 $ openssl x509 -in ca.crt -text -noout Issuer: CN=example-ca Subject: CN=example-ca CA:TRUE 続いて、サーバの秘密鍵を作成する。 この秘密鍵に対応する証明書はCAから署名される必要があるので、Certificate Signing Request(CSR) を作成する。...

January 12, 2021

RoCE v2 メモ

RDMAをEthernet上で実現する仕組みであるRoCE v2についてマイクロソフト社内での運用 1 について調べてみた。 イントロ RDMAというとInfinibandというイメージだったが、最近はiWARP、RoCEなども候補になる。 RoCEを略さずにいうと、Remote Direct Memory Access over Converged Ethernetとなる。 Remote Direct Memory Access とは、CPUを経由せずにリモートノードの主記憶を読み書きできる仕組みである。Converged Ethernet とはロスレスなEthernetであると理解した。 RoCEは2種類のバージョン v1 と v2 がある。v1はL2ヘッダの後ろにRDMAのペイロードが置かれる構造をしている。原理的にL2サブネット間でのRDMAを想定している。一方、v2はL4ヘッダの後ろにRDMAのペイロードが置かれる。つまり、Ethernet/IP/UDP上のプロトコルなので、IPルーティングを経由したRDMAを実現できる。 そもそもなぜデータセンター内でRDMAが必要になるからというと、TCP/IPスタックで満たせない需要が出てきたからだと思う。例えば、40Gbps・8セッションの通信におけるCPUの利用率をみると、送信側で8%、受信側で12%となる。このオーバヘッドの削減がRDMA導入の狙いとなる。遅延の削減も狙いとなることが多い。エンドノードのネットワークスタックがソフトウェア実装(Linuxカーネルなど)であるため、原理的に遅延が入り込む余地(スケジューリング待ちなど)がある。また、TCP/IPはパケットドロップの発生を前提とした輻輳制御を行うので、ここも遅延の原因となる。 今回はIP CLOS ネットワーク上で RDMA を実現する。ほぼ全てのリンクが40Gで、全てのスイッチがIPルーティングを担当する。 RoCE v2は5-tupleを持つので、ECMP(Equal Cost Multipath Routing)の恩恵を受けられる。 ロスレスネットワークでは、通信経路中のスイッチで、バッファオーバーフローなどによるパケロスが起きてはならない。 そこで、PFC(Priority-based Flow Control)を使って、流量を制御する。 PFCは、リンク間のプロトコルで、スイッチのバッファ利用率がある閾値を超えると、リンク相手のスイッチに対して pause frame を送出する。 pause frame はパケットの送出停止を依頼する意味を持つ。 キューごとに Priority を割り当てられるので、キューの単位でpause frameを送ることができる。 ただ、pause frame を送ってから、実際の送信が停止されるまでには、時間差があるので、余裕を持たせておく。 マイクルソフト社内では、スイッチがShallow Bufferなので、2つのPrirorityのみを使っている。 片方が遅延を重視するリアルタイムトラフィック用途、もう一方が帯域を重視するバルクデータトラフィック用途に使われる。 PFCはリンク間のプロトコルなので、RDMAのエンドノードに到達するまでに何度かスイッチを伝播する。 そこで、エンド間のプロトコルであるDCQDN(Data Center Quantized Congestion Notification)と組み合わせて使っている。 PFCプロトコルには、Priorityをどのヘッダに設定するかによって、2種類の仕様が存在する。もともとはVLANタグの中にPriorityを設定するVLAN-basedな仕様だった。ただ、IPルーティングを前提とするIP CLOSネットワークや、PXEブートとの相性が良くなかった。そこで、IPヘッダのDSCPにPriorityを設定するDSCP-basedな仕様が出てきた。マイクロソフト社内では、単純にPFC PriorityをDSCPの値として割り当てている。現在では主要なスイッチベンダがDSCP-basedをサポートしている。 出典:RDMA over Commodity Ethernet at Scale...

November 25, 2020

vDPA(Virtio Data Path Acceleration)メモ

仮想マシンやコンテナ環境で、高パフォーマンス(NICワイヤレート)かつ柔軟なIOを実現する方法。 まだあんまり日本語の情報は見つからない。 触ったわけではないので、勘違いなどあるかも。 vDPAカーネルフレームワーク 2020年3月に、vDPA カーネルフレームワークがLinux 5.7にマージされた。 vDPAカーネルフレームワークが扱うvDPA デバイスとは、 データプレーンがvirtio仕様、コントロールプレーンがベンダ仕様であるデバイスを指す。 ゲスト上のvirtio-netデバイスから見ると、データプレーンがホストをバイパスして物理NICに直接アクセスし、 コントロールプレーンがホストのvDPAフレームワーク(とベンダ依存のドライバ)を経由する、と捉えることができる。 かつてvDPAカーネルフレームワークは、mdevベースで作られた。 mdevはVFIOパススルー時にコントロールプレーンを仲介するもので、 ベンダ依存のコマンドとエミュレートされたPCIデバイス間の変換を担当する。 ただ以下の理由でmdevベースのアプローチを辞め、VFIOから独立した新しいサブシステムとしてvDPAカーネルフレームワークを設計した。 VFIOとmdevは、vDPAと比べるとレイヤの低い部分で抽象化を行っているため、レイヤの高いAPIをVFIOに取り入れるのは自然ではない 世の中のNICがすべてVFIO IOMMUの設計に適しているわけではない vDPAカーネルフレームワークはvhostキャラクタデバイスを提供するので、 QEMUのようなユーザスペースのドライバからvhostデバイスとして扱える。 独立したサブシステムなので、新たなハードウェアの機能に追従できる。 例えば、ライブマイグレーションのために、vhost API経由でデバイスの状態を保存・復元することができる。 また、SVA(Shared Virtual Address)やPASID(Process Address Space ID)もサポートする。 QEMUのようなユーザスペースでホスト・ゲストを仲介するレイヤが必要になるが、 SR-IOVによって単純にパススルーする構成と比べると、攻撃の対象領域を小さく保てる。 Intel Scalable IOVやSub Function(SF)とも相性が良い。 vDPA DPDK フレームワーク vDPAのもう一つのフレームワークとして、ホストのDPDKを使った vDPA DPDK framework も存在する。 QEMUから見ると、単純に vhost-user バックエンドと接続するだけで良い。 ほとんどのメジャーなNICに対して、このvDPA DPDK driverが存在している。 ただvDPA DPDK フレームワークには以下の制約があった。 vhost-userはユーザスペースのAPIなので、ホストのカーネルサブシステムを操作することができない。例えば、eBPFのような機能と協調して動かすことができない。 DPDKはデータプレーンに注力しているため、ハードウェアの操作するためのツールを提供していない。 これらの制約を取り除くために、vDPAカーネルフレームワークが必要だった。 How deep does the vDPA rabbit hole go?, redhat.com にさらに突っ込んだ内容が書かれている。 既存のアプローチとの比較 vDPAと既存のアプローチとの比較をしてみる。 項目 vhost-net vhost-user virtio full HW offload vDPA パフォーマンス 低 中 高 高 NIC側のデータプレーンサポート No No Yes Yes NIC側のコントロールプレーンサポート No No Yes No ライブマイグレーション Yes Yes No Yes 成熟度 高 高 高 中? 出典:Achieving network wirespeed in an open standard manner: introducing vDPA, redhat....

October 27, 2020

VMware徹底入門 読書メモ

雑多なメモ vSpehre環境のインターフェイス GUI:vSphere Client、vSphere Web Client CLI:vSphere CLI、VMware vSphere Power CLI DCUI(Direct Console User Interface):ESXiのコンソール 仮想ディスクは .vmdk という単一のファイルとして作成され、データストアに格納される。 VLAN VST 構成の場合、ポートグループ = VLAN の構成が一般的で推奨されている。 vSphere DRSは、ESXi間の負荷を平準化する目的で、vMotionを自動的に実行すること。 vMotionはいわゆるライブマイグレーションのこと。 Cross vSwitch vMotion:仮想スイッチが異なっているホスト間 Cross vCenter vMotion:vCenterが異なっているホスト間 Long Distance vMotion:最大150msのネットワーク遅延を許容 テンプレートやクローンによって仮想マシンを複製する際、ホスト名・IPアドレス・ライセンス情報などユニークな設定項目については「カスタマイズ仕様」として扱える vSphere 5.5移行ではESXiホスト上でパケットキャプチャやトレースを行うためのCLI pktcap-uw が追加された。物理NIC、仮想ポート、仮想スイッチ、仮想分散スイッチのパケットをキャプチャできる 仮想マシンを構成するファイル VMXファイル:詳細な構成情報・ハードウェア情報 VSWPファイル:仮想マシンのスワップアウト先 VMDKファイル(-flat.VMDKファイル):仮想ディスクの内容が保存される VMSDファイル:スナップショットとメタデータ vCenter配下のESXiホストをロックダウンモードに設定すると、直接ログインできなくなる ESXiホストはデータセンター内に配置される VMDKの格納 VMFS:複数のESXiホストからアクセス可能なクラスタファイルシステムでFC、iSCSI上に作成される Lazy Zeroed(シックプロビジョニング):VMDK作成時に領域を確保。ゼロ初期化なし。 Eager Zeroed(シックプロビジョニング):VMDK作成時に領域を確保。ゼロ初期化あり。 シンプロビジョニング:必要時に領域を拡張する。 NFS シンプロビジョニング:NFSサーバ側で管理するため。 VLANの扱い EST(External Switch Tagging) ESXiホストの物理NIC をポートVLAN(アクセスポート)として扱う 標準仮想スイッチ(VLAN IDの指定):0または空白 分散仮想スイッチ(VLANタイプの指定):なし VST(Virtual Switch Tagging) 物理スイッチでタグVLANを設定して、仮想スイッチのポートグループにVLANを割り振る 標準仮想スイッチ:1~4094 分散仮想スイッチ:VLANを選択してIDを入力 VGT(Virtual Guest Tagging) 物理スイッチでタグVLANを設定する、VLANタグがついたまま仮想マシンにフレームを転送する 標準仮想スイッチ:4095 または ALL 分散仮想スイッチ:VLANトランクを選択して、範囲を入力 参考 VMware徹底入門 第4版

October 15, 2020

XDPメモ(アーキテクチャ、性能、ユースケース)

はじめに The eXpress data path: fast programmable packet processing in the operating system kernel 1 を読んだ。 この文章はほとんどこの論文をもとに書いたが、一部ニュース記事を引用している。 eBPF/XDPが流行っているということは、BCC、bpftrace、Facebook Katran、Cloudflare Gatebot などeBPF/XDPを使うプロジェクトのGithub Star数から感じ取れる。 eBPF/XDPには、特殊なハードウェア・ソフトウェアに依存せず、 カーネルの仕掛けとして高速パケット処理を実現できるという強力なメリットがある。 一方であまり弱点を主張するような記事は見当たらないので、実際のところどうなのか感触を知りたい。 XDPを使うとNICデバイスドライバのコンテキストで、eBPF Verifilerの制約はありつつも、 比較的自由にパケット処理を実現できる。 また、成熟したLinuxのネットワークスタックと共存しつつ、1コアで24Mppsという高速なパケット処理を実現できる。 XDPプログラムは、eBPFの制約のもとC言語で記述することができ、clangでELFバイナリにコンパイルする。 XDPの競合としてカーネルバイパスなDPDKがある。両者の特徴は以下のとおり。 DPDK: カーネルバイパスによってコンテキストスイッチを避け高速化を図る コアを専有する(特定のコアでCPU 100%に張り付かせてポーリング) スループットとレイテンシどちらの観点で見てもDPDKのほうが優れている ネットワークスタックを再実装する必要がある XDP: 専用コアが不要(電力面などで有利) 容易にロード・アンロードできる 名前空間などカーネルの機能に強く依存するコンテナ環境の普及で、XDPの重要度が増しているように感じる やはりカーネルネットワークスタックと共存できるというメリットが強い アーキテクチャ パケット着信のたびに、デバイスドライバのフックポイントでXDPプログラムが実行される。 このフックポイントは、デバイスドライバの処理の中でも初期に位置する(sk_buff の割り当て前)。 XDPプログラムは、ヘッダのパース、eBPFマップの読み書き、ヘルパ関数(FIBのルックアップなど)の呼び出しを経て、 最終的にパケットをどこに送り出すか決定する。 送り先については、XDPプログラムの終了コードで制御することができ、 ドロップさせる、同インターフェイスに送り返す、他インターフェイスに転送する、AF_XDPとしてユーザプログラムに送る、 通常のネットワークスタックに送る、から選択する。 2つ以上のXDPプログラムを同インターフェイスに紐付けたい場合には tail call として処理を引き渡すことができる。 外部のシステムとデータのやり取りをするために、eBPF Mapが用意されている。 eBPF Verifilerが厳しくチェックしているので、必ずeBPF Mapを使うことになりそうだ。 出典:The eXpress data path: fast programmable packet processing in the operating system kernel...

September 17, 2020

ER-X を Prometheus で監視する

Ubiquiti Networks社のルータ EdgeRouter X (ER-X)を数年前に購入したものの放置したままだったので、 今回 L2 スイッチとして使ってみた。 ER-X上ではDebianベースのOSで動いているため、Prometheus用に Node exporter のような監視プログラムを使うことができる。 Prometheus自体はRaspberry Pi上で動かした。 ElastiFlowも動かしたかったが、Raspberry Piのスペックでは厳しそうだった。 Prometheus と Grafana の導入 Raspberry PiにPrometheusとGrafnaをインストールする。 Prometheusはメトリクスを収集するために、GrafanaはPrometheusで収集したメトリクスをウェブUIから確認するために使う。 wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list apt install prometheus grafana -y sudo systemctl start prometheus sudo systemctl start grafana-server Node exporter の導入 ER-XにNode exporterをインストールする。 CPU、メモリ、ディスク、ネットワークに関連するメトリクスを自動で収集してくれる。 curl -L https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-mipsle.tar.gz -o node_exporter.tar.gz tar xf ./node_exporter.tar.gz sudo mv ....

August 10, 2020

TP-Link Archer T3U AC1300をLinuxから使う

USB接続の無線LAN子機 TP-Link Archer T3U AC1300 を、Thinkpad X1 Carbon 2015(Fedora release 29 (Twenty Nine)、linux 5.3.6-100.fc29.x86_64)から使えるようにしたので手順を残しておく。 # 公式HPではドライバが配布されていなかったので rtl88x2bu を使った git clone https://github.com/cilynx/rtl88x2bu cd rtl88x2bu/ git rev-parse HEAD # 962cd6b1660d3dae996f0bde545f641372c28e12 VER=$(sed -n 's/\PACKAGE_VERSION="\(.*\)"/\1/p' dkms.conf) sudo rsync -rvhP ./ /usr/src/rtl88x2bu-${VER} # /usr/src/<module_name>_<module_version> に移動させて dkms で管理する sudo dkms add -m rtl88x2bu -v ${VER} sudo dkms build -m rtl88x2bu -v ${VER} sudo dkms install -m rtl88x2bu -v ${VER} sudo dkms status sudo modprobe 88x2bu 2種類の子機(オンボードの子機とTP-Linkの子機)を同一のネットワークにつなぐと、metric によって優先順位が決まる。 metric の値を見ると、オンボードの子機側を優先していた(値が小さい)ので入れ替えた。...

November 9, 2019

TCP技術入門 読書メモ

TCP技術入門を読んだので、 気になったところを雑多な感じだがメモしておく。まず前半部分。 ネットワークまわりの話は聞いたことはあるが、使わずに忘れてしまっていることが多い。 1章 TCP入門 伝送効率 Ethernetフレーム 1500 バイト、TCPヘッダが 60 バイト、IPヘッダが20バイトとする アプリケーションが使えるのは 1420 バイト Ethernetヘッダ 14 バイト、FCS(Frame Check Sequence)4バイトを考慮すると、伝送効率は$1420/(1500+18) \times 100=93.5 %$ UDP 実際にUDPがやっていることは、転送先へデータを送ることと、チェックサムの確認だけ TCPはユニキャストだが、UDPはユニキャストに加えて、マルチキャストとブロードキャストにも対応 シーケンス番号とタイムスタンプを追加したRTP(Real-time Transport Protocol)や、それに加えて再送機能も追加したRUDP(Reliable user Datagram Protocol)もある QUIC はUDPベースで、それを使ったHTTP/3(HTTP-over-QUIC)。コネクション確立とTLS確立を同時に実施。 TCP ACKのシーケンス番号は、次に受信したい番号。当該セグメントが届くまで、同じシーケンス番号を返送し続ける。 フロー制御:受信側のバッファ溢れを防ぐために、送信データ量を調整すること。TCPでは一度に送信可能なサイズをウィンドウと呼ぶ。特に、送信側がもつパラメータを swnd (send window)と表記する。対して、受信側はrwnd(recieve wndoe)。 TCP輻輳制御 Loss-based:データの消失から輻輳を判断 Delay-based:RTTから輻輳を判断 特定の用途向けプロトコル RUDP(Reliable User Datagram Protocol):UDPベースで、シーケンス番号、ACK、再送、フロー制御を加えたもの DCCP(Datagram Congestion Control Protocol):UDPにおける輻輳緩和が目的 2章 TCP/IPの変遷 ARPNETなどではネットワークが信頼性を担保していたが、TCP/IPは各ノードがその役割を担う Nagleアルゴリズム:TCP/IPの送出パケット数削減の方法。輻輳制御アルゴリズムのはしり Windows95(OSR2以降)にTCP/IPが搭載されたことが普及のきっかけになった IEEE 802.11ではMACレイヤーでCSMA/CAを採用 3章 TCPとデータ転送 MTUは、イーサネットは1500バイト、PPPoEでは1492バイト、ATMは9180バイト。ただ最近は任意に設定できる MSS(Maximum Segment Size):TCPが区切る最大パケット長さ MTU(1500バイト)= IPヘッダ(20バイト)+ TCPヘッダ(20~60バイト)+ アプリケーションデータ(MSS以下) MSSは、TCPのペイロードのみ MTUは、TCPのペイロードからTCPヘッダやIPヘッダまで。Ethernetヘッダは含まない ACK(Acknoledgement Number):確認応答番号。次に送ってほしいシーケンス番号 コントロールフラグ RST(Reset the connection):コネクションを強制切断。使われていないポート番号に送るなど、異常があれば有効になる CWR(Congestion Window Reduced):輻輳ウィンドウの減少を通知する。ECNとセットで使われる ECE(ECN echo):輻輳が発生したら通知 ウィンドウ制御:一度に送信可能なウィンドウサイズ $swnd$ を調整 $swnd = min(rwnd, cwnd)$ フロー制御:受信側から送信側に送信量を通知して、調整する。受信側は、送信側へ受信可能なバッファ量$rnwd$を通知 輻輳制御:輻輳ウィンドウ $cwnd$ を調整 スロースタート 通信開始時点で、ACKを受け取るたびに $cwnd$ を1セグメントずつ増やしていく $cwnd = cwnd + mss$ 指数的に $cwnd$ が拡大 輻輳回避 スロースタートを行うと、再び再送が起きやすい 再送が起きた時の $cwnd$ の半分 $cwnd/2$を閾値として、それを越えた時は更新を緩やかにする $cwnd = cwnd + mss/cwnd$ RTTごとに線形に増える 高速リカバリー 輻輳のたびに、スロースタート→輻輳回避という挙動をするのは効率が悪い 重複ACKを契機とする Recoで採用 セグメントの消失 再送タイマーがタイムアウトした場合 重複ACKが一定数届いた場合

September 25, 2019

BGP in the Data Center 読書メモ

BGP in the Data Centerの前半部分を読んだので、気になったところをメモしておく。CLOSネットワークをどのように設計するか、BGPをどのように運用するかについて、実践的な内容が書かれていた。普段触っていない領域なので、勘違いもあると思う。 1. Introduction to Data Center Networks ローカルネットワーク内のサーバ間通信をEast-Westトラフィック、ローカルネットワークと外部のネットワークの間の通信をNorth-Southトラフィックと呼ぶ。 大量のケーブルを管理する必要があるので、巨大なネットワークの管理者は、それぞれ管理技術を持っている。Prescriptive Topology Manager(PTM)というOSSもある。 同一のスイッチで巨大なネットワークを構成しておくと、故障した場合でも、単純に取り替えるだけで復旧できる。日々の運用コストについて考えておくことが大事。 CLOSネットワークを外部と接続するために、Border PodあるいはBorder Leavesを配置する。データセンタ内で使われているルーティングプロトコルは外部とは分離しておく。もし、Border PodやBordor Leavesを配置できない場合には、すべてのSpinesを外部と接続させる(Spineの対称性を保つため)。 iBGPに比較し、eBGPは理解やデプロイが容易なので、eBGPを採用するのが良い。歴史的な観点から、eBGPのほうが完成度の高い実装が多い。 2. How BGP Has Been Adapted to the Data Center PublicなASNは使わないほうが良い。オペレータを混乱させてしまったり、万が一外部に漏れた時にBGPハイジャックになってしまったりといった危険性がある。 2バイトのASNを4バイトへ拡張すると、およそ95,000,000個のprivate ASNを利用できる。 単純にすべてのBGPスピーカにユニークなASNを割り当てると、Path Huntingに苦しむことになる。 あるPrefixへの到達性をもつノードがダウンしたときに、その情報が収束するまでに時間がかかってしまう。これは、BGPのベストパス選択の性質に起因する。 真に到達不可能なのか、それとも別の経路でもって到達できるのかの区別ができない。 密に接続したCLOSトポロジでは、顕著な問題となる。 Path Hunting問題への対応として、以下のASN割り当てモデルがある。ループを検出できるので、必要以上にメッセージを送らなくて済む。ただし、Route Summarizationができないことに注意する。 すべてのToRはユニークなASN LeafはPodごとにユニークなASN。Pod内では同一のASN Spineは共通のASN OSPFやIS-ISはBest path選択のメトリクスを1つだけ。一方、BGPではそれが8つある。 Wise Lip Lovers Apply oral medication Every Night. Wight, LOCAL PREFERENCE, Locally originated, ASPATH, ORIGIN, MED, eBGP over iBGP, NextHop IGP Cost これら8つが等しければ、Equal Costと考えられ、Multipath Selectionできる。 ASPATHの比較については、長さに加えて要素がすべて等しければ、Equal Costとみなされる。 例えば、同一のPrefixが異なるASから届いた時には、Multi Pathとはならない。 ただし、bestpath -as-path multipath-relaxの設定を行うと、ASPATH長のみで(内容には触れずに)比較するよう設定できる。 タイマ設定を変更することで、CLOSトポロジにおける収束を早くする必要がある。ふつうはプロバイダ向けを想定して、安定性を第一にデフォルトが設定されていることが多いので、適宜設定する。 Advertisement Interval:このInterval内に含まれるメッセージは統合されて、送り出される。eBGPの場合、デフォルト30秒だが、0秒に設定すれば良い。 Keepalive and hold Timers:ある周期でkeepaliveメッセージをピアと交換する。Hold timeの期間内に、keepaliveを受け取らなかった場合は、ノードダウンと判定される。ケーブル障害の検知のために、BFD(Bidirectional forwarding Detectiion)を導入している場合でも、BGPプロセス自体のエラー検出のために、これらのタイマを調整する必要がある。おすすめは、3秒ごとのKeepaliveと9秒間のhold timersである。 Connect Timer:ピアの接続が切れた時、再接続までの待ち時間。 3....

March 21, 2019