APRESIA Technical Blog

SONiCとWedge100BF-32Xを使ったインバンドネットワークテレメトリ(INT)によるマイクロバースト検知

インバンドネットワークテレメトリ(INT)とは?

ネットワーク機器を流れる通信帯域の監視には、SNMPによるカウンタ収集やストリーミングテレメトリなど、いくつかの方法があります。ただ、短時間に発生するマイクロバーストを検出するためには、リアルタイムに通信帯域を監視できる仕組みが必要になります。その目的のために、インバンドネットワークテレメトリ(以降、INTと記載)が開発されました。INTは、文字通り、流れている通信経路(インバンド)にて、テレメトリ情報を取得する仕組みです。今回はp4.org(データプレーンのプログラミング言語を制定しているコミュニティ)がスペックを制定したINTを使った実験の結果について共有いたします。 今回の実験環境は以下です。
  • スイッチ:Wedge100BF-32X (P4スイッチ)
  • NOS: Edgecore商用ディストリビューションのSONiC※ (以降、Edgecore SONiCと記載)
※正式名称は”Enterprise SONiC Distribution by Edgecore Networks Inc.”

物理環境と使用したSONiC

今回の実験では、以下のようにWedge100BF-32Xを使って、Leafを2台、Spineを2台のファブリックネットワークを用意しました。

ケーブルは以下のように接続しました。INTの情報を収集し可視化するためのサーバをLeaf01に繋いでいます。INTの情報はインバンドを流れるため、INT情報可視化サーバと各Leaf/SpineスイッチはIP reachabilityが必要です。

Edgecore SONiCは202111ブランチがベースのバージョンを使いました。なお、Edgecore SONiCについては、こちらの「ダウンロードはこちら」から無償でダウンロード可能です。このEdgecore SONiCは、以下のINT XD (eXport Data) モードをサポートしています。このモードでは、各スイッチはパケットを中継する際に、対象スイッチが受信してから送信するまでに発生した遅延時間やキュー(パケットを一時的に保存するスイッチ内部のメモリ)の使用量などのテレメトリ情報を、パケットのヘッダと一緒にモニタリングシステムに転送します。このテレメトリ情報をモニタリングシステムにて可視化・分析することで、ネットワーク内の輻輳箇所や輻輳の原因となったパケットを特定し、輻輳を回避するための情報を得ることができます。

抜粋: https://p4.org/p4-spec/docs/telemetry_report_v2_0.pdf

Leaf/SpineのBGP設定

インバンドネットワークテレメトリを設定する前に、BGPを設定してファブリックネットワークを構築します。BGPの設定の仕方は、FRRを直接設定する方法もありますが、ここではSONiCのconfig_db.jsonに設定を書く例を示します。Leaf1の場合は、SONiCの/etc/sonic/config_db.jsonファイルに、以下の定義を追加しました。
    "DEVICE_METADATA": {
        "localhost": {
            "bgp_asn": "65110",
            "buffer_model": "traditional",
            "default_bgp_status": "up",
            "default_pfcwd_status": "disable",
            "hostname": "Leaf01",
            "hwsku": "montara",
            "mac": "XX:XX:XX:XX:XX:XX",
            "platform": "x86_64-accton_wedge100bf_32x-r0",
            "synchronous_mode": "enable",
            "type": "LeafRouter"
        }
    },
    "LOOPBACK_INTERFACE": {
        "Loopback0": {},
        "Loopback0|10.1.1.3/32": {}
    },
    "INTERFACE": {
        "Ethernet0": {},
        "Ethernet0|10.0.0.1/31": {},
        "Ethernet4": {},
        "Ethernet4|10.0.0.5/31": {},
        "Ethernet8": {},
        "Ethernet12": {}
    },
    "BGP_NEIGHBOR": {
        "10.0.0.0": {
            "asn": "65100",
            "holdtime": "180",
            "keepalive": "60",
            "local_addr": "10.0.0.1",
            "name": "Spine01",
            "nhopself": "0",
            "rrclient": "0"
        },
        "10.0.0.4": {
            "asn": "65100",
            "holdtime": "180",
            "keepalive": "60",
            "local_addr": "10.0.0.5",
            "name": "Spine02",
            "nhopself": "0",
            "rrclient": "0"
        }
    },
