BIG-IP on EC2に複数のVirtual Serverを追加してみた

BIG-IP on EC2に複数のVirtual Serverを追加してみた

ENIに割り当て可能なIPアドレス数に気をつけよう
2025.07.24

BIG-IP経由でアクセスしたいシステムが増えた場合にどのような対応が必要なのか気になる

こんにちは、のんピ(@non____97)です。

皆さんはBIG-IP経由でアクセスしたいシステムが増えた場合にどのような対応が必要なのか気になったことはありますか? 私はあります。

BIG-IP経由でアクセスしたいシステムが増えた場合はVirtual Serverを追加してくことになります。

しかし、インターネット上の情報ではAWS上でBIG-IP VEを動作させ、複数のVirtual Serverを動作させているような事例は見つかりませんでした。

思わぬ落とし穴があるかもしれません。

ということで、実際に複数のVirtual Serverを動作させてみます。

いきなりまとめ

  • Virtual Serverを追加する際には大きく以下の2パターンがある
    • 既存のENIにVirtual Server用のIPアドレスを付与するパターン
    • 新規にENIを用意してVirtual Server用のIPアドレスを付与するパターン
  • EC2インスタンスに割り当て可能なENIと一つのENIあたりに付与できるIPアドレスを把握しておこう

検証環境

検証環境は以下のとおりです。

フェイルオーバー前.png

以下記事で用意したリソースをそのまま利用します。

https://dev.classmethod.jp/articles/bigip-on-ec2-without-source-nat/

既存のENIにVirtual Server用のIPアドレスを付与するパターン

ENIにIPアドレスを付与

Virtual ServerそれぞれにVIPを用意する必要があります。AWSにおいては以下記事で紹介しているように、Cloud Failover Extention(CFE)を用いてVIPのEIPをActive側のBIG-IPに関連づけるようにしています。

https://dev.classmethod.jp/articles/big-ip-multi-az-ha-cluster-cloudformation/

Virtual Server個別にVIPを用意する必要があるのであれば、まず考えられる方法は既存のENIにVirtual Server用のIPアドレスを付与するパターンです。

まず、External ENIにIPアドレスを付与します。今回は10.0.0.102を付与しました。

1.External ENIにIPアドレスを追加.png

確認して付与します。

2.External ENIにIPアドレスを追加2.png

追加後のExternal ENIは以下のようになりました。

3.ENIの確認.png.png

BIG-IP BのExternal ENIにも同様にセカンダリIP10.0.4.102を付与しました。

4.ENIの確認2.png

現在の構成を図示すると、以下のとおりです。

既存のENIにVirtual Server用のIPアドレスを付与するパターン.png

EIPの割り当て

続いて、追加するVirtual Serverが使用するVIPと関連付けるEIPの割り当てを行います。

既存のVirtual Server用のEIPを参考にタグ付けをして、EIPの割り当てをします。

5.EIPの割り当て.png

割り当てられたEIPをBIG-IP Aに先ほど追加したセカンダリIP10.0.0.102に関連づけます。

6.EIPの関連付け.png

これで、Virtual Server側で10.0.0.102で待ち受けていれば、紐づいているEIP経由で通信できるようになります。

Virtual Serverの作成

Virtual Serverの作成を行います。

7.Virtual Serverの追加.png

Destination Address/Mask10.0.0.102にしたapplication2-01も作成します。

8.Virtual Serverの追加2.png

Destination Address/Mask10.0.4.102にしたapplication2-02も作成します。追加後は以下のとおりです。

9.Virtual Server一覧.png

Cloud Failover Extentionの設定確認

CFEの設定を事前に確認しておきます。

