0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

クライド上でVRRPを実現する

Posted at

概要

Oracle Cloud Infrastructure(OCI)上にてVRRPの検証を行いました

仕組み

オンプレ環境と比較してクラウドはネットワーク冗長化の制約があるため以下のように実現しています
クラウドはOCI, ネットワークデバイスはVYOSを使用しました

  • VRRP Hello
    • オンプレ:Multicastで実行可能
    • OCI:Multicast通信の制限があるのでUnicastを使用
  • VRRP切り替え
    • オンプレ:BACKUPがMASTERに切り替わり、新MASTERよりGratuitous ARP送出
    • OCI:BACKUPがMASTERに切り替わり、以下手順でセカンダリIP(VIP)を移動
      • 新MASTERからAPI Gatewayにcurl POST発行
      • API GatewayからFunction呼び出し
      • 旧MASTERのVNICのセカンダリIP(VIP)を新MASTERのVNICに移動するFunctionsを実行

検証構成図

  • ACTIVEルーターをVYOS1, STANDBYルーターをVYOS2
  • サブネット
    • 10.107.1.0/24 : 外部ルーター接続
    • 10.107.2.0/24 : VRRP稼働、サーバーが存在
    • 10.107.3.0/24 : API GWおよびFn用

前提

以下を前提としています

  • Functionを作成したことがある
  • オンプレ~OCI間のVPN構築済

準備

OCI Policy

IPアドレスを操作するためのポリシーは以下を設定します

  • FunctionsからIPアドレス更新を実行
    Allow dynamic-group [functionsリソースを含むグループ] to use private-ips in compartment [コンパートメント名]
    Allow dynamic-group [functionsリソースを含むグループ] to use vnics in compartment [コンパートメント名]
    または
    Allow dynamic-group [functionsリソースを含むグループ] to use virtual-network-family in compartment [コンパートメント名]

Seconday IP

  • OCIコンソールナビゲーションメニューからコンピュート>>インスタンス>>対象のインスタンス(例:VYOS1)を選択
  • ResourcesからアタッチされたVNIC>>セカンダリVNIC>>IPv4 アドレスを選択して[セカンダリ・プライベートIPアドレスの割当て]を押下してセカンダリIPを入力して[割当て]を押下(例:10.107.2.100)
  • 作成したセカンダリIPの3点リーダー(︙)をクリックしてプライべートIP OCIDのコピーを選択

ルーティング

  • OCIコンソールナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>対象VCN>>ルート表>>対象ルート表を選択して[ルート・ルール]を押下
  • 以下を設定して[ルートルールの追加]を押下
    • ターゲット・タイプ:プライベートIP
    • 宛先タイプ:CIDRブロック
    • 宛先CIDRブロック:対向側CIDR
    • ターゲット選択:プライべートIP OCID

Functions

  • OCIコンソールナビゲーションメニューから開発者サービス>>ファンクションを選択して[アプリケーションの作成]を押下
  • 以下を設定して[作成]を押下
    • 名前:任意
    • サブネット:Functionを実行するサブネット(例:10.107.3.0/24)
    • 作成したアプリケーション下でFunctionを設定
func.py
import io
import json
import logging
import oci

def handler(ctx, data: io.BytesIO = None):
    try:
        body = json.loads(data.getvalue())
        private_ip_id = body["private_ip_id"]
        vnic_id = body["vnic_id"]

        # Resource principal
        signer = oci.auth.signers.get_resource_principals_signer()
        
        # Update private ip using resource principal
        core_client = oci.core.VirtualNetworkClient(config={},signer=signer,service_endpoint="https://iaas.ap-tokyo-1.oraclecloud.com")

        update_private_ip_response = core_client.update_private_ip(
            private_ip_id=private_ip_id,
            update_private_ip_details=oci.core.models.UpdatePrivateIpDetails(
                vnic_id=vnic_id
            )
        )

    except Exception as e:
        print('ERROR: bad Event!', flush=True)
        raise