上記のconig_db.jsonでは、自分自身のASNを65110にして、ASN 65100を持つ二台のSpineとBGPのピアを張ります。LeafとSpineをそれぞれ設定し、Leaf配下のトラフィックジェネレータ間で通信を流せる状態を作っておきます。

インバンドネットワークテレメトリの設定

BGPによるLeaf/Spineのファブリックネットワークが構築の次はINTの設定を行います。json形式になりますが、Leaf01のINTの設定は以下を使いました。これをconfig_db.jsonに追記するか、このjsonをファイルに保存して、"sudo config load"コマンドでloadすれば、INTが動作します。なお、以下設定内のDTELは、Dataplane TELemetryの略で、INTと同じ意味です。
{
    "DTEL": {
	"POSTCARD": {
	    "POSTCARD": "TRUE"
	},
	"DROP_REPORT": {
	    "DROP_REPORT": "TRUE"
	},
	"QUEUE_REPORT": {
	    "QUEUE_REPORT": "TRUE"
	},
	"SWITCH_ID": {
	    "SWITCH_ID": "101"
	},
	"FLOW_STATE_CLEAR_CYCLE": {
	    "FLOW_STATE_CLEAR_CYCLE": "2"
	},
	"LATENCY_SENSITIVITY": {
	    "LATENCY_SENSITIVITY": "32"
	}
    },
    "DTEL_INT_SESSION": {
        "INT_SESSION1": {
            "COLLECT_SWITCH_ID": "TRUE",
            "COLLECT_INGRESS_TIMESTAMP": "TRUE",
            "COLLECT_EGRESS_TIMESTAMP": "TRUE",
            "COLLECT_SWITCH_PORTS": "TRUE",
            "COLLECT_QUEUE_INFO": "TRUE",
            "MAX_HOP_COUNT": "8"
        }
    },
    "DTEL_REPORT_SESSION": {
        "REPORT_SESSION1": {
            "SRC_IP": "10.249.39.53",
            "DST_IP_LIST": "10.20.1.11",
            "TRUNCATE_SIZE": "256",
            "UDP_DEST_PORT": "33333",
	    "VRF": "default"
        }
    },
    "DTEL_QUEUE_REPORT": {
        "Ethernet0|0": {
            "REPORT_TAIL_DROP": "FALSE",
            "QUEUE_DEPTH_THRESHOLD": "18",
            "QUEUE_LATENCY_THRESHOLD": "100000",
            "THRESHOLD_BREACH_QUOTA": "1"
        },
        "Ethernet4|0": {
            "REPORT_TAIL_DROP": "FALSE",
            "QUEUE_DEPTH_THRESHOLD": "18",
            "QUEUE_LATENCY_THRESHOLD": "100000",
            "THRESHOLD_BREACH_QUOTA": "1"
        },
        "Ethernet8|0": {
            "REPORT_TAIL_DROP": "FALSE",
            "QUEUE_DEPTH_THRESHOLD": "18",
            "QUEUE_LATENCY_THRESHOLD": "100000",
            "THRESHOLD_BREACH_QUOTA": "1"
        }
    },
    "ACL_TABLE": {
        "DTEL": {
            "policy_desc": "DTEL",
            "ports": [
                "Ethernet8",
                "Ethernet4",
                "Ethernet12",
                "Ethernet0"
            ],
            "stage": "ingress",
            "type": "L3"
        }
	
    },
    "ACL_RULE": {
	"DTEL|RULE1": {
            "FLOW_OP": "POSTCARD",
	    "DROP_REPORT_ENABLE": "TRUE",
            "TAIL_DROP_REPORT_ENABLE": "FALSE",
            "REPORT_ALL_PACKETS": "FALSE",
            "PRIORITY": "20",
            "DST_IP": "10.10.102.0/24",
            "SRC_IP": "10.10.101.0/24",
            "IP_TYPE": "IP",
	    "IP_PROTOCOL": "17"
        }
    }
}
考え方としては、ACLを使って、INT対象となるパケットを限定し、ACLのアクションとしてINTを実行、という流れになります。上記の例では、ACL_RULEの"DTEL|RULE1"にて、監視対象のパケットのIPアドレスを限定しています。また、ACLルール内の設定について以下に補足します。
"FLOW_OP": "POSTCARD" INTのモードをXD (eXport Data)に指定
"DROP_REPORT_ENABLE": "TRUE" パケットの破棄が発生したときのINTレポートを有効
"REPORT_ALL_PACKETS": "FALSE" 全パケットに対してINTレポートを送信しない設定(サンプリングとイベント発生時に限定)
その他、DTEL関係のオプションを以下に補足します。
"QUEUE_REPORT": {
    "QUEUE_REPORT": "TRUE"
}
キューの使用量の監視と、閾値を超えたときのINTレポートを有効
"SWITCH_ID": {
    "SWITCH_ID": "101"
},
各スイッチのユニークIDを指定
"REPORT_SESSION1": {
    "SRC_IP": "10.249.39.53",
    "DST_IP_LIST": "10.20.1.11",
    "TRUNCATE_SIZE": "256",
    "UDP_DEST_PORT": "33333",
    "VRF": "default"
}
  • DST_IP_LIST: INT可視化サーバ(INTレポートの送信先)
  • UDP_DEST_PORT: INT可視化サーバにてリスニングするL4のDst Port