>  curl \
    -sku admin:$admin_password \
    -X GET https://23.20.172.35/mgmt/shared/cloud-failover/declare \
    | jq .
{
  "message": "success",
  "declaration": {
    "schemaVersion": "1.0.0",
    "class": "Cloud_Failover",
    "environment": "aws",
    "controls": {
      "class": "Controls",
      "logLevel": "silly"
    },
    "externalStorage": {
      "encryption": {
        "serverSide": {
          "enabled": true,
          "algorithm": "AES256"
        }
      },
      "scopingTags": {
        "f5_cloud_failover_label": "bigip_high_availability_solution"
      }
    },
    "failoverAddresses": {
      "enabled": true,
      "scopingTags": {
        "f5_cloud_failover_label": "bigip_high_availability_solution"
      },
      "requireScopingTags": false
    },
    "failoverRoutes": {
      "enabled": true,
      "routeGroupDefinitions": [
        {
          "scopingName": "rtb-060adeaa8fe5b2bbb",
          "scopingAddressRanges": [
            {
              "range": "0.0.0.0/0"
            }
          ],
          "defaultNextHopAddresses": {
            "discoveryType": "static",
            "items": [
              "10.0.0.11",
              "10.0.4.11"
            ]
          }
        }
      ]
    }
  }
}

今回はタグで制御するため特に追加の変更は不要です。

動作確認

動作確認です。追加したVirtual ServerのIPアドレスに紐づくEIPでアクセスします。

>  curl http://35.153.164.7/
big-ip-application1-01

>  curl http://35.153.164.7/
big-ip-application1-02

>  curl http://35.153.164.7/
big-ip-application1-01

>  curl http://35.153.164.7/
big-ip-application1-02

正常にレスポンスが返ってきていますね。

既存のVirtual Serverでも通信できることを確認します。

>  curl http://98.80.114.203/
big-ip-application1-01

>  curl http://98.80.114.203/
big-ip-application1-02

>  curl http://98.80.114.203/
big-ip-application1-01

>  curl http://98.80.114.203/
big-ip-application1-01

>  curl http://98.80.114.20

こちらも問題ありません。

それではフェイルオーバーをします。

フェイルオーバー前のBIG-IP Aは以下のとおりです。Virtual Server用のEIPであるeip-03eip-04が関連付いています。

11.フェイルオーバー前のBIG-IP A.png

フェイルオーバーを行います。

10.フェイルオーバー.png

フェイルオーバー前のBIG-IP Aは以下のとおりです。先ほどはあったVirtual Server用のEIPであるeip-03eip-04がありませんね。

12.フェイルオーバー後のBIG-IP A.png

フェイルオーバー前のBIG-IP Bは以下のとおりです。BIG-IP Aに変わりVirtual Server用のEIPであるeip-03eip-04が関連付いています。

13.フェイルオーバー後のBIG-IP B.png

肝心の通信ですが、フェイルオーバー後以下のように正常に行えていました。今回のダウンタイムは165秒です。

$ while true; do
    start_time=$(date +%s.%N)
    response=$(curl -s --max-time 5 "http://35.153.164.7/")
    end_time=$(date +%s.%N)
    elapsed=$(echo "$end_time - $start_time" | bc)

    echo "$response | Response time: ${elapsed}s"
    sleep 0.1
done
.
.
(中略)
.
.
big-ip-application1-02 | Response time: .475858000s
big-ip-application1-01 | Response time: .467910000s
big-ip-application1-02 | Response time: .443871000s
big-ip-application1-01 | Response time: .430977000s
big-ip-application1-02 | Response time: .459591000s
 | Response time: 5.058976000s
 | Response time: 5.046715000s
 | Response time: 5.069641000s
 | Response time: 5.042827000s
 | Response time: 5.039422000s
 | Response time: 5.035741000s
 | Response time: 5.053062000s
 | Response time: 5.054793000s
 | Response time: 5.064019000s
 | Response time: 5.075754000s
 | Response time: 5.087337000s
 | Response time: 5.052597000s
 | Response time: 5.060167000s
 | Response time: 5.056574000s
 | Response time: 5.042860000s
 | Response time: 5.049029000s
 | Response time: 5.041052000s
 | Response time: 5.071579000s
 | Response time: 5.073980000s
 | Response time: 5.072291000s
 | Response time: 5.057779000s
 | Response time: 5.063992000s
 | Response time: 5.072451000s
 | Response time: 5.057887000s
 | Response time: 5.057067000s
 | Response time: 5.101915000s
 | Response time: 5.048106000s
 | Response time: 5.074464000s
 | Response time: 5.064783000s
 | Response time: 5.047526000s
 | Response time: 5.046538000s
 | Response time: 5.031387000s
 | Response time: 5.053621000s
