APRESIA Technical Blog

「SRv6でサービスチェイニングをやってみた」の全configを載せてみた(後半)

最初に

前半に引き続き、以下のJANOG43の「SRv6でサービスチェイニングをやってみた」のデモ環境をご紹介いたします。前半では、SRv6のSIDのprefixをBGPによってIP CLOSファブリック内に配布できることを確認しました。後半では複数のSIDを並べたサービスチェインを用意し、SRv6のサービスチェイニングによってトラフィック中継を制御していきたいと思います。

前提とするSRv6の機能

SRv6のHeader Format

SRv6はSegment ID (SID) をIPv6のアドレス体系で表現します。このSIDをリストとして、以下の図の通りSRv6 Header(IPv6 optional header)に積んで、パケットが中継されることになります。(出典: https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-16)

図1 SRv6 Header format

このSRv6 Headerを用いて中継を制御するために、SRv6ではいくつかの中継用のFunctionが定義されており、それらを組み合わせてend to endの通信の制御を実現します。例として、このデモではT.Encaps、End、End.DX6の3つのFunctionを使って、SRv6のサービスチェインを実現します。その時のパケットの中継は下図の通りとなります。
  • T.Encaps
    SRv6 Headerを付与
  • End
    SRv6 HeaderのSID listに従い、Dst IPv6 アドレスを変更して中継
  • End.DX6
    SRv6 Headerを削除

図2 SRv6のFunctionと中継例

SRv6によるサービスチェイニングの事前準備

サービスチェインの設計

試験構成は、下図のLeaf/SpineのIP CLOS Fabricになります。Leaf1がT.Encaps、Service1とService2がEnd、Leaf3とLeaf4がEnd.DX6になります。

図3 試験構成

まずは、サービスチェインの配置を検討していきます。今回は下図のdefaultに記載している、Host2がApp1にアクセスする通信をサービスチェイニングの対象とします。これに対して、図の通り、4つのlocalテーブルを用意し、それぞれのテーブルにてサービスチェイニングを定義していきます。

図4 サービスチェインの論理イメージ

local1、local2は、途中の経路に、Service1を経由させる、あるいはServce1、Service2の両方を経由させるサービスチェインになっています。さらに、local 3とlocal4は、Service1、Service2の両方を経由しながら、最終的に到達する先をApp2、App3のように強制的に変更するサービスチェインになっています。それぞれ4つのサービスチェインによる通信の経路(上り方向)は以下の図の通りとなります。

図5 サービスチェイニングによるトラフィックの物理経路

前編でも説明しましたとおり、各End、End.DX6は以下のようにSIDを割り当てます。                                                                              
装置SRv6 functionSID
Service1Endfd00:ffff:0:2:1::1:1
Service2Endfd00:ffff:0:2:2::1:1
Leaf3End.DX6fd00:ffff:0:3::2:1
Leaf4End.DX6fd00:ffff:0:4::2:1
Leaf4End.DX6fd00:ffff:0:4::2:2

サービスチェインを実行する前段階の設定 (End, End.DX6)

上記にて設計したサービスチェインを実際に設定していきます。まずは、End、End.DX6を配置します。SID (IPv6アドレス)に対して、対応するFunctionであるEnd、End.DX6のfunctionを指定するコマンドを設定します。                                                                              
コマンドを実行する装置SRv6 function実行コマンド
Service1Endsudo ip -6 route add fd00:ffff:0:2:1::1:1 encap seg6local action End dev ens4
Service2Endsudo ip -6 route add fd00:ffff:0:2:2::1:1 encap seg6local action End dev ens4
Leaf3End.DX6sudo ip -6 route add fd00:ffff:0:3::2:1 encap seg6local action End.DX6 nh6 :: dev ens6
Leaf4End.DX6sudo ip -6 route add fd00:ffff:0:4::2:1 encap seg6local action End.DX6 nh6 fd00:0:0:4:1::11 dev ens6
※ fd00:0:0:4:1::11 == App2
Leaf4End.DX6sudo ip -6 route add fd00:ffff:0:4::2:2 encap seg6local action End.DX6 nh6 fd00:0:0:4:2::11 dev ens6
※ fd00:0:0:4:2::11 == App3

これらのコマンドのaddの後のIPv6アドレスがSIDとなります。つまり、対象の装置にDst IPv6アドレスが設定されたSIDと同一だった場合に、指定されたSRv6 functionが実行されます。また、End.DX6は、SRv6を紐解く際に、次に転送する先(next hop)を明示的にnh6にて指定することが可能です。Leaf4のEnd.DX6はnh6にApp2、App3を指定しています。その上で、App2とApp3のloopbakcインタフェースに、App1のIPアドレスである'fd00:0:0:3::33/64'を設定しておきます。そうすることで、Leaf4のEnd.DX6でSRv6を紐解かれた通信はApp2、App3に到達し、それらがApp1と同じIPアドレスを持っていることからApp2、App3が最終目的地だと勘違いして、それらのアプリケーションにアクセスすることになります。

サービスチェインを実行する前段階の設定 (T.Encaps)