"Ethernet0|0": {
    "REPORT_TAIL_DROP": "FALSE",
    "QUEUE_DEPTH_THRESHOLD": "18",
    "QUEUE_LATENCY_THRESHOLD": "100000",
    "THRESHOLD_BREACH_QUOTA": "1"
},
キューの使用率の監視閾値のパラメータ(監視したいバーストトラフィックの帯域や時間によって、パラメータの調整が必要)

インバンドネットワークテレメトリの動作確認

Edgecore SONiCのINTのレポートはこちらのスペックに従っています。今回の試験では、INT情報可視化サーバにて、INTレポートを解析して、時系列データベースのInfluxDBにINT情報を登録し、それをGrafanaにて可視化しました。以下は、1Gbpsの通信負荷をかけたときの可視化の状況です。 上記の右上のグラフは、各スイッチの遅延を可視化した結果です。また、右下のグラフは各スイッチのキューの使用量を示しています(これらの値は相対値に変換していますので、秒数などの具体的な値を示しているわけではありませんので、ご注意ください)。その状態から、100Gbpsのバーストトラフィックを200μ秒間、印可します。この場合、Spineの物理帯域は受信側は100G、送信側は40Gにしていますので、Spineスイッチにて短時間の輻輳が発生します。以下はこのバーストトラフィックを3回かけた結果です。 上記のグラフのように、輻輳が発生することで、右上の遅延時間の増加と、右下のキューの使用量の増加が見えています。また、この際は、キューの使用量の閾値超えを検知してキューレポートがSpineスイッチから送信されています。なお、バーストトラフィックは短時間のため、Spine装置ではパケットの破棄は発生していません。つまり、パケットの破棄が発生する前の段階で、何らかの輻輳の兆候をINTにて検知できていると言えます。

まとめ

今回は、Edgecore SONiCとWedge100BF-32Xを使ったINTの試験環境の構築方法と、その試験結果を共有しました。パケットロスが発生しなくても、マイクロバースト発生時に遅延の増加やキューの使用量の増加をINTによってリアルタイムに検知できることが分かりました。INTを実現するためにはデータプレーンのハードウェア中継の振る舞いを拡張する必要がありましたが、データプレーンのプログラミングが可能なP4言語が登場したおかげで、このような機能開発が可能になりました。P4であれば、INT以外の拡張も可能ですので、ご興味ありましたら当社までお問合せください。