big-ip-application1-02 | Response time: .458846000s
big-ip-application1-01 | Response time: .462222000s
big-ip-application1-02 | Response time: .471163000s
big-ip-application1-02 | Response time: .498125000s
big-ip-application1-01 | Response time: .409760000s

また、S3バケットに出力されたf5cloudfailoverstate.jsonは以下のとおりです。

f5cloudfailoverstate.json
{
  "taskState": "SUCCEEDED",
  "message": "Failover Complete",
  "timestamp": "2025-07-22T07:42:40.900Z",
  "instance": "failover02.www.non-97.net",
  "failoverOperations": {
    "addresses": {
      "publicAddresses": {
        "35.153.164.7": {
          "current": {
            "PrivateIpAddress": "10.0.0.102",
            "AssociationId": "eipassoc-06cfc5c0b17c5dd31"
          },
          "target": {
            "PrivateIpAddress": "10.0.4.102",
            "NetworkInterfaceId": "eni-04bec0335a47b26c3"
          },
          "AllocationId": "eipalloc-0f4f1689213270fdf"
        },
        "98.80.114.203": {
          "current": {
            "PrivateIpAddress": "10.0.0.101",
            "AssociationId": "eipassoc-03c5c6c908c1ba99b"
          },
          "target": {
            "PrivateIpAddress": "10.0.4.101",
            "NetworkInterfaceId": "eni-04bec0335a47b26c3"
          },
          "AllocationId": "eipalloc-0814e2bbaf002a2bc"
        }
      },
      "interfaces": {
        "disassociate": [
          {
            "networkInterfaceId": "eni-0812e390d83655675",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-0603a4992d0579540",
            "addresses": []
          }
        ],
        "associate": [
          {
            "networkInterfaceId": "eni-097a6bb7971ecceb4",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-04bec0335a47b26c3",
            "addresses": []
          }
        ]
      },
      "loadBalancerAddresses": {}
    },
    "routes": {
      "operations": [
        {
          "routeTableId": "rtb-060adeaa8fe5b2bbb",
          "networkInterfaceId": "eni-04bec0335a47b26c3",
          "routeAddress": "0.0.0.0/0",
          "nextHopAddress": "10.0.4.11",
          "ipVersion": "4"
        }
      ]
    }
  }
}

2つのVirtual Server用のEIPについて、関連付くENIの切り替えが発生したことが分かりますね。

新規にENIを用意してVirtual Server用のIPアドレスを付与するパターン

サブネットの作成

「既存のENIにVirtual Server用のIPアドレスを付与するパターン」はお手軽ですが、Virtual Serverの上限は気にする必要があります。

というのもインスタンスタイプごとに、1つのENIに割り当てられるIPアドレス数は決まっているためです。

例えば、m6i.xlargeの場合は最大4NIで、各ENIに15個のIPアドレスを割り当てることが可能です。インスタンスタイプごとのENIとIPアドレス数は以下AWS公式ドキュメントをご覧ください。

https://docs.aws.amazon.com/ec2/latest/instancetypes/gp.html#gp_network

ENIのプライマリIPアドレスはBIG-IPでSelf IPアドレスとして定義しているため、今回のケースでは一つのENIでは最大14個までのVirtual Serverまでしか用意ができません。

そのため、15個以上のVirtual Serverを動作させる場合は、追加のENIをアタッチして、そこにVirtual Server用のIPアドレスを割り振ることになります。

ざっと眺めたところ、いずれのインスタンファミリーでもインスタンスサイズがxlarge2xlargeの場合は1ENIにつき15IPアドレス、最大4ENIで、4xlargeから1ENIにつき30IPアドレス、最大8ENIの割り当てが可能でした。