func.yaml
schema_version: 20180708
name: updateprivateip
version: 0.0.8
runtime: python
build_image: fnproject/python:3.11-dev
run_image: fnproject/python:3.11
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256
requirements.txt
fdk>=0.1.86
oci

アプリケーションを指定してFunctionsをデプロイ

fn -v deploy --app <App名>

API Gateway

ネットワーク・セキュリティ・グループ(NSG)

NSGを設定してAPI GatewayへのアクセスはVYOSのみに制限します

  • OCIコンソールナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>対象VCN>>リソース ネットワーク・セキュリティ・グループを選択して[ネットワーク・セキュリティ・グループの作成]を押下
  • 以下を設定して[作成]を押下
    • 名前:任意
    • ルール:
      • 方向:イングレス
      • ソース・タイプ:CIDR
      • ソースCIDR:VYOS1 LAN IP(例:10.107.1.98/32)
      • IPプロトコル:TCP
      • ソース・ポート範囲:All
      • 宛先ポート範囲:443
    • 別のルール:
      • 方向:イングレス
      • ソース・タイプ:CIDR
      • ソースCIDR:VYOS2 LAN IP(例:10.107.1.99/32)
      • IPプロトコル:TCP
      • ソース・ポート範囲:All
      • 宛先ポート範囲:443

API Gateway

  • OCIコンソールナビゲーションメニューから開発者サービス>>API管理>>ゲートウェイから[ゲートウェイの作成]を押下
  • 以下を設定して[ゲートウェイの作成]を押下
    • 名前:任意
    • タイプ:プライベート
    • ネットワーク:対象ネットワークを指定(例:10.107.3.0)
    • ネットワーク・セキュリティ・グループの有効化にチェックして作成したNSGを選択
  • 作成したゲートウェイから呼び出すFunctionsを選択してリソース デプロイメントから[デプロイメントの作成]を押下
  • 以下を設定して[作成]を押下
    - 名前:任意
    - パス接頭辞:任意(例:/icnfnapp)
    - 認証:なし
    - パス:任意(例:/updateprivateip)
    - メソッド:POST
    - バックエンド・タイプ:Oracleファンクション
    - アプリケーション:作成したアプリケーション
    - 関数名:作成したFunction

VYOS

ルーターVYOS1およびVYOS2にVRRPを設定します。
設定のポイントは以下のとおりです。

  • StateがMasterになった場合Curl POSTするShellを実行
  • VYOS1復旧時にMasterとなるDelay値を60秒にする

VYOS1

  • config抜粋
set high-availability vrrp group vrrp01 hello-source-address '10.107.2.98'
set high-availability vrrp group vrrp01 interface 'eth1'
set high-availability vrrp group vrrp01 peer-address '10.107.2.99'
set high-availability vrrp group vrrp01 preempt-delay '60'
set high-availability vrrp group vrrp01 priority '200'
set high-availability vrrp group vrrp01 transition-script master '/config/scripts/updateprivateip_1.sh'
set high-availability vrrp group vrrp01 virtual-address 10.107.2.100/24
set high-availability vrrp group vrrp01 vrid '10'

set interfaces ethernet eth0 address '10.107.1.98/24'
set interfaces ethernet eth1 address '10.107.2.98/24'

set protocols static route 0.0.0.0/0 next-hop 10.107.1.1
  • Shell
/config/scripts/updateprivateip_1.sh
#!/bin/bash

curl -k -X POST https://10.107.3.105/icnfnapp/updateprivateip -d '{"private_ip_id":"<Secondary IP OCID>","vnic_id":"<VYOS1 Secondary VNIC OCID>"}'

VYOS2

  • config抜粋
