投稿日

【Ask SA!】SORACOM Gateの “Gate Peer” を冗長化して、障害に強いネットワークを作る方法

こんにちは。ソリューションアーキテクトの今井です。ニックネームはfactoryです。

このブログではSORACOM Gateというサービスを利用して、デバイスとクラウドの双方向通信が可能なネットワークを構成する際に、クラウド側のエンドポイントになる “Gate Peer” を冗長化して、障害に強いネットワークを作る方法を解説します。

具体的な方法を紹介しているため、TCP/IPネットワークの基礎知識を持っている前提での解説も含まれます。ネットワークエンジニアの方に、特にご覧いただきたい内容です。

このブログで解説している「クラウド」の範囲

ここでいうクラウドは、サーバーサイドのアプリケーションのことを指していますので、オンプレミスのデータセンターで動くアプリケーションでも同様に実現可能です。

SORACOM Gateとは?

SORACOM Gateをざっくり説明すると「クラウド上のサーバーやルーターを、IoT デバイスと同じLAN(L2 ネットワーク)に所属させる」ということができるサービスです。例えば172.16.0.0/16というネットワークにデバイスとサーバーの双方を所属させることができますので、NATやネットワークファイアウォールを介すことなく、相互の直接通信が可能です。

ネットワークレベルでの双方向通信を実現するSORACOMサービスには、オンデマンドリモートアクセス「SORACOM Napter」もあります。こちらはTCPのポート転送にて、インターネット側からIoTデバイスへセキュアにアクセスできるサービスです。こちらは「特定のIoTデバイスに、必要に応じて利用するリモートアクセス」として設計されており、例えばLTE通信している小型コンピューターへSSHによるリモート制御といった時に手軽に利用できます。また、時間が経過すると自動OFFとなるため、設定の解除し忘れといった心配事も減ります。

一方で、例えばブロードキャストのようなL2ネットワークを前提としたアプリケーションや、ソースIPアドレスの認識が必要な場合など、ネットワークレベルの要件を実現したい時に、「IoTデバイスとクラウドをネットワークのレベルで常時接続しておく」といった用途には、SORACOM Gateが向いています。

その他のSORACOMサービスとのすみわけ

IoTプラットフォームSORACOMは「IoTデバイスとクラウドをセキュアで簡単に接続する」という目的に対して、様々な「レイヤー」で手段をご提供しています。
例えばSORACOM Funkは、デバイスから送信されたデータを引数に、AWS Lambda等のFaaS(Function as a Service)を呼び出すことができます。すなわちSORACOM Funkは、ネットワークの事を考えることなく「アプリケーションレイヤーでクラウド連携できる」わけです。

同様のサービスにSORACOM BeamSORACOM Funnelがあり、これらをまとめて「アプリケーションレイヤのサービス」と称しています。共通の特徴は、デバイスからのデータ送信をアプリケーションレベルでSORACOMが一度受け取り、それを外部に転送したり保存したりするという使い方のサービスです。(Proxyのように動作すると思っていただいてもOKです)

一方で、クラウドアプリケーションとデバイスの間を直接的にIPネットワーク接続したいというケースも多々あると思います。ここで活躍するのがSORACOM Gateのカテゴライズされる「ネットワークレイヤのサービス」です。

SORACOMの提供している各レイヤーのサービスはSORACOMのサービスをご覧ください。

SORACOM Gateを利用するための構成

SORACOM Gateを使うためには、前提としてSORACOMの閉域網サービス(SORACOM Canal / SORACOM Door / SORACOM Direct)のいずれかのサービスを使って、SORACOMとクラウドを接続しておく必要があります。今回はSORACOM Canalを使ってAWSのVPCと以下のようなネットワーク構成を作っていると仮定しましょう。

SORACOM Canal 等の閉域網サービスはオンラインからお申込み可能で、即日利用可能なものばかりです(一部は申請制)。手順も公開しています。

“デバイスサブネット” が IoT デバイスが接続しているネットワーク、”カスタマーVPC” がAWS上でのVPCネットワークです。実はSORACOM Canalの利用だけでも、クラウド(カスタマーVPC)との通信は可能です。ただし、クラウド側のアプリケーションには後述する制約が発生するのですが、その背景は図内の「VPGのPrivate IPで通信」という説明書きです。

