WSA研 : XDPを利用したエッジデバイスでのネットワーク制御

概要

自動車など移動を伴うエッジデバイス上での通信では、これまで各アプリケーションごとに不安定なネットワークに対応するための実装を行っていた。例を挙げると、MQTTなどClient(エッジデバイス)とServer(クラウド)の間にBroker層を利用することで不安定なネットワーク下でも通信を行えるようにしている。このようなBroker層を利用する場合、Client層とServer層に独自のプロトコルに対応する処理を追加する必要がある。

今回は、クラウドで利用されるServiceMeshアーキテクチャを元に、ClientとServer側で独自の実装を追加せずネットワークの制御を行った方法と、その際に発生した課題を挙げ、XDP(eXpress Data Path)を利用した解決策について考察する。

背景

ServiceMeshアーキテクチャでどのようにネットワークを制御しているか

分離したい共通機能をサイドカーコンテナとして実行する。共通機能については以下のようなものなどがある。
  • リトライ/タイムアウト処理
  • データ暗号化
  • データ監視/モニタリング

本来は図のProxyにあたるDataPlane同士が相互に通信する様が網目のようなためServiceMeshと呼ばれているが、今回の発表では触れない。

エッジで実現しようとした機能


ServiceMeshアーキテクチャではサイドカーで実行しているProxyをベアメタルサーバ上でも動かす。ローカルマシンに透過プロキシが存在し、すべてのリクエストがプロキシを経由する。
プロキシには以下の機能が含まれる。
  • HTTPリクエストの情報に応じて、ネットワークインターフェースを選択できる
  • 高価なモバイル回線での通信を減らし、ネットワークコストを抑える
  • 通信できるネットワークがない場合、一定時間バッファリングを行い、回復次第リクエストを復活させる
  • 一定時間ネットワークが回復しない場合、リクエストデータを保存し、非同期でリクエストを行う
この際、目的を達成するための補助プロセスを走らせている。補助プロセスには以下の機能が含まれる。
  • 起動スクリプトとして、iptablesの編集を行いプロキシ以外のコンポーネントからのリクエストをすべてプロキシに送る設定を行う
  • 常駐プログラムとして、DNS Resolverを起動する
  • ネットワークがない場合のみ、ダミーとなるIPを返却する (カーネルで実行される名前解決でのリクエスト失敗を回避する)

実際の動作イメージ

指定したネットワークでのリクエストができない場合、リクエストをバッファリングする
ネットワークが一定時間回復しない場合、非同期でリクエストを送る

発生した課題

プロキシ、および補助プロセスのいずれかが停止した際に全リクエストが失敗するため、パケットの動作を柔軟に制御したい。しかし、iptablesはプログラム言語ではなく、ルールを定義する仕組みで設定するため、動的な制御が難しい。

課題に対する解決策


すでにKubernetes環境でCiliumというツールが、iptablesを利用せずXDPを利用して動的にパケット制御をおこなっていた。そのため、エッジデバイスであってもXDPを用いて動的にパケット制御を行うことで、柔軟に各コンポーネントへのリクエスト制御を行えると考えた。

iptablesから乗り換えるために必要な機能として、以下のものがある。
  • ネットワークがない状況での名前解決は、ローカルマシン上で行う
  • すべてのパケットリクエストを、ローカルマシンで動作する透過プロキシのポートへ集約する
  • 透過プロキシが動作するポートからのリクエストのみ、外部へのリクエストを許可する

以上の機能を実装し、XDPを利用する利点や課題を結論にて記載する。