次に、Leaf1にT.Encapsを配置します。T.Encapsは、既に配置したEnd、End.DX6をSIDリストとして指定したlocal1からlocal4のテーブルを用意していきます。まず、/etc/iproute2/rt_tablesに以下の行を追加しておきます。(番号は必ずしも下で記載した値通りでなくても大丈夫です)
101 local1
102 local2
103 local3
104 local4
その上で、Leaf1にて、以下のようにテーブル名を指定して、T.encapsを配置していきます。
  • local1: Service1 -> App1
    sudo ip -6 route add fd00:0:0:3::/64 encap seg6 mode encap segs fd00:ffff:0:2:1::1:1,fd00:ffff:0:3::2:1 dev ens4 table local1 
  • local2: Service1 -> Service2 -> App1
    sudo ip -6 route add fd00:0:0:3::/64 encap seg6 mode encap segs fd00:ffff:0:2:1::1:1,fd00:ffff:0:2:2::1:1,fd00:ffff:0:3::2:1 dev ens4 table local2 
  • local3: Service1 -> Service2 -> App2
    sudo ip -6 route add fd00:0:0:3::/64 encap seg6 mode encap segs fd00:ffff:0:2:1::1:1,fd00:ffff:0:2:2::1:1,fd00:ffff:0:4::2:1 dev ens4 table local3 
  • local4: Service1 -> Service2 -> App3
    sudo ip -6 route add fd00:0:0:3::/64 encap seg6 mode encap segs fd00:ffff:0:2:1::1:1,fd00:ffff:0:2:2::1:1,fd00:ffff:0:4::2:2 dev ens4 table local4 
これで、SRv6のSIDを配置し、またSIDリスト(サービスチェイン)も準備ができました。この時点では、SRv6のFunctionを配置しただけであり、トラフィックには何も影響しません。ここから事前に準備したlocal1からlocal4までのテーブルにトラフィックを紐づけることでSRv6サービスチェイニングによるトラフィック制御を適用していきます。

SRv6によるサービスチェイニングの実行

サービスチェインのデモ画面

それでは具体的に、用意したSRv6のサービスチェインをトラフィックに適用していきます。本デモでは、その効果を図6のデモ画面にて説明します。

図6 デモ画面の各ウィンドウの説明

このデモ画面の右下の二つの画面には、Host1、Host2がApp1から受信している動画の画面が表示されています。また、それ以外の5つのウィンドウはService1、Service2、App1、App2、App3のそれぞれの装置の通信キャプチャの状況を示しています。スタート時点では、サービスチェイニングを適用前ですので、Host1もHost2もApp1が配信する同じ内容の動画を受信しており、App1のキャプチャのみが反応している状況です。(下図)

図7 サービスチェイニング適用前のデモ画面

まずはlocal1のサービスチェインをHost2 (IPv6アドレス = fd00:0:0:1:2::22) から送信されるトラフィックに適用するため、以下のコマンドをLeaf1にて実行いたします。
sudo ip -6 rule add from fd00:0:0:1:2::22 table local1 
すると、下図の通り、Service1のキャプチャ画面(左下)にトラフィックがキャプチャされ始めます。これは、つまりトラフィックがService1を経由していることを確認したことになります。

図8 local1適用後のデモ画面

続いてlocal2のサービスチェインをHost2から送信されるトラフィックに適用するため、以下のコマンドをLeaf1にて実行いたします。
sudo ip -6 rule add from fd00:0:0:1:2::22 table local2 
すると、下図の通り、Service1とService2のキャプチャ画面(左下の二つ)にトラフィックがキャプチャされ始めます。これは、つまりトラフィックがService1とService2を経由していることを確認したことになります。

図9 local2適用後のデモ画面

続いてlocal3のサービスチェインをHost2から送信されるトラフィックに適用するため、以下のコマンドをLeaf1にて実行いたします。
sudo ip -6 rule add from fd00:0:0:1:2::22 table local3 
すると、下図の通り、App2のキャプチャ画面(上部中央)にトラフィックがキャプチャされ始め、同時にHost2にて視聴している動画の内容(右下)が切り替わります。これはHost2からの通信がApp2に到達し、そのApp2がHost2に動画を配信し始めたことを示しています。

図10 local3適用後のデモ画面

最後に、local4のサービスチェインをHost2から送信されるトラフィックに適用するため、以下のコマンドをLeaf1にて実行いたします。
sudo ip -6 rule add from fd00:0:0:1:2::22 table local4 
すると、下図の通り、App3のキャプチャ画面(上部右)にトラフィックがキャプチャされ始め、同時にHost2にて視聴している動画の内容(右下)が切り替わります。これはHost2からの通信がApp3に到達し、そのApp3がHost2に動画を配信し始めたことを示しています。

図11 local4適用後のデモ画面

上記の通り、SRv6によってサービスチェイニングが実現できることを確認することができました。

最後に

以上のデモから、SRv6のサービスチェイニングによって、途中の通信経路を制御できること、加えて、アクセス先のアプリケーションも切り替えることができることが分かりました。また、サービスチェインの適用はLeaf1にて、予め用意したサービスチェインにトラフィックを紐づけるだけでよく、その際にルーティングの設定およびホスト側の設定について何の変更も必要ないことが分かりました。
特に今回のデモのようにSRv6によって、ホスト側に手を入れることなくアクセス先のアプリケーションを制御することで以下のユースケース等が考えられます。
  • End to endのアプリケーションのロードバランス
  • アプリケーションをメンテナンスする際の一時的なトラフィックの避難
  • アプリケーションに障害発生した際の代替サーバへのトラフィックの避難
  • 動的なエッジコンピューティングの制御
今回のデモでは、SRv6のFunctionを全てLinuxを使って試験しました。ただし、商用サービスに適用するためには、より高スループット・低中継遅延を求められる可能性があります。そのために、今回のデモと同等以上の機能をP4にてプログラム可能なハードウェアデバイス (Barefoot社のTofinoチップを搭載したWedge BFシリーズなど)にて実現していく取り組みを進めていくことを考えております。
なお、本デモでは以下の3つの動画(Creative Commons Attribution license)を使用させていただきました。