VPG(Virtual Private Gateway)とは、SORACOMプラットフォーム上の仮想ゲートウェイ装置、要するにルーターのようなものです。「VPGのPrivate IPで通信」というのは、デバイスサブネット(172.16.0.0/16)とカスタマーVPC(10.0.0.0/16)はVPGによるNATを介して通信することになる事を意味しています。すなわち、クラウド側のアプリケーションからは、すべてVPGとの通信として見えており、その先のIoTデバイスのIPアドレスが直接見えるわけではありません。

IoTデバイスの識別をIPアドレスで行いたい場合は、この制約は課題となります。これを解決するために生まれてきたのがSORACOM Gateです。前述のように「クラウド上のサーバーやルーターをデバイスと同じLANに所属させる」 ことでこれを実現します。技術的には VXLAN という、L3ネットワークの上でL2ネットワークを作れる技術を利用しています。実際の作業としては、クラウド側でVXLANを動かすことができるサーバー(Amazon EC2等で構築するLinuxサーバー、Geet Peer と称する)を構築し、VPGとの間でVXLANのトンネルを作ります。

Gate PeerをAWS上で構築する方法は、オンラインで公開しています。

これにより、デバイスサブネット(黄色のネットワーク)が、Gate Peerのネットワークインターフェイスまで伸びてくるわけです。
下図の「VXLAN IF」が、デバイスサブネットのIPアドレスを持っていることに、ご注目ください。

これでデバイスとGate Peerが同じLAN(172.16.0.0/16)上に配置されましたので、相互に任意の通信が可能になりました。例えばGate Peerを踏み台として、デバイスに対してSSHしたりRDPしたりということができるようになります。もちろん、デバイス側からも直接Gate PeerのIPアドレスに対して通信が可能であり、その際のソースIPアドレスはデバイス個々のIPアドレスで認識できます。

Gate Peer でサポートされる OS の種類は?

VXLANをサポートしているOSであれば利用できる可能性があります。2022年1月時点ではLinux OSとなります。SORACOMではAmazon Linux もしくは Ubuntuが確認済みです。最新の対応状況はこちらをご覧ください。

Gate Peerを運用するうえでの課題: 可用性

上記の構成で一点気になってくるのが、Gate Peerの可用性です。

SSHやRDPの踏み台ということであれば、Gate Peerのダウンタイムは許容できそうです。またGate Peerに問題が発生しても、IPアドレスそのままにマシンをすげ替えるということで対処可能でしょう。EC2などのクラウド環境でなら簡単に実施可能ですね。実際、Floating IPパターンという名称のデザインパターンにもなっています。

デバイスからクラウドへデータ送信する場合はどうでしょうか。SORACOM Gateの検討背景を振り返ると「L2ネットワークを前提にしたアプリケーションを動かしたい」といった目的があることから、 SORACOM Funk等のアプリケーションレイヤーのサービスや、Amazon ELB(Elastic Load Balancing)のようなクラウドサービスがうまく活用できなかったりすることが考えられます。

また、ネットワークレベルでも例えばDNSによるフェイルオーバーといった手法が考えられますが、IoTデバイス側のDNSによる名前解決の実装に依存するため、長期にキャッシュされてしまっていたり、そもそも名前解決の実装がされていないケースも考えられます。

このような場合においても、データ送信を安定的に実現するためには、Gate Peerの可用性がポイントとなってきます。
こういったケースで活躍するのが、ネットワークレイヤでの冗長性を提供してくれるVRRPです。

VRRPでGate Peerを冗長化する

VRRP(Virtual Router Redundancy Protocol)は、複数のサーバーやルータを束ねて「仮想ルーター」を実現します。

この仮想ルーターには仮想IP(以下VIP)を設定し、外部の機器はVIPに対してアクセスしてもらうように設定します。
VIPは、仮想ルーター内のどれかの機器に割り当たるようになっており、これによってVIPから実際にパケットを処理するサーバーやルーターに転送される仕組みです。VIPが割り当たっているサーバーやルーターが障害でダウンしても、別のサーバーやルーターがVIPを引き継ぐため、外部からの見た目には「正常」なわけです。