ということで、「新規にENIを用意してVirtual Server用のIPアドレスを付与するパターン」を以降試します。

既存のVLANに追加のENIを登録しようとすると、Configuration error: vmw-compat: vlan may only have one interfaceとエラーになります。

そのため、新規のVLANを作る必要があります。

また、新規のVLANを追加した場合、追加のENIのSelf IPを既存のSelf IPと同一のサブネットマスクで登録しようとすると、01070354:3: Self IP 10.0.0.21 / 255.255.255.0: This network is defined on two vlans (/Common/external and /Common/external2)とエラーになります。

これはManagement用SubentにENIを追加し、そのENIのSelf IPを作成しようとした場合も同じで、01070392:3: Self IP 10.0.1.21 / 255.255.255.0: This IP shares a network with the management IP (10.0.1.11 / 255.255.255.0).とエラーになります。

対応として、既存のSelf IPと異なるサブネットマスクで追加のENIを用意する必要があります。

10.0.8.0/2410.0.9.0/24のCIDRブロックを持つサブネットを作成しました。

28.サブネットを作成.png

既存のパブリックサブネット用のルートテーブルを関連付けします。

29.ルートテーブルの関連付け.png

ENIの作成

新規に作成したサブネットにENIを追加します。IPアドレスは10.0.8.11としました。

30.External2 SubnetにENIを追加.png

Virtual Serverで使用するセカンダリIPアドレスを10.0.8.101として割り当てます。

31.セカンダリIPの追加.png

準備したENIをBIG-IP Aにアタッチします。

32.ENIのアタッチ.png

BIG-IP Aのネットワーク周りの設定は以下のようになっています。

42.BIG-IP Aのネットワーク.png

同様にBIG-IP B分のENIを作成して、BIG-IP Bに割り当てます。

44.BIG-IP Bのネットワーク.png

EIPの割り当て

追加するVirtual Serverが使用するVIPと関連付けるEIPの割り当てを行います。

既存のVirtual Server用のEIPを参考にタグ付けをして、EIPの割り当てをします。

37.EIPの割り当て.png

割り当てられたEIPをBIG-IP Aに先ほど追加したセカンダリIP10.0.8.101に関連づけます。

38.EIPの関連付け.png

これで、Virtual Server側で10.0.8.101で待ち受けていれば、紐づいているEIP経由で通信できるようになります。

現時点の構成を図示すると以下のとおりです。

新規にENIを用意してVirtual Server用のIPアドレスを付与するパターン.png

VLANの作成

追加したENIはInterface 1.3として認識されており、UNINITIALIZEDとなっています。

33.UNINITIALIZEDの確認.png

VLANを作成しましょう。

17.VLANの追加.png

今回はexternal2というVLANを作成します。

18.VLANの追加2.png

作成後は以下のとおりです。

19.VLANの確認.png

このタイミングでInterface 1.3がUPとなったことを確認します。

34.UPの確認.png

BIG-IP B側でもVLANの作成を行います。

45.BIG-IP BのVLAN.png

Self IPの設定

続いて、Self IPの設定を行います。

external2-selfという名前で10.0.8.11と追加したENIのプライマリIPアドレスを指定します。

35.Self IPの設定.png

Port Lockdownは既存のexternalのSelf IPと同様に以下ポートを許可します。

  • TCP/443
  • TCP/4353
  • TCP/6123
  • TCP/6124
  • TCP/6125
  • TCP/6126
  • TCP/6127
  • TCP/6128

Self IPの作成が完了すると、以下のとおりです。

36.Self IP作成完了.png

BIG-IP B側でも同様に行います。

46.BIG-IP BのSelf IP.png

Virtual Serverの作成

Virtual Serverの作成をします。

Virtual Server用のIPアドレス10.0.8.101で待ち受けるようにします。

39.Virtual Serverの追加.png

また、Source Address Translationはアクセスした時に他Virtual Serverのものと判別しやすくするためにAuto Mapとしました。External ENIが複数あり、それぞれのENIを使用しているVirtual ServerがSNATを行わない形でも問題なく動作します。