set high-availability vrrp group vrrp01 hello-source-address '10.107.2.99'
set high-availability vrrp group vrrp01 interface 'eth1'
set high-availability vrrp group vrrp01 peer-address '10.107.2.98'
set high-availability vrrp group vrrp01 priority '100'
set high-availability vrrp group vrrp01 transition-script master '/config/scripts/updateprivateip_2.sh'
set high-availability vrrp group vrrp01 virtual-address 10.107.2.100/24
set high-availability vrrp group vrrp01 vrid '10'

set interfaces ethernet eth0 address '10.107.1.99/24'
set interfaces ethernet eth1 address '10.107.2.99/24'

set protocols static route 0.0.0.0/0 next-hop 10.107.1.1

  • Shell
/config/scripts/updateprivateip_2.sh
#!/bin/bash

curl -k -X POST https://10.107.3.105/icnfnapp/updateprivateip -d '{"private_ip_id":"<Secondary IP OCID>","vnic_id":"<VYOS1 Secondary VNIC OCID>"}'

検証

ACTIVEルーターを落として迂回できることを確認しました。なお、環境の都合上海外サイトを使用しているためレイテンシーが大きいですがテストには支障ありません。

通常時

  • VRRP StateをVYOSから確認
user@VYOS1:~$ show vrrp
Name    Interface      VRID  State      Priority  Last Transition
------  -----------  ------  -------  ----------  -----------------
vrrp01  eth1             10  MASTER          200  2d17h48m29s

user@VYOS2:~$ show vrrp
Name    Interface      VRID  State      Priority  Last Transition
------  -----------  ------  -------  ----------  -----------------
vrrp01  eth1             10  BACKUP          100  2d17h48m26s
  • OCIコンソールからセカンダリIP付与を確認
    VYOS1

VYOS2

  • オンプレからサーバーにPING
C:\>ping 10.107.2.200 -t

10.107.2.200 に ping を送信しています 32 バイトのデータ:
10.107.2.200 からの応答: バイト数 =32 時間 =382ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =378ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =391ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =371ms TTL=60

VYOS1障害

  • VRRP StateをVYOSから確認
user@VYOS1は障害のためログなし
user@VYOS2:~$ show vrrp
Name    Interface      VRID  State      Priority  Last Transition
------  -----------  ------  -------  ----------  -----------------
vrrp01  eth1             10  MASTER          100  24s
  • OCIコンソールからセカンダリIP付与を確認
    VYOS1

VYOS2

  • オンプレからサーバーにPINGして復旧を確認
C:\>ping 10.107.2.200 -t

10.107.2.200 に ping を送信しています 32 バイトのデータ:
10.107.2.200 からの応答: バイト数 =32 時間 =379ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =432ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =377ms TTL=60
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
10.107.2.200 からの応答: バイト数 =32 時間 =376ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =370ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =367ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =377ms TTL=60

VYOS1復旧

  • VRRP StateをVYOSから確認
user@VYOS1:~$ show vrrp
Name    Interface      VRID  State      Priority  Last Transition
------  -----------  ------  -------  ----------  -----------------
vrrp01  eth1             10  MASTER          200  10s

user@VYOS2:~$ show vrrp
Name    Interface      VRID  State      Priority  Last Transition
------  -----------  ------  -------  ----------  -----------------
vrrp01  eth1             10  BACKUP          100  14s
  • OCIコンソールからセカンダリIP付与を確認
    VYOS1

VYOS2

  • オンプレからサーバーにPING
C:\>ping 10.107.2.200 -t

10.107.2.200 に ping を送信しています 32 バイトのデータ:
10.107.2.200 からの応答: バイト数 =32 時間 =376ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =383ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =380ms TTL=60
略
10.107.2.200 からの応答: バイト数 =32 時間 =380ms TTL=60
10.107.2.200 からの応答: バイト数 =32 時間 =374ms TTL=60

10.107.2.200 の ping 統計:
    パケット数: 送信 = 190、受信 = 190、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 354ms、最大 = 723ms、平均 = 383ms

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?