Gate Peerも “サーバー” であるため、VRRPによって冗長化が可能です。

VRRPの設定の前に、まず実際の動作を見てみましょう。

  1. 画面「左」が、IoTデバイスです。pingを送信するようにしています。
  2. 画面中央の「上」が、Gate Peer 1台目です。
    最初にVIPが割り当てられています。そのため、デバイスからのpingは、Gate Peer 1に着信しています。
  3. 画面中央の「下」が、Gate Peer 2台目です。
    動画再生後、20秒くらいでGate Peer 1台目のネットワークを止め※ました。これにより、VIPがGate Peer2に引き継がれ、pingのパケットもGate Peer 2に着信し始めています。
    (※正確にはkeepalivedを停止)
  4. 動画の46秒からは、Gate Peer 1 のネットワークを回復しました。これにより、VIPが Gate Peer 1 に引き継がれ、pingのパケットもGate Peer 1 に着信しています。
AWS(や他のクラウド)でVRRPって使えたっけ?

鋭い疑問です。VRRPはIPマルチキャストを利用しています。一方で、AWS (未確認ですがGoogle CloudやMicrosoft Azureも同様)ではマルチキャストをサポートしておらず、そのままではVRRPが利用できません。
今回の場合、VXLANで構成したオーバーレイネットワーク(L2)上でVRRPを動かすところにポイントがあります。オンプレミスデータセンターのネットワークの場合この制約はありませんが、デバイスとの通信はVXLANトンネル内で行われるため、いずれにせよVXLAN上でVRRPを構成することになります。

VRRPを設定していく

Linux OS 上でVRRPを実現するにはkeepalivedが有名ですので、こちらを使っていきます。手順としてはざっくり以下のような形になります。

  1. VPG Type-Fを起動して、AWS VPCとのピアリングを設定する。
  2. Gate Peer用に2台のEC2を起動する
  3. VPGに上記2台のEC2をGate Peerとして登録する
  4. EC2にそれぞれVXLANインターフェイスを設定し、VXLANを開通させる
  5. EC2にkeepalivedをインストールしてVRRPの設定を行う

手順を追って中身を見ていきたいと思います。なお、ここでは「そのままやれば動く」という手順書ではないことにご注意ください。構築手順のイメージを付けていただくための参考としてご利用ください。

1. VPG Type-Fを起動してAWS VPCとのピアリングを設定する

ネットワークは以下のような構成であるとします。

  • デバイスサブネット: 172.16.0.0/16
  • AWS VPC: 10.0.0.0/16
  • VPGサブネット: 100.67.0.0/27(これはVPG作成時に自動的に決まります)

VPG Type-Fの設定は以下のようなイメージになります。

「VPCピア接続」を追加するとAWS VPCのコンソールでVPCのピアリングリクエストが確認できるようになりますので、それを受け入れてください。そのうえでVPGサブネットのアドレス100.67.0.0/27(NATされたあとのIPアドレスとして利用される)に向けのパケットをpeering connectionに向ける、という設定をVPCのルートテーブルに追加します。さらに、100.67.0.0/27からのパケットを許可するというルールをセキュリティグループに追加しておきましょう(少なくとも、UDP 4789番ポートがVXLANの疎通に必要です)。

2. Gate Peer用に2台のEC2を起動する

手順1で用意したVPC内に、EC2を2台起動しておきます。ここではひとまずUbuntu20.04で話を進めることにします。2台のIPアドレスをそれぞれ10.0.0.9610.0.0.101とします。

3. VPGに上記2台のEC2をGate Peerとして登録する

下記のようなイメージで前述のEC2のIPアドレスをVPGにGate Peerとして登録していきます。

4. EC2にそれぞれVXLANインターフェイスを設定し、VXLANを開通させる

Ubuntu上でSORACOM GateのVXLANを設定するためのスクリプトgate_init_vxlan.shをダウンロードし、実行します。ダウンロードしたスクリプトに実行権限を付与して引数なしに実行してみると、以下のようなUsageが表示されます。