BIG-IP B用のVirtual Serverも用意します。

最終的に以下のような状態になります。

41.Virtual Serverの確認.png

このタイミングで軽く動作確認をします。

SNATをしないVirual Serverにアクセスします。

$ curl http://35.153.164.7
big-ip-application1-02

$ curl http://35.153.164.7
big-ip-application1-01

$ curl http://35.153.164.7
big-ip-application1-02

$ curl http://35.153.164.7
big-ip-application1-01

問題ないですね。

この時のアクセスログは以下のとおりです。

big-ip-application1-01の/var/log/nginx/access.log
{"time_local":"24/Jul/2025:02:57:09 +0000","remote_addr":"104.28.243.105","remote_user":"","request":"GET / HTTP/1.1","status": 200,"body_bytes_sent": 23,"request_time": 0.000,"http_referrer":"","http_user_agent":"curl/8.14.1","http_x_forwarded_for":"104.28.243.105"}
{"time_local":"24/Jul/2025:02:57:11 +0000","remote_addr":"104.28.243.105","remote_user":"","request":"GET / HTTP/1.1","status": 200,"body_bytes_sent": 23,"request_time": 0.000,"http_referrer":"","http_user_agent":"curl/8.14.1","http_x_forwarded_for":"104.28.243.105"}

SNATをしていないため、remote_addrhttp_x_forwarded_forの値が一致していますね。

つい先ほど追加したVirtual Serverにアクセスします。

$ curl http://98.86.126.154
big-ip-application1-02

$ curl http://98.86.126.154
big-ip-application1-01

$ curl http://98.86.126.154
big-ip-application1-01

$ curl http://98.86.126.154
big-ip-application1-02

こちらも問題なく動作しています。

この時のアクセスログは以下のとおりです。

big-ip-application1-01の/var/log/nginx/access.log
{"time_local":"24/Jul/2025:02:58:35 +0000","remote_addr":"10.0.0.11","remote_user":"","request":"GET / HTTP/1.1","status": 200,"body_bytes_sent": 23,"request_time": 0.000,"http_referrer":"","http_user_agent":"curl/8.14.1","http_x_forwarded_for":"104.28.243.105"}
{"time_local":"24/Jul/2025:02:58:35 +0000","remote_addr":"10.0.0.11","remote_user":"","request":"GET / HTTP/1.1","status": 200,"body_bytes_sent": 23,"request_time": 0.000,"http_referrer":"","http_user_agent":"curl/8.14.1","http_x_forwarded_for":"104.28.243.105"}

こちらはAuto Mapなので、remote_addrhttp_x_forwarded_forの値が異なっていますね。

動作確認

フェイルオーバー後も正常に通信が行えることを確認します。

結果は以下のようにフェイルオーバー後も正常に行えていました。今回のダウンタイムは145秒です。

$ while true; do
    start_time=$(date +%s.%N)
    response=$(curl -s --max-time 5 "http://98.86.126.154/")
    end_time=$(date +%s.%N)
    elapsed=$(echo "$end_time - $start_time" | bc)

    echo "$response | Response time: ${elapsed}s"
    sleep 0.1
done
.
.
(中略)
.
.
big-ip-application1-02 | Response time: .499082000s
big-ip-application1-01 | Response time: .431307000s
big-ip-application1-02 | Response time: .421754000s
big-ip-application1-01 | Response time: .450458000s
big-ip-application1-01 | Response time: .452805000s
big-ip-application1-02 | Response time: .440617000s
 | Response time: 5.063204000s
 | Response time: 5.064601000s
 | Response time: 5.067433000s
 | Response time: 5.063204000s
 | Response time: 5.047891000s
 | Response time: 5.104974000s
 | Response time: 5.042047000s
 | Response time: 5.053368000s
 | Response time: 5.054971000s
 | Response time: 5.046252000s
 | Response time: 5.069700000s
 | Response time: 5.066611000s
 | Response time: 5.096630000s
 | Response time: 5.071345000s
 | Response time: 5.073140000s
 | Response time: 5.048746000s
 | Response time: 5.067593000s
 | Response time: 5.056039000s
 | Response time: 5.065750000s
 | Response time: 5.049015000s
 | Response time: 5.054108000s
 | Response time: 5.063461000s
 | Response time: 5.059771000s
 | Response time: 5.057051000s
 | Response time: 5.046760000s
 | Response time: 5.060434000s
 | Response time: 5.060983000s
 | Response time: 5.056340000s
 | Response time: 5.050734000s
big-ip-application1-01 | Response time: .466152000s
big-ip-application1-01 | Response time: .455993000s
big-ip-application1-02 | Response time: .469700000s
big-ip-application1-02 | Response time: .433265000s
big-ip-application1-01 | Response time: .515623000s
big-ip-application1-01 | Response time: .441114000s
big-ip-application1-02 | Response time: .423759000s

フェイルオーバー後は以下の曜日BIG-IP BにVirtual Server用のEIPが移動していました。

47.フェイルオーバー後のBIG-IP B.png

また、S3バケットに出力されたf5cloudfailoverstate.jsonは以下のとおりです。

f5cloudfailoverstate.json
{
  "taskState": "SUCCEEDED",
  "message": "Failover Complete",
  "timestamp": "2025-07-24T06:49:44.075Z",
  "instance": "failover02.www.non-97.net",
  "failoverOperations": {
    "addresses": {
      "publicAddresses": {
        "35.153.164.7": {
          "current": {
            "PrivateIpAddress": "10.0.0.102",
            "AssociationId": "eipassoc-0f00a15a83ee38c81"
          },
          "target": {
            "PrivateIpAddress": "10.0.4.102",
            "NetworkInterfaceId": "eni-04bec0335a47b26c3"
          },
          "AllocationId": "eipalloc-0f4f1689213270fdf"
        },
        "98.80.114.203": {
          "current": {
            "PrivateIpAddress": "10.0.0.101",
            "AssociationId": "eipassoc-0da904522071a6b23"
          },
          "target": {
            "PrivateIpAddress": "10.0.4.101",
            "NetworkInterfaceId": "eni-04bec0335a47b26c3"
          },
          "AllocationId": "eipalloc-0814e2bbaf002a2bc"
        },
        "98.86.126.154": {
          "current": {
            "PrivateIpAddress": "10.0.8.101",
            "AssociationId": "eipassoc-05add6e6f5120d878"
          },
          "target": {
            "PrivateIpAddress": "10.0.9.101",
            "NetworkInterfaceId": "eni-01af553b87fc1ebaa"
          },
          "AllocationId": "eipalloc-0ababfc0a7aa61370"
        }
      },
      "interfaces": {
        "disassociate": [
          {
            "networkInterfaceId": "eni-0603a4992d0579540",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-0a338c89f2a2cec39",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-0812e390d83655675",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-0603a4992d0579540",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-0a338c89f2a2cec39",
            "addresses": []
          }
        ],
        "associate": [
          {
            "networkInterfaceId": "eni-04bec0335a47b26c3",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-04bec0335a47b26c3",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-097a6bb7971ecceb4",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-01af553b87fc1ebaa",
            "addresses": []
          },
          {
            "networkInterfaceId": "eni-01af553b87fc1ebaa",
            "addresses": []
          }
        ]
      },
      "loadBalancerAddresses": {}
    },
    "routes": {
      "operations": [
        {
          "routeTableId": "rtb-060adeaa8fe5b2bbb",
          "networkInterfaceId": "eni-04bec0335a47b26c3",
          "routeAddress": "0.0.0.0/0",
          "nextHopAddress": "10.0.4.11",
          "ipVersion": "4"
        }
      ]
    }
  }
}

ENIに割り当て可能なIPアドレス数に気をつけよう

BIG-IP on EC2で複数のVirtual Serverを追加してみました。

ENIに割り当て可能なIPアドレス数に気をつけましょう。大量のVirtual Serverを用意する場合は複数のBIG-IPのHAクラスターを作る形になるでしょう。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.