$ ./gate_init_vxlan.sh
usage: 
./gate_init_vxlan.sh [PHY_IF] [PHY_ADDR] [VXLAN_IF] [VXLAN_ADDR] [VXLAN_NETMASK] [VXLAN_ID] [VPG Outer IP 1] [VPG Outer IP 2]

今回の環境に合わせるなら、以下のような引数となります。

# Gate Peer1(10.0.0.96) 
./gate_init_vxlan.sh eth0 10.0.0.96 vxlan0 172.16.0.100 16 10 100.67.12.4 100.67.12.20 10.0.0.101

# Gate Peer2(10.0.0.101)
./gate_init_vxlan.sh eth0 10.0.0.101 vxlan0 172.16.0.101 16 10 100.67.12.4 100.67.12.20 10.0.0.96

VPG Outer IPは、VPGの物理IPアドレスです。VPGの「高度な設定」タブの「VPG の Gate Peer 一覧」にある「トンネル接続用IPアドレス」をコピーして利用してください。なお、このアドレスが2つあるのは、SORACOM側ではVPGが冗長化されているためです。

これで以下のような構成が出来上がりました。Gate PeerのEC2同士でもVXLANを張っているのは、VPGが折返し通信を許容していないためです。これがないとheatbeatなどが通らなくなり、keepalivedによるVRRPがうまく動きません。

5. EC2にkeepalivedをインストールしてVRRPの設定を行う

まず、VRRPを扱えるように/etc/sysctl.confに以下の1行を追加します。

net.ipv4.ip_nonlocal_bind = 1

keepalivedのインストールは、yumやaptでインストールします。
その後、 以下のような設定ファイルを作成したうえでkeepalivedを起動してやればOKです。

Gate Peer 1 用 /etc/keepalived/keepalived.conf
#Gate Peer1: /etc/keepalived/keepalived.conf
global_defs {
    vrrp_garp_master_refresh 60
}
vrrp_instance VI_1 {
    state MASTER
    interface vxlan0
    virtual_router_id 51
    priority 160
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    unicast_peer {
        172.16.0.101
    }
    virtual_ipaddress {
        172.16.0.150
    }
}
Gate Peer 2 用 /etc/keepalived/keepalived.conf
#Gate Peer2 /etc/keepalived/keepalived.conf
global_defs {
    vrrp_garp_master_refresh 60
}
vrrp_instance VI_1 {
    state BACKUP
    interface vxlan0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    unicast_peer {
        172.16.0.100
    }
    virtual_ipaddress {
        172.16.0.150
    }
}

もうひとつのユースケース: Gate Peerの向こう側のサーバーとルーティングする

実はSORACOM GateにSORACOM JunctionのRedirection機能(以下、Redirection)を組み合わせると、Gate Peerをルーターとして利用して、カスタマーVPC内のサーバー群と通信が可能です。以下のように、IoT デバイスから Gate Peer を抜けて “EC2” とあるサーバーに着信できます。

なぜSORACOM Junctionが必要になるのかという点についてはSORACOMで拡張する企業ネットワークの構築例で詳しく解説されていますが、未知のネットワーク向けのパケットの投げ先としてGate Peerを指定する、というところでRedirectionがその役割を負ってくれます。

ここで冗長化の話に戻ってくるのですが、やはりルーターと化したGate Peerも冗長化したいですよね?
ということでRedirectionのリダイレクト先にVRRPのVIPを指定することでルーターとしてのGate Peerも冗長化できてしまいます!設定は簡単で以下のようなイメージです。

  1. Redirectionのターゲットとして指定するためのVIPをGate Peerとして追加
  2. 上記で作成したVIPをRedirectionのターゲットとして設定

VIPをGate Peerとして設定するのがポイントです。これはRedirectionのターゲットが登録済みのGate PeerのIPアドレスしか設定できないようになっているためです。なお、このVIP用のGate Peerはダミー的な設定なので「トンネル接続用IPアドレス」は存在しないもので構いません。

ここまでの設定で「クラウド向き」のパケットはうまくルーティングされるようになりました。「デバイス向き」のパケットもやはり動的にVRRPのMaster側を通してやる必要があります。オンプレミスネットワークの場合、こちら側にもVRRPを設定してやることで実現できますが、AWS等のクラウドの場合、生のネットワーク上ではVRRPが使えないので、VRRPのMaster切り替えのタイミングで動的にルートテーブルの設定を書き換えてやるのがよいでしょう。

今回の例で利用しているkeepalivedではState変更時に任意のスクリプトを呼び出すことができますのでそれを使って以下のような設定をしてやることでうまく実現ができます。

VRRP Master 用 /etc/keepalived/keepalived.conf
#### /etc/keepalived/keepalived.conf
global_defs {
    vrrp_garp_master_refresh 60
}
vrrp_instance VI_1 {
    state MASTER
    interface vxlan0
    virtual_router_id 51
    priority 160
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    unicast_peer {
        172.16.0.101
    }
    virtual_ipaddress {
        172.16.0.150
    }
    notify /usr/local/bin/switch-route-trigger.sh
}
VRRP Master /usr/local/bin/switch-route-trigger.sh
####/usr/local/bin/switch-route-trigger.sh
TYPE=$1
NAME=$2
STATE=$3

case $STATE in
        "MASTER") echo "MASTER"
                  /usr/local/bin/switch-route.sh
                  exit 0
                  ;;
        "BACKUP") echo "BACKUP"
                  exit 0
                  ;;
        "FAULT")  echo "FAULT"
                  exit 0
                  ;;
        *)        echo "unknown state"
                  exit 1
                  ;;
esac
VRRP Master /usr/local/bin/switch-route.sh
####/usr/local/bin/switch-route.sh
ROUTE_TABLE_ID="rtb-212ba845" #ターゲットべた書きなのはご容赦を
TARGET_CIDR="172.16.0.0/16"
echo "switching route to ${TARGET_CIDR} of route table ${ROUTE_TABLE_ID}"
aws ec2 delete-route --region ap-northeast-1 --route-table-id ${ROUTE_TABLE_ID} --destination-cidr-block ${TARGET_CIDR}
aws ec2 create-route --region ap-northeast-1 --route-table-id ${ROUTE_TABLE_ID} --destination-cidr-block ${TARGET_CIDR} --instance-id `wget -q -O - http://169.254.169.254/latest/meta-data/instance-id`

最後に、作成したシェルスクリプトに実行権限を付与します。

####/usr/local/bin/switch-route.sh
chmod +x /usr/local/bin/switch-route-trigger.sh
chmod +x /usr/local/bin/switch-route.sh

ざっくりとした流れは以下のようなイメージです。

  1. keepalived.confでnotify指定したスクリプトがState変更時に呼び出される
  2. switch-route-trigger.shでは自身がMasterにState変更された場合のみさらにswitch-route.shを呼び出す
  3. switch-route.shは指定されたルートテーブルに対して、デバイス向けのパケットのNexthopを自身に向けるようAWSのAPIを呼び出して設定変更する

デモ動画です。手順が込み入ってるので、こちらは音声で解説を付けてあります。

いかがでしょうか!Gate Peerを冗長化されたルーターとして利用して、デバイスと外部のネットワークをルーティングできている様子が見えたと思います。

まとめ

サーバーでデータを受け取る」という構成をつくることができました。
SORACOM Gateはサーバーをデバイスと同じネットワークに所属させることができる便利なサービスですが、商用利用時に当然必要になってくるGate Peerの冗長化には一工夫必要なのでご紹介してみました。Gate Peerを利用する構成を検討する際にはぜひ検討材料としてご活用いただければ幸いです。

注意頂きたい点としてはこういった構成を取るのは、既存の仕組みの制約からクラウドネイティブなアプリケーション構成を取れない場合の選択肢であるということです。
本文中でも何度か触れていますが、AWS LambdaやAmazon ELB、他にもAWS IoT CoreやAmazon Kinesisなど)といったようなマネージドなクラウドサービスが利用できる場合はぜひそちらの利用を検討してみてください。SORACOMで構成できるネットワークとNAT越えのさまざまというタイトルで、デバイスとクラウドの通信方式を網羅的にまとめたものがありますので、ぜひこちらもご参考になさっていただければと思います。

― ソラコム今井 (factory)