ネットワークエンジニアのITブログ

長らくネットワークで仕事をしてきましたが、ここ数年クラウドとサーバー系に触れる機会が増えて、クラウドのネットワークというのが自分の性分にはあっているようです。最近のお気に入りはNSXALBとGoogle Cloud。

Avi Load Balancer導入編 (完) 名前解決も全自動!DNS連携で実現する「NoOps」なロードバランサ運用

ついにこの時が来ました。Avi Load Balancer導入記、最終回です。

第1回でメモリ枯渇に怯えながらSE(Service Engine)をデプロイし、第2回でMTUの壁に阻まれてVyOSを緊急投入し、第3回でWAFによる鉄壁の防御を手に入れました。
物理・仮想・オーバーレイが繋がり、セキュリティも確保された今、最後に残された課題は「運用」です。

「新しいWebサーバーを公開したい」と思った時、VS(仮想サービス)を作ってVIPを払い出すまではAviがやってくれます。
しかし、そのIPアドレス(例:192.168.49.101)を、手動でDNSサーバーに登録しに行っていませんか?

今回は、Aviの「DNSプロバイダー機能」を有効化し、「ロードバランサの設定を入れたら、勝手に名前解決できるようになっている」という、夢のような自動化環境を構築してシリーズを締めくくります。

DNSレコード登録からの脱却

これまでの検証では、Webブラウザhttp://192.168.49.100 のようにIP直打ちでアクセスしていました。
検証ならそれで良いですが、本番運用(ホームラボ的な意味で)では、やはり https://wordpress.avi.lab.local のようなFQDNでアクセスしたいものです。

しかし、VSを追加するたびに、既存のDNSサーバー(ADやBind)の設定ファイルを書き換えてAレコードを追加するのは非常に面倒です。
「AviでVIPを作った瞬間に、DNSレコードも自動で生成してほしい」
これを実現するのが、AviのIPAM/DNS連携機能です。

Aviを「権威DNSサーバー」にする

Aviは単なるロードバランサではなく、高機能なDNSサーバーとしても動作します。
今回は、Avi自身に特定のサブドメイン(例:*.avi.lab.local)の管理を任せる設定を行います。

Step 1:DNS VIPの作成

DNS VSを作成するためのVIPを作成します。
Applications> VS VIPsからCREATEをクリックします。

CloudでHomelab、VRF ContextでT1-GW-01をセットし、VIPsのADDをクリックします。

EDIT VIPにて、以下の設定を行いSAVEをクリックします。

  • Enable VIP:チェックを入れる
  • Private IP:Static
  • IPv4 Address:192.168.49.53(わかりやすいようにポート番号とあわせました)


VIPsに反映されたことを確認してSAVEをクリックします。


Step 2:DNSサービスの作成

続いて、DNSリクエストを待ち受けるための仮想サービス(DNS VS)を作ります。
Applications> Virtual Services からCREATE VIRTUAL SERVICEのAdvanced Setupをクリックします。

Select CloudでHomelab、Select VRF ContextでT1-GW-01を選択します。


以下の内容で設定しNextをクリックします。

  • Name:Avi-DNS-Service
  • VS VIP:DNS-VIP
  • TCP/UDP Profile:System-UDP-Per-Pkt
  • Application Profile:System-DNS
  • Services:53
  • Pool:なし

Service Engine Groupで、Homelab-Groupを選択し、Nextをクリックします。

あとはデフォルトのままSAVEをクリックするとDNS VSができます。

これで、AviがDNSパケットを喋れるようになりました。IPアドレス(192.168.40.53)を控えておきます。

Step 3:DNS Profileの定義

続いて「どのドメインをAviが管理するか」を定義します。
Templates > Profiles > IPAM/DNS Profiles で DNS Profile をクリックします。

以下の情報を入力しSAVEをクリックします。

  • Name:HomeLab-DNS-Profile
  • Type:Avi Vantage DNS
  • Domain Name:avi.lab.local(ホームラボのサブドメインとします)
  • Override Record TTL:60(ラボ用なので短めに)


プロファイルも作成できました。

Step 4:Cloudへの紐付け

作成したプロファイルを、第1回で設定した NSX連携しているCloudに適用します。
これで、Avi Controllerは「自分が avi.lab.local の管理者である」と認識し、配下のVSに対して名前を割り振る準備が整います。

Infrastructure > Clouds からHomelabの編集ボタンをクリックします。

IPAM/DNSDNS Profileが空欄になっているので、先ほど作成したHomeLab-DNS-Profileを選択しSAVEをクリックします。

Step 5:DNS SERVICESへの紐付け

作成したDNS VSをDNS SERVICEとして紐づけます。
私は、ここの設定が漏れていて、なかんかAviで名前解決が行ませんでした。
Administration > System Settings からEDITをクリックします。

DNS Sericesが空欄になっているので、DNS VSのAvi-DNS-Serviceを選択しSAVEをクリックします。

これで登録は完了です。

既存DNS (Bind) との連携

ここで一つの疑問が浮かびます。
「クライアントPCは既存のDNSサーバー(Bind: 192.168.10.9)を見ているのに、どうやってAviのレコードを引くの?」

答えは「フォワーディング(転送)」です。
既存のDNSサーバーに、「avi.lab.local への問い合わせが来たら、Avi (192.168.40.50) に転送してね」と教えるだけでOKです。

Bindの設定追加 (named.conf.local)

【追加】の部分から追加します。

hisato@dns09:~$ cat /etc/bind/named.conf.local
// 正引きゾーン
zone "lab.local" {
    type master;
    file "/etc/bind/lab.local.zone";
};

// 逆引きゾーン (192.168.10.x なので 10.168.192.in-addr.arpa)
zone "10.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/lab.local.zone.rev";
};

// 【追加】avi.lab.local は Avi DNS (192.168.49.53) へフォワード
zone "avi.lab.local" {
    type forward;
    forward only;
    forwarders { 192.168.49.53; }; // Avi DNS VSのIP
};
hisato@dns09:~$

これで、既存の環境を壊すことなく、Aviの管理領域だけを切り出すことができます。

DNSSECの無効化

プライベートIPアドレス(192.168.x.x)を持つAviへの転送を成功させるため、DNSSEC検証を無効化します。

hisato@dns09:~$ cat /etc/bind/named.conf.options
acl internal-network {
        192.168.0.0/16;
        10.0.0.0/8;
        localhost;
};

options {
        directory "/var/cache/bind";

        # 問い合わせを受け付ける範囲
        allow-query { internal-network; };

        # 再帰問い合わせ(インターネットへの転送)を許可
        recursion yes;

        # 上位DNSサーバー(Google DNSなど)
        forwarders {
                8.8.8.8;
        };

        # Ubuntu標準の設定
        dnssec-validation no; //ここを追加
        listen-on-v6 { any; };

        # IPv4のリスン設定 (any または自身のIP)
        listen-on port 53 { any; };
};

bindを再起動して反映

sudo systemctl restart bind9
sudo rndc flush  # キャッシュクリアも忘れずに

VSを作るだけで名前解決

最後はVSの作成します。
いつもと手順が異なるのは、VS VIPの作成部分です。
ここで、FQDNを記載していくので見ていきます。

VIPsでのFQDN登録

VS VIPの作成画面で、VIPsをAuto-Allocateで設定したら、その下にDNSの項目があるのでADDをクリックします。

Application Domainの項目で希望するホスト名(ここでは:www)を入力しました。
後ろのサブドメインはあから締め表示されています。(avi.lab.local)
TTLは60としてSAVEをクリックします。

「www.abi.lab.local」のFQDNが反映されたことを確認してSAVEをクリックします。

実際に新しい仮想サービスを作ってみましょう。

VSの作成手順はいつも通り、VIP、Pool、Profileの紐づけを行うだけなので割愛します。
すべての設定が完了しSAVEをクリックします。

この瞬間、裏側で何が起きているかというと...

  1. AviがIPAMから未使用のVIP(192.168.49.104)を払い出す。
  2. 同時に、DNS VSのDNS Recordsに「www.avi.lab.local は 192.168.49.105だよ」というAレコードを登録する。
  3. ロードバランシングを開始する。

動作確認

手元のPCから nslookup してみます。

PS C:\Users\hisato> nslookup www.avi.lab.local. 192.168.10.9
サーバー:  dns09.lab.local
Address:  192.168.10.9

権限のない回答:
名前:    www.avi.lab.local
Address:  192.168.49.104

PS C:\Users\hisato>  <-- 引けた!!

ブラウザからもアクセスしてみましょう。

感動です。
VIPは自動的に採番されるようになっているので、採番された情報とFQDNを自動的にレコード登録してくれるので、DNSサーバーの設定ファイルをいじる必要はありません。
Aviでサービスを作れば、即座に名前でアクセスできるようになります。
これが Software-Defined Load Balancing の真価です。

Avi導入シリーズ:総まとめ

全4回にわたるAvi Load Balancer導入の旅、いかがでしたでしょうか。
最後に、構築した「最強のホームラボLB基盤」のポイントを振り返ります。

第1回:リソースとの戦い

  • 課題:デフォルト設定だとSE(Service Engine)がメモリを100%予約してしまい、ESXiが枯渇する。
  • 解決:「SE Group」のチューニングを実施。メモリ予約を解除し、ラボ用にスペックを絞ることで、省エネ運用を実現しました。

第2回:見えない壁(MTU)との戦い

  • 課題:物理PCからオーバーレイ上のVIPに通信できない。原因はカプセル化によるパケットサイズ超過。
  • 解決:「VyOS」をゲートウェイとして導入。MSS Clamping機能でパケットサイズを強制的に調整し、物理・仮想・オーバーレイの完全な疎通を確保しました。

第3回:鉄壁の守り

  • 課題:公開サーバーへの攻撃が怖い。
  • 解決:「iWAF」をワンクリックで有効化。SQLインジェクションなどの攻撃をエッジで遮断し、可視化する環境を整えました。

第4回:運用の自動化(今回)

  • 課題:DNS登録が面倒。
  • 解決:「DNS連携」により、VIP作成と同時に名前解決を提供。NoOpsな運用フローを確立。

おわりに

NSXがあるならロードバランサもNSXでいいじゃん」
最初はそう思っていましたが、今なら自信を持って言えます。
「Aviはいいです。」

コントローラーを中心とした集中管理、柔軟なスケーリング、リッチな可視化、そしてインフラとの高度な連携。これらは従来のロードバランサアプライアンスでは味わえない体験でした。
少々構築のハードル(特にメモリとMTU!)は高いですが、それを乗り越えた先には、商用クラウドにも負けない快適なアプリケーション配信基盤が待っています。

Avi Load Balancerセキュリティ編 (3) 鉄壁の守り!ワンクリックで有効化する「インテリジェントWAF」でSQLインジェクションを防ぐ

ここまで、導入編、解決編と、ハマリまくってなんとか環境構築をしてきました。
最後はセキュリティです。 自宅ラボでWebサーバーを公開していると、どこからともなく怪しいスキャンが飛んできます。
/?id=1' OR '1'='1 みたいなSQLインジェクション攻撃のログを見ると、背筋が寒くなりますよね。

通常、WAF(Web Application Firewall)を導入しようとすると、専用アプライアンスを買うか、WebサーバーにModSecurityを入れるか...いずれにせよ面倒で高コストです。
しかし、Aviなら「チェックボックス一つ」でWAFになります。
VCF環境における「多層防御」の最前線を、Aviで構築してみましょう。

Avi WAFの「CRS」とは

AviのWAFは、業界標準の OWASP CRS (Core Rule Set) をベースにしています。
要するに、「世界中で流行っている主要なWeb攻撃パターン」の辞書を最初から持っているということです。

自分で正規表現を書いて「この文字列をブロック」なんてやる必要はありません。
SQLインジェクション対策:有効」「XSS対策:有効」。
これだけでいいんです。
この手軽さが、運用エンジニアには涙が出るほど嬉しいです。

WAFプロファイルの作成と適用

WAF Policyの作成

それでは、設定を行っていきましょう。
まずは Templates > WAF > WAF Policy からCREATEをクリックします。

Nameは「Web-WAF-Policy」とし、System-WAF-Profile という雛形があるので、これを選択してProfileを作成します。
Policy Modeが、デフォルトでDetectionとなっていますが、防御モードで動作させたいので「Enforcement」を選択します。

中身を見ると、27Groups, 438 Rulesという大量のルールセットが並んでいます。
最初は誤検知(False Positive)が怖いので、とりあえずデフォルトのままで行きます。
AviのWAFエンジンは優秀で、学習モード(Learning)も持っていますが、今回はシンプルに「既知の攻撃を防ぐ」設定にします。

あとはデフォルトのまま、SAVEをクリックします。

WAF Policyの適用

WAF PolicyはVSの設定画面で、WAF Policyという項目があるので、ここで先ほど作成した「Web-WAF-Policy」を選択するだけです。

作成したプロファイルを、WebサイトのVirtual Service (VS) に紐付けた後、VSの画面に戻ると、Healthスコアの部分が水色で囲まれて盾マークついているのがわかります。
この瞬間、ロードバランサがファイアウォールに進化しました。

攻撃シミュレーション

それでは、攻撃者になりきってWebサーバーを攻撃してみましょう。
Linuxcurl コマンド、またはブラウザを使って、典型的なSQLインジェクションのパターンを含むリクエストを投げます。

攻撃パターン(URLパラメータへの注入)

# 1. 正常なアクセス
# 普通のリクエストは問題なく通るはずです

PS C:\Users\hisato> curl.exe -I http://192.168.49.101
HTTP/1.1 200 OK ←Webサーバーが応答しています
Content-Type: text/html; charset=UTF-8
Content-Length: 3525
Connection: keep-alive
Date: Mon, 29 Dec 2025 01:07:34 GMT
Server: Apache/2.4.37 (Rocky Linux)
Last-Modified: Sun, 28 Dec 2025 03:01:45 GMT
ETag: "dc5-646fa58c00fc0"
Accept-Ranges: bytes

# 2. SQLインジェクション攻撃
# URLに ' OR '1'='1 を付与して認証回避などを狙う典型的な手口
curl.exe -I "http://192.168.49.101/index.html?id=1' OR '1'='1"
# ※URL内のスペースは %20 に置き換えて実行します

PS C:\Users\hisato> curl.exe -I "http://192.168.49.101/index.html?id=1'%20OR%20'1'='1"
HTTP/1.1 403 Forbidden ←「403 Forbidden」 が返ってきました!
Webサーバーに到達する前に、Aviのエッジでリクエストが拒否された証拠です。
Content-Type: text/html
Content-Length: 3945
Connection: keep-alive

攻撃の可視化:WAF Analytics

「ブロックしました」で終わりではありません。
Aviのいいところは「どんな攻撃が来たか」の可視化にあります。
Virtual Services > Web-VS > Logs を開き、右側のフィルタで WAF Groups を選択します。

どのIPからの通信をREJECTしたのかわかるので、対象の通信をクリックします。

詳細を開くとRequest InformationでどのようなURIで攻撃したのかを確認できます。

さらに下にスクロールするとWAF Hitsの下のSIGNATURES(1RULE)が開けます。
内容を確認するとSQLインジェクションをマッチしたことがわかります。

【番外編】エラー画面カッコよくする

標準の設定だと、WAFでブロックされた際にブラウザに表示されるのは味気ないデフォルトのエラーページです。

これではユーザー(あるいは攻撃者?)に対して不親切なので、「セキュリティポリシーによりブロックされました」 ということが明確にわかるカスタムページを設定してみます。

Step 1:カスタムHTMLの用意

Aviでは Error Page Profile を使うことで、特定のエラーコード(今回は403)に対するレスポンスHTMLをカスタマイズできます。
以下のようなHTMLを用意しました。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Access Denied</title>
    <style>
        body { font-family: "Helvetica Neue", Arial, sans-serif; background-color: #f4f6f9; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
        .container { background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); text-align: center; max-width: 500px; border-top: 5px solid #e74c3c; }
        h1 { color: #e74c3c; margin-bottom: 20px; }
        p { color: #555; line-height: 1.6; }
        .info { background: #f8f9fa; padding: 10px; border-radius: 4px; margin-top: 20px; font-size: 0.9em; color: #7f8c8d; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Access Denied</h1>
        <p>お客様のリクエストは、当サイトのセキュリティポリシーによりブロックされました。</p>
        <p>もし誤検知と思われる場合は、以下の情報を添えて管理者までご連絡ください。</p>
        <div class="info">
            <strong>Action:</strong> Blocked by Intelligent WAF<br>
            <strong>Reason:</strong> Suspicious Activity Detected
        </div>
    </div>
</body>
</html>

Step 2:Error Page Profileの作成

Aviのメニューから Templates > Applications > Error Page Profile を開きCreateをクリックします。

名前を WAF-Error-Page とします。
Error Pages セクションで Add をクリック。

「Enable Error Page」にチェックを入れ、「Status Code」に 403 を入力します。
Error Page Body でCREATEクリックし、上記のHTMLコードを貼り付けます。


SAVEを3回クリックして完了です。

Step 3:VSへの紐付け

Applications > Virtual Services で対象のVS (Web-VS) を編集します。
Settings タブ(または Error Page 設定項目)にある Error Page Profile のプルダウンから、先ほど作成した WAF-Error-Page を選択します。

保存します。
これで、WAFに検知された際に表示される画面が、作成したスタイリッシュな警告画面に切り替わります。

Error Pageの確認

ブラウザに「http://192.168.49.101/index.html?id=1' OR '1'='1」を入力してEnterキーを実行すると以下のようなエラー画面が表示されました。
これならアクセス拒否されたのだとわかりますね。

まとめ

今回は、Avi Load Balancerのセキュリティ機能「iWAF」を検証しました。

  • 導入が爆速:VSの設定で有効にするだけ。エージェントも専用機も不要。
  • 鉄壁の防御:OWASP CRSベースで、既知の脆弱性攻撃をほぼカバー。
  • 見える安心感:ログ画面がリッチで、攻撃の内容が手に取るように分かる。

ホームラボで外部公開サーバーを作る際、この機能があるだけで安心感が段違いです。
VyOSで足回りを固め、Aviでセキュリティを固める。これでようやく、安心してアプリを公開できる基盤が完成しました。

Avi Load Balancer解決編 (2) NSXオーバーレイの「通信できない」を救え!VyOS導入で挑むMTU問題とゲートウェイ移行の大手術

前回、Avi Load Balancerを構築し、管理画面上では「All Green」の状態まで持ち込みました。
しかし、物理ネットワーク(自分のPC)から、オーバーレイ上のVIPにアクセスしようとすると、通信がドロップしてしまいました。

原因はやはり 「MTU(パケットサイズ)」 です。 これまで騙し騙しやってきましたが、ここに来て「Catalyst 2960によるL3ルーティングの限界」に直面しました。
今回は、この根深い問題を解決するために、VyOS を導入し、ネットワークトポロジーを刷新する「大手術」の全記録を公開します。

何が起きていたのか?(おさらい)

現象はシンプルかつ致命的でした。

  • Aviのステータス:緑 (正常)
  • オーバーレイ内の通信:OK
  • 物理PC -> VIPへの通信:NG(大きいサイズの情報を取得できない)

原因:1500byte以上のパケットが通信できない

NSXのオーバーレイ通信は、元のパケットに「Geneveヘッダー(約50バイト)」が付与されます。 1500バイトで送られたパケットは 1550バイト になり、物理ネットワーク(MTU 1500)を通れません。
これまで、インターネット出口のルーター NVR510 で無理やりサイズを制限したり、各Linux VMNIC設定(MTU 1440) を書き換えたりして凌いでいました。
しかし、AviのVIPのような「自動生成されるIP」や「物理PCからのアクセス」に対しては、個別にMTUサイズを変更することはできません。

ボトルネックは「Catalyst 2960」

現在、物理と仮想をつなぐゲートウェイCatalyst 2960 が担っています。
ジャンボフレームは9000byteまで対応するよう設定変更していましたが、このスイッチは「パケットの中身を見てサイズを調整する機能(TCP MSS Clamping)」を持っていません。
つまり、TEPの通信を処理することはできるけど、そもそも1500byte以上のパケットをLAN内に転送する際に調整機能はないので、「1500byte以上のパケットをそのまま通そうとして、物理の壁に激突している」 これが真相でした。

解決策:VyOSを「調整役」として召喚する

この状況を打破するには、「パケットの中身をよしなに小さく書き換えてくれる賢いルーター」 が必要です。
手持ちのルータとして、RTX1200、Cisco891FJがありましたが、どちらもMTU 9000byte、TCP MSS Clamping 機能を持っておらず断念。
NVR510を仮想基盤のゲートウェイにまとめようかと思いましたが、設定変更の影響が大きすぎてさすがに無理かなと。
ルータを買ってこようかと思いましたが、年末で配送されるのは年明けになりそう。。。
秋葉原に行くのも面倒なのであきらめちゃおうかと頭をよぎりましたが、ちょうど疎通確認用に稼働させていたOSSのソフトウェアルーター VyOS ならできるんじゃない!?と調べたらTCP MSS Clamping機能を持っていました!!

新・ネットワークトポロジー

ポイントは、オーバーレイネットワークと、物理ネットワークおよびアンダー例の仮想基盤(物理クラスタP-ESXi-MGT)間に、VyOSを配置し、ここでTCP MSS Clamping機能により、1500byte以上の通信が来たら、パケットサイズを小さくするように調整してあげればいいわけです。
よって、Tier-0とCatalyst2960間を接続しているVLAN30にVyOSを割り込ませ中継用セグメント(VLAN29:192.168.29.0/24)を設置しました。
また、クライアントワークロードのVLAN16もここを中継させたいので、Catalyst 2960から「ゲートウェイ(ルーティング)」の役割をVyOSに移行させます。

Catalyst2960のゲートウェイとしての機能をすべてVyOSに切り替えるのは大工事になるし、vMotionなどの通信は、そのままCatalyst2960でスイッチングさせるだけなので、そのままにしておいたほうがいいものもあるので、必要最小限の構成変更としました。

実践!移行の大手術

ここからは、稼働中のネットワークを切り替える緊張の作業です。
なにせ、Tier-0ゲートウェイのデフォルトルートのネクストホップをCatalyst2960からVyOSに切り替えつつ、VyOSとCatalyst2960間にTransit用VLANを追加するので、失敗するとオーバーレイの通信はすべて行えなくなります。変更部分の構成を別にまとめました。

Step 1:VyOSのデプロイと設定準備

VyOSをデプロイし、2つのNIC(eth0:管理用、eth1:データ用)を設定します。
データ用NICは、ESXiの Trunkポートグループ(VLAN 4095) に接続し、複数のVLANを扱えるようにします。

投入するコンフィグの要(かなめ)はここです。
この ip adjust-mss 1400 です。
「ここを通るなら、パケットを1400バイトに減らしてね」と、通信の開始時に全端末へ指令を出してくれます。

# --- 1. システム基本設定 ---
set system host-name 'VyOS-Core'
set system time-zone 'Asia/Tokyo'
set service ssh port '22'

# --- 2. 管理用インターフェース (eth0) ---
# ※既存の管理VLAN(VLAN10)の空きIPを指定 (環境に合わせて変更可)
set interfaces ethernet eth0 address '192.168.10.55/24'
set interfaces ethernet eth0 description 'Management-Network'

# --- 3. データ用インターフェース (eth1) ---
set interfaces ethernet eth1 description 'Trunk-Uplink'
# ※MTUはデフォルト(1500)のままでOKです

# [VLAN 16] 物理VM用ゲートウェイ (Cat2960から引継ぎ)
set interfaces ethernet eth1 vif 16 address '192.168.16.1/24'
set interfaces ethernet eth1 vif 16 description 'Gateway-for-P-ESXi-VMs'
# 【重要】MSS Clamping設定
set interfaces ethernet eth1 vif 16 ip adjust-mss '1400'

# [VLAN 29] Transit (Cat2960との接続用 - 新設)
set interfaces ethernet eth1 vif 29 address '192.168.29.2/29'
set interfaces ethernet eth1 vif 29 description 'Transit-to-Cat2960'
# 【重要】MSS Clamping設定
set interfaces ethernet eth1 vif 29 ip adjust-mss '1400'

# [VLAN 30] NSX Uplink用ゲートウェイ (Cat2960から引継ぎ)
set interfaces ethernet eth1 vif 30 address '192.168.30.1/24'
set interfaces ethernet eth1 vif 30 description 'Gateway-for-NSX-Edge'
# 【重要】MSS Clamping設定
set interfaces ethernet eth1 vif 30 ip adjust-mss '1400'

# --- 4. ルーティング設定 ---
# デフォルトルート -> Catalyst 2960 (Transit側)
set protocols static route 0.0.0.0/0 next-hop 192.168.29.1
# NSXオーバーレイネットワークへのルート -> NSX Edge (VLAN 30経由)
# 管理セグメント
set protocols static route 192.168.40.0/24 next-hop 192.168.30.2
# ワークロードセグメント
set protocols static route 192.168.41.0/24 next-hop 192.168.30.2
# VIPセグメント
set protocols static route 192.168.49.0/24 next-hop 192.168.30.2

★★★この時点ではまだcommitしません★★★
# --- 設定の保存 ---
# commit
# save

Step 2:運命の切り替え(Switchover)

IPアドレスの重複(Conflict)を防ぐため、以下の手順を一気に行います。

  1. Catalyst 2960:VLAN 16, 30 のSVIを shutdown し、GW機能を停止。
  2. Catalyst 2960:VyOSとの接続用 Transit VLAN (29) を作成し、ルートを向ける。
  3. VyOS:待機させていた設定を commit(反映)。

Step 3:動作確認

切り替え完了後、恐る恐る物理PCから AviのVIP (192.168.49.101) へアクセスしました。
「...表示された!!」

Webページがサクサク表示されます。
Pingも落ちません。
VyOSが裏でしっかりとパケットサイズを調整し、NSXのオーバーレイ(Geneve)を通ってもあふれないようにコントロールしてくれています。

暫定対応のお片付け(Cleanup)

VyOSという「恒久対策」が入った今、これまで行ってきた「対症療法」は不要なので、すべて元の状態に戻します。

NVR510の設定戻し

出口ルーターで無理やり行っていた制限を解除し、標準の auto に戻します。

ip lan1 tcp mss limit auto
tunnel select 1
 ip tunnel tcp mss limit auto

これで、NVR510は「普通のインターネットルーター」に戻りました。

Linux VMのMTU戻し

各サーバーで設定していた MTU 1440 設定も不要です。
「MTU 1500」に戻します。

まとめ:VyOSはホームラボの必須科目だった

今回のトラブルシューティングを通じて、以下の教訓を得ました。

  • L3スイッチの限界を知る:Catalystは速いが、パケットの中身までは見てくれない。
  • オーバーレイには「調整役」が必要:GeneveやVXLANを使うなら、MSS Clampingができるルーターゲートウェイに置くのが鉄則。
  • VyOSは偉大:わずかなリソースで、エンタープライズ級の機能(BGP, MSS調整, Zone Firewall)を提供してくれる。

これでようやく、物理・仮想・オーバーレイがストレスなく繋がる 「真のインフラ基盤」 が完成しました。

おまけ

お掃除も終わった後に、WEBサーバーを3台構成にして負荷分散されることを確認しました。




ちなみに、このHTMLは各サーバで以下の「setup_html.sh」を実行すると、ホスト名、IPアドレス、環境情報を取得し、自動でindex.htmlを作成してくれます。
色分けも自動です。

#!/bin/bash

# --------------------------------------------
# 1. 自サーバー・環境情報の動的取得
# --------------------------------------------
HOSTNAME=$(hostname)
IP_ADDR=$(hostname -I | awk '{print $1}')
[ -z "$IP_ADDR" ] && IP_ADDR="127.0.0.1"

# OS情報の取得 (PRETTY_NAME を使用)
OS_INFO=$(grep ^PRETTY_NAME /etc/os-release | cut -d'=' -f2 | tr -d '"')

# Webサーバー情報の取得 (Nginx または Apache)
if command -v nginx >/dev/null 2>&1; then
    MW_INFO="Nginx $(nginx -v 2>&1 | cut -d'/' -f2)"
elif command -v httpd >/dev/null 2>&1; then
    MW_INFO="Apache $(httpd -v | head -n1 | cut -d'/' -f2 | cut -d' ' -f1)"
elif command -v apache2 >/dev/null 2>&1; then
    MW_INFO="Apache $(apache2 -v | head -n1 | cut -d'/' -f2 | cut -d' ' -f1)"
else
    MW_INFO="Unknown"
fi

# IP末尾の下一桁(0-9)からカラーインデックスを作成
IP_LAST_OCTET=$(echo $IP_ADDR | cut -d'.' -f4)
# 末尾一桁を抽出
LAST_DIGIT=$((IP_LAST_OCTET % 10))
COLOR_INDEX=$LAST_DIGIT

# --------------------------------------------
# 2. 目に優しく視認性の高い10色 (Deep & Standard Colors)
# --------------------------------------------
# 輝度を抑えた、インフラ技術者が識別しやすい色相を採用
COLORS=(
    "#2563eb" # 0: Blue (青)
    "#16a34a" # 1: Green (緑)
    "#dc2626" # 2: Red (赤)
    "#d97706" # 3: Amber/Orange (琥珀)
    "#7c3aed" # 4: Violet (紫)
    "#0891b2" # 5: Cyan (シアン)
    "#be185d" # 6: Pink (濃いピンク)
    "#4f46e5" # 7: Indigo (藍)
    "#059669" # 8: Emerald (深緑)
    "#475569" # 9: Slate (濃いグレー)
)
THEME_COLOR=${COLORS[$COLOR_INDEX]}

# --------------------------------------------
# 3. HTMLの生成 (デザインを維持しつつ色を調整)
# --------------------------------------------
OUTPUT_FILE="/var/www/html/index.html"

cat <<EOF > $OUTPUT_FILE
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Verification Node: $HOSTNAME</title>
    <style>
        :root {
            --theme-color: $THEME_COLOR;
            /* 背景はテーマカラーを10%程度の薄さで敷く */
            --theme-bg: ${THEME_COLOR}1a;
            --theme-shadow: ${THEME_COLOR}33;
        }

        body {
            font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
            background-color: var(--theme-bg);
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            color: #1e293b;
        }

        .container {
            background: #ffffff;
            padding: 2.5rem;
            border-radius: 24px;
            box-shadow: 0 20px 60px -10px var(--theme-shadow);
            width: 95%;
            max-width: 600px; /* 改行防止のため余裕を持たせる */
            text-align: center;
            border-top: 12px solid var(--theme-color);
        }

        .status-badge {
            display: inline-block;
            padding: 0.5rem 1.5rem;
            background-color: var(--theme-color);
            color: #ffffff;
            font-weight: 700;
            border-radius: 50px;
            font-size: 0.85rem;
            margin-bottom: 2rem;
            box-shadow: 0 4px 15px var(--theme-shadow);
        }

        h1 {
            font-size: 0.85rem;
            text-transform: uppercase;
            letter-spacing: 0.2em;
            color: #64748b;
            margin: 0 0 2rem 0;
            font-weight: 700;
        }

        .info-group {
            margin-bottom: 1.2rem;
            text-align: left;
            background: #f8fafc;
            padding: 1.2rem 1.5rem;
            border-radius: 12px;
            border-left: 8px solid var(--theme-color);
        }

        .label {
            font-size: 0.75rem;
            color: #94a3b8;
            display: block;
            margin-bottom: 0.4rem;
            font-weight: 600;
            text-transform: uppercase;
        }

        .value {
            font-family: 'Cascadia Code', 'Ubuntu Mono', monospace;
            font-size: 1.6rem;
            font-weight: 700;
            color: var(--theme-color); /* 全ての情報のカラーを統一 */
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .footer {
            margin-top: 2rem;
            font-size: 0.75rem;
            color: #94a3b8;
            padding-top: 1.5rem;
            border-top: 2px solid #f1f5f9;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="status-badge">ACTIVE NODE</div>
    <h1>Infrastructure Verification</h1>

    <div class="info-group">
        <span class="label">HOSTNAME</span>
        <div class="value">$HOSTNAME</div>
    </div>

    <div class="info-group">
        <span class="label">IP ADDRESS</span>
        <div class="value">$IP_ADDR</div>
    </div>

    <div class="info-group">
        <span class="label">OS VERSION</span>
        <div class="value">$OS_INFO</div>
    </div>

    <div class="info-group">
        <span class="label">WEB SERVER</span>
        <div class="value">$MW_INFO</div>
    </div>

    <div class="footer">
        Generated for HomeLab Environment
    </div>
</div>

</body>
</html>
EOF

# パーミッション設定
[ -d "/var/www/html" ] && chmod 644 "$OUTPUT_FILE"
if id "www-data" &>/dev/null; then chown www-data:www-data "$OUTPUT_FILE"
elif id "apache" &>/dev/null; then chown apache:apache "$OUTPUT_FILE"
fi

echo "Success: HTML updated with eye-friendly primary colors (Index: $COLOR_INDEX)."

Avi Load Balancer導入編 (1) メモリを食いつぶす「Service Engine」をコントロール!配置戦略とサイジング

NSXがあるなら、ロードバランサもNSXネイティブ(NSX-T LB)でいいのでは?」そう思うかもしれません。しかし、BroadcomNSXのロード版サー機能を今後廃止予定で、Aviへの移行を推奨していますし、何より「コントローラーが脳となり、SE(実働部隊)をスケールイン/スケーアウトさせる」というアーキテクチャは、一度触ると病みつきになる面白さがあります。
今回は、Aviの導入として、「コンポーネントの配置設計」と、ホームラボにおける「リソース(メモリ)消費対策」について紹介します。

【重要】Avi構築の「順序」を間違えるな!

本題に入る前に、今回の検証で痛感したことを共有します。
今回、Avi、vCenter、NSXの3つを連携し、動的にNSXやvCenterの情報を取得し設定を行っていく機能を実装したのですが、「SEグループの設定」と「ネットワーク設定」**を先に済ませておかないと、最後の最後でエラーになったり、ホストのメモリが食いつぶされたりします。
以下が、「失敗しない構築フロー」です。
特にStep 3と4が鬼門です。

(ここに作成したフロー図を挿入)

配置戦略:脳は物理に、手足は論理に

Aviを導入する際、最初に悩むのが「どこに置くか」です。
今回のラボでは、以下のようなハイブリッド構成を採用しました。

Avi Controller (脳みそ)

  • 配置:物理ネットワーク (VLAN 10) / 192.168.10.41
  • 理由:コントローラーは管理プレーンです。vCenterやNSX Managerと同じ場所に置くのが鉄則。もしNSXオーバーレイが全滅しても、管理画面にはアクセスできないと困りますからね。

Service Engine (手足)

  • 配置:NSXオーバーレイネットワーク
  • SE管理用:Seg-Avi-Mgmt (192.168.40.0/24)
  • VIP用:Seg-Avi-VIP (192.168.49.0/24)
  • 理由:ここがポイントです。Webサーバーたちがオーバーレイ(Tier-1配下)にいるので、LBも同じオーバーレイ空間に置くことで、ルーティング効率が最大化されます。

この構成なら、AviがTier-1ゲートウェイと連携し、「VIPの経路を自動で広報 (RHI)」してくれます。静的ルートを書く必要すらありません。

Service Engine (SE) の「デフォルト」を知る

Aviの設定を進め、NSX-T Cloud Connectorを構成しました。これでAviはvCenter/NSXAPIで繋がり、いつでもSEをデプロイできる状態です。
しかし、ここで Service Engine グループ のデフォルト設定を見てみるとメモリが100%予約されていました。

  • vCPU:1 (または2)
  • Memory:2 GB (以上)
  • Reservation:有効 (100%予約)

AviのSEは、パフォーマンスを保証するために、割り当てられたメモリを「ハイパーバイザー側で100%予約」しようとします。
つまり、オーバーコミットが効きません。いくらメモリ48GB積んだNested ESXiホストとはいえ、スカスカのロードバランサにリソースを占有されるのは、自宅ラバーの美学に反します。

自宅ラボ専用「Homelab-Group」を作る

デフォルト設定を使うのはやめて、ラボ用にチューニングしたSEグループ「Homelab-Group」を作成します。
VS(仮想サービス)を作る前に、必ずこれを実施してください。 後から変更するのは大変です。

リソースの緩和:予約を外せ!

「基本設定」タブでスペックを定義しますが、最重要なのは 「詳細 (Advanced)」 タブです。
ここの 「Memory Reserve (メモリ予約)」 のチェックを外します。
これで、ESXi側では「使った分だけ」メモリを消費するようになります。
スペック自体も、ラボのトラフィック量なら 1 vCPU / 2 GB RAM で十分お釣りが来ます。

配置モード:Elastic HA (Active/Active)

可用性モードは Elastic HA 一択です。
これは「必要になったらSEを追加でデプロイする(スケールアウト)」方式。普段は最低限の台数で運用し、負荷が高まったら勝手に増える。クラウドっぽくてカッコいいし、リソース効率も最高です。

配置場所(Scope)の指定:忘れがちな重要設定

ここでも少しハマりました。スペックだけ下げて保存しようとしても、いざデプロイする段階で「どこにVMを作ればいいか分からない」状態になります。
「Scope」設定で、以下を明示的に指定する必要があります。

  • vCenter:登録済みのVCを選択
  • Host/Cluster:WLDクラスタを選択
  • Data Store:SEを配置するデータストア(余っているSATA SSD領域などを活用!)
ネットワーク設定と「IP枯渇」の罠

SEの準備ができたら、次はネットワークです。ここにも落とし穴がありました。

Aviには「Auto-Allocate(VIPの自動払い出し)」という便利な機能がありますが、これを使うには下準備が必要です。
単にネットワークセグメント(Seg-Avi-VIP)をAviに教えるだけでは不十分で、「Static IP Pool」を定義しないと、以下のエラーが出ます。

Error: Missing IP address

私はこれに遭遇し、「自動って言ったじゃないか!」と画面に向かってツッコミました。
「Network」設定画面で、VIPとして使って良いIP範囲(例: 192.168.49.100-199)をプールとして登録することで、初めて自動払い出しが可能になります。

以上のことを踏まえて、環境を構築していきます。

事前準備

Aviのコントローラーをデプロイする前に、受け入れ環境を整えます。

セグメントの作成

NSX Managerにて、AviのService Engine(SE)が接続するためのセグメントを作成します。

  • Seg-Avi-Mgmt:SEの管理インターフェース用 (192.168.40.0/24)
  • Seg-Avi-VIP:ロードバランス対象のVIP用 (192.168.49.0/24)

これらはTier-1ゲートウェイに接続しておきます。

コンテンツライブラリの作成

vCenterにて、AviがSEのイメージファイル(OVA)を保存するための「コンテンツライブラリ」を作成します。
名前は「vcsa-liblary」などとし、ローカルストレージを指定して作成しておきます。Aviはここに自動的にSEのテンプレートをアップロードします。

コントローラーのデプロイ

ダウンロードしたAvi ControllerのOVAファイル(controller-30.1.2-9093.ova)をvCenterにデプロイします。

コントローラーのネットワークは、物理ネットワークの管理用(PG-MGMT:192.168.10.0/24)を指定します。

コントローラー用のIP設定を行います。


OVAファイルの読み込みと起動で約10~15分ぐらいまって、「https://192.168.10.41」or「https://avi41.lab.local/」にアクセスすると、adminユーザーのパスワード設定画面が表示されるので入力し、adminアカウントを作成します。

その後、DNS Resolverの設定では、192.168.10.9を指定します。

Email/SMTPは「None」を指定します。

Multi-Tenantの設定はデフォルトのままSAVEをクリックします。

これでデプロイは完了しAviの管理画面にログインできます。

初期設定

ライセンス登録

まず最初にEnterprise (Evaluation) ライセンスの登録を行います。
Administration > Settings > Licensingから、Licensingの横にある歯車ボタンをクリックします。

「Enterprise with Cloud Services Tier」から「Enterprise Tier」へ変更しSAVEをクリックします。

そうすると、ライセンスキーを入力する画面が表示されるので、VCFで取得したライセンスを入力してApply Keyをクリックします。

デフォルトだとEvalというService Coreが20で1か月有効なライセンスと、TrialというService Coreが2つで10年間有効なライセンスに加え、VCFでライセンス申請した日から1年間有効なService Coreが12あるライセンスが追加されます。

認証情報の登録

続いて、この後設定するNSX、vCenterのCredential情報をあらかじめ登録しておきます。

まずは、NSX Managerのログイン情報を登録します。

さらに、vCenterのログイン情報も登録します。

登録が完了しました。

Cloudの設定

ここから、クラウドの設定をしていきます。
以前22.1.7のAviを構築したときは一切連携をしない「No Orchestrator」を選択しましたが、今回はNSX連携を行うので「NSX Cloud」をクリックします。

ここでは、以下の設定を行います。

  • General

Name:Homelab
Type:NSX Cloud
Object Name Prefix:Homelab

「CHANGE CREDENTIALS」をクリックし、NSX Managerの情報を入力します。


Management Networkは、オーバーレイの「nsx-overlay-transportzone」、「T1-GW-01」、「Aeg-Avi-Mgmt」を選択します。

Data Network Segmentは、オーバーレイの「nsx-overlay-transportzone」、「Aeg-Avi-VIP」を指定してSAVEをクリックします。

この時点では、まだ、IPAMを作成していないので登録はしません。
IPAMはCloudの設定をしてからでないと作成できないため後で設定します。

IPAMの登録

VIPの自動払い出しを行うためのプロファイルを作成します。
Templates > Profiles > IPAM/DNS Profiles にて Create > IPAM Profile を選択します。

ここで以下の情報を入力しSAVEをクリックします。

  • Name:HomeLab-IPAM
  • Cloud:Homelab
  • Usable Networks:Seg-Avi-VIP


Service Engine Groupの作成

続いて、自動的に作成されるService Engineの設定を行っていきます。
Infrastructure > Cloud Resources > Service Engine Group を開き、Select Cloudから前で作成している「Homelab」をクリックします。
デフォルトだと「Default-Cloud」が表示されており、そのまま作成を進めると、Service Engineが正常にデプロイされず削除されてしまうので間違えずに選択してください。

名前を「Homelab-Group」で入力します。

Placementでは、以下の設定を行います。
ここでは、Service Engineは最大10台まで展開され、すべてActiveで動作します。
さらに、Distributedを選択しているため、Virtual Serviceは最低2台のSEに分散配置されます。

  • High Availability Mode:Active/Active
  • Number of Service Engines:10
  • Virtual Service Placement Across Service Engines:Distributed
  • Scale per Virtual Service:Minimumを2、Maximumを2


Resourcesでは、作成されるService Engineのリソースを決定します。
ここでポイントなのが、Enable memory Reserveのチェックを外すことです。
ここにチェックが入っていると、VSの負荷状況にかかわらず最初から100%メモリを確保するため、あえて外しておきます。
SEのScaleの数にもよりますが、ホームラボの環境ではメモリ節約は重要なのでここはチェックを外しましょう。

続いてScopeでvCenterの情報を入力するためADDをクリックします。

vCenter Serverは、CloudでNSX、vCenter情報を入力しているので、プルダウンから表示されているものを選択します。
Service Engineの配置クラスタについては、オーバーレイ上のvSANとするため以下の設定を行い、SAVEをクリックします。

  • Host/Cluster Scope Service Engine Within:Cluster
  • Cluster:Include > N-ESXi-WLD
  • Data Store Scope for Service Engine Virtual Machine:Shared
  • Data Store:Include > vsanDatastore



それ以外は、デフォルトのままSAVEをクリックします。

Networkの設定変更

次は、SEのネットワーク設定です。
すでにCloudのHomelabで設定したManagement NetworksとData Networksの設定からネットワークの情報は自動的に表示されていると思います。
ただ、どちらのネットワークもサブネットから払い出すIPアドレスの範囲が未設定であるため追加していきます。
Seg-Avi-Mgmtの画面右端の鉛筆マーク編集ボタンをクリックします。

SubnetsにあるADDボタンをクリックします。

それぞれ以下の情報を入力しSAVEをクリックします。
なお、Subnet Prefixの情報を正しく入力しないと、その下にあるStatic IP Rangeが入力できないので注意してください。

  • Subnet Prefix:192.168.40.0/24
  • Static IP Range:192.168.40.101-192.168.40.120


IPv6は不要なのでチェックを外しSAVEをクリックします。

設定が反映されたので、同様にSeg-Avi-VIPも設定を行います。

Seg-Avi-VIPの設定は以下のようになります。

両方とも設定すると以下のように20個のIPが確保されます。

VRF Contextの設定変更

続いて、VRFの設定です。
Select Cloudから前で作成している「Homelab」をクリックします。
そうすると2つのVRFが表示されています。

先ほどのネットワークの設定を確認するとわかりますが、管理用ネットワークとVIP用ネットワークが異なる2つのVRFにそれぞれ紐づいています。
VRFは、論理的にネットワークやルーティング設定を分け、個別に管理する機能で、VRFが分かれているとルーティングテーブルも個別に設定することになります。
現在はこのように紐づいています。

VRF Network 用途 通信の範囲
global 192.168.40.0/24 SEの管理用ネットワーク Avi Controllerや管理系SVとの通信
T1-GW-01 192.168.49.0/24 VIP用ネットワーク 不特定のクライアントからアクセス

ただし、どちらのネットワークもルーティング設定されていないため、セグメントを超えることができません。
なので、デフォルトルートを設定していきます。
globalの画面右端の鉛筆マーク編集ボタンをクリックします。
Static RouteのSubnetsでADDボタンをクリックし以下の情報を入力します。

  • Gateway Subnet:0.0.0.0/0
  • Next Hop:192.168.40.1 ←このネットワークのGWはNSXのT1GWとなっています


反映されるとStatic Routeに「1」と表示されます。

同様にT1-GW-01のVRFも設定していきます。

IPAMの修正

NetworkとVRFの設定が完了したら再度IPAMの設定に戻ります。
右端の編集ボタンをクリックします。

HomeLab-IPAMでCloud設定は行っていましたが、設定が外れているので、再度設定します。
また、Usable NetworksにSeg-Avi-VIPの表示が見えていますが、ここも再選択するとIPアドレスまで表示されるようになるのでプルダウンリストから再度設定します。

再設定後は以下のように表示されるのでSAVEをクリックして完了です。

CloudのIPAM登録

ここまで実施してやっと、CloudのHomelabでIPAMの選択ができます。
Homelabの右端にある編集ボタンをクリックします。

IPAM/DNSにあるIPAM Profileで、作成した「HomeLab-IPAM」を選択しSAVEをクリックします。

これで「下準備」はすべて完了です!

ロードバランスの設定

いよいよアプリケーションを公開します。
ここからは、1台のWebサーバーのフロントに負荷分散用のVIPを設定し、紐づけを行っていきます。

VIPの作成

まずは、VIPを作成していきます。
Applications > VS VIPs からCREATEをクリックします。

Nameを「WEB-VIP」とし、CloudとVRF Contextを以下ので設定します。

  • Cloud:Homelab
  • VRF Context:T1-GW-01


VIPsのADDをクリックします。

VIPの設定画面で以下の項目を選択し、SAVEをクリックします。

  • Private IP:Auto-Allocate
  • IP Protocol:V4 Only
  • VIP Address Allocation Network:Seg-Avi-VIP - 192.168.49.0/24
  • IPv4 Subnet:192.168.49.0/24


設定が反映されたことを確認してSAVEをクリックします。

設定が完了すると、自動的にVIPを払い出してくれます。
今回は、192.168.49.101が採番されました。

Poolの作成

続いてPoolの作成です。
Applications > PoolsからCREATE POOLをクリックします。

Nameを「WEB-Pool」とし、CloudとVRF Contextを以下ので設定します。

Serversで負荷分散対象の「192.168.41.21」を入力しADDをクリックします。

Serversに入力したサーバーが反映されるので、右端の編集ボタンをクリックします。

Hostnameを「seg14-web01」に変更し、Portを「80」と入力しSAVEをクリックします。


Health Monitorでは、デフォルトで定義されている「System-HTTP」を選択しSAVEをクリックします。

登録が完了し設定内容が表示されました。

VSの作成

準備が整ったので最後に、Virtual Service(VS)を作成していきます。
Applications > Virtual Service からCREATE VIRTUAL SERVICEをクリックし、Advanced Setupをクリックします。

Select Cloudで「Homelab」を選択します。

Select VRF Contextで「T1-GW-01」を選択します。

以下の項目を選択しNextをクリックします。

  • Name:WEB-VS
  • VS VIP:WEB-VIP
  • TCP/UDP Profile:System-TCP-Proxy
  • Application Profile:System-HTTP
  • Services:80
  • Pool:WEB-Pool


正常なログおよびヘッダー情報も記録したいので以下の項目にチェックを入れます。

  • Log all headers:有効
  • Non-significant logs:有効


最後にSerivce Engine Groupは「Homelab-Group」を選択しSAVEをクリックします。

初回はSEのデプロイを待つ

Serivce Engineが1台もデプロイされていない状態だと、VSを作成するとコンテンツライブラリにあるSerivce EngineのOVFイメージからデプロイを開始します。

自動的に「Homelab_Avi-se-jmnew」というSEを設定しパワーオンします。

起動すると、Infrastructure > Cloud Resources > Service Engine にデプロイされたSEが表示され、Initializingとなります。
数分待つとStatusが「UP」となり登録が完了します。

そして2台目がデプロイされます。

Avi Controllerに戻り、VSのステータスを確認します。
SEが起動し、コントローラーと通信できれば、VSのステータスが赤から 緑 (Up) に変わります。


動作確認

無事 Green になりました。
割り当てリソースも 1vCPU / 2GB RAM。予約も入っていません。
これならProDeskのリソースを圧迫せずに、複数のVSをガンガン立てられそうです。

実際にクライアントから、「http://192.168.49.101」にアクセスし無事ページが表示されました。

Logsを確認し、クライアント、Avi、Webサーバと接続しResponseを返していることが確認できました。

まとめ

手順としては順番に紹介しましたが、リソースを作成していると、事前準備ができておらずやり直しを何度も繰り返しました。
また、IPが自動的に採番されずにハマってしまいパケットキャプチャなどもしましたが、いくつかの落とし穴を回避し、ようやくエコなSE基盤ができあがりました。

  • SEグループ作成が先、VS作成は後!
  • メモリ予約はOFFにし、配置スコープ(Scope)を忘れない!
  • IPプールを設定しないと自動払い出しは動かない!

この3点を守れば、Aviはホームラボの強い味方になります。
「脳(Controller)」は物理ネットワークでどっしりと構え、「手足(SE)」はオーバーレイネットワーク内で必要に応じて増減する。この柔軟性がAviの魅力です。

さて、ここまできれいにまとまったかのように見えますが、WebページがNginxのデフォルトだと味気ないなと思い、自作のHTMLに差し替えたところ、Aviの画面では「UP(緑)」なのに、物理PCからはタイムアウトが発生。
Pingを打ってみると、通るけれどWebページは表示されない。
「またか...」 そう、これは以前 dnf update で苦しめられた 「MTUとパケットサイズ」 の問題がプンプンです。
ここからトラブルシューティングに1日費やし、ネットワーク構成の大幅変更になる話は次回紹介します。

オーバーレイのVMでパッケージインストールが固まる怪奇現象!犯人は「オーバーレイの50バイト」とMTUだった

NSX環境構築も終わり、オーバーレイ上のLinux VMでパッケージをアップデートしようとした時のことです。
dnf install bash-completion を実行した瞬間、プログレスバーが止まり、そのままタイムアウト…。

「あれ? インターネットには繋がっているのに?」

pingは通る。でも、大きなデータのダウンロードだけが失敗する。
この「ホームラボあるある」な挙動の裏には、仮想化特有の「パケットサイズの壁」が潜んでいました。
今回は、バイト単位の計算で原因を突き止め、物理ルーターYamaha NVR510)で解決するまでの全記録を共有します。

ネットワーク構成

ホームラボの構成は以下となっています。
今回、アップデートの通信ができなかったのは、NSXオーバーレイNWの192.168.41.0/24のセグメントでした。

発生した症状:特定の通信だけが「死ぬ」

オーバーレイセグメント(NSX上の仮想ネットワーク)に配置したVMで、以下の現象が発生しました。

  • pingGoogle DNS等):正常に応答あり
  • dnf upgrade / yum update:ミラーサイトへの接続までは行くが、ダウンロード開始直後にタイムアウト
  • SSH経由のvi操作:閲覧はできるが、編集モードで文字を入力するとフリーズする

「通信はできているのに、大きなデータだけ通らない」。
これはネットワークエンジニアにとって「MTU(Maximum Transmission Unit)問題」を疑う典型的なサインです。

[root@web01 ~]# dnf install bash-completion
^CRocky Linux 8 - AppS     [   ===              ] ---  B/s |   0  B     --:-- ETRocky Linux 8 - AppStream                       0.0  B/s |   0  B     00:36
Errors during downloading metadata for repository 'appstream':
Curl error (28): Timeout was reached for https://mirrors.rockylinux.org/mirrorlist?arch=x86_64&repo=AppStream-8&countme=1 [Operation timed out after 30000 milliseconds with 0 out of 0 bytes received]
エラー: repo 'appstream' のメタデータのダウンロードに失敗しました : Cannot prepare internal mirrorlist: Interrupted by signal

徹底調査:パケットの「限界」はどこか?

どこでパケットが詰まっているのか調べるため、ping コマンドでパケットサイズ(ペイロード)を1バイトずつ変えながら「通るギリギリのサイズ」を探ります。 (※ -M do オプションでフラグメント禁止を指定するのがポイントです)

[root@web01 ~]#
[root@web01 ~]# ping -c 3 -M do -s 1415 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 1415(1443) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
[root@web01 ~]#
[root@web01 ~]# ping -c 3 -M do -s 1414 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 1414(1442) bytes of data.
1422 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=12.9 ms
1422 bytes from 8.8.8.8: icmp_seq=2 ttl=117 time=13.9 ms
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 12.854/13.398/13.943/0.556 ms
[root@web01 ~]#

調査の結果、「1414バイト」が運命の境界線であることが判明しました。
たった1バイトの違いで、通信がドロップされていたのです。

原因解明:なぜ「1414バイト」が限界だったのか?

なぜ 1414 という中途半端な数字が限界だったのでしょうか?
これを理解するには、「イーサネットの標準」と「自宅回線の現実」、そして**「NSXのオーバーヘッド」**という3つの要素を計算する必要があります。

前提知識:1500バイトと1492バイトの壁

通常、LANケーブル(イーサネット)を通れるパケットの最大サイズ(MTU)は 1500バイト と決まっています。
しかし、日本の多くの家庭用光回線フレッツ光など)では、PPPoE という接続方式を使う際に、ユーザー認証などの情報を付加するために 8バイト ほどのスペースを使います。

  • 標準的なMTU:1500バイト
  • PPPoEのオーバーヘッド:-8バイト
  • 自宅回線の限界(MTU):1492バイト

つまり、私たちの家のネット回線は、会社のLANなどと違って「少しだけ通り道が狭い」のです。ここにNSXの事情が加わります。

今回のパケット計算式

NSXのオーバーレイネットワークでは、パケットを仮想空間で運ぶために「Geneve(ジュネーブ)」という技術でカプセル化(ラッピング)します。この包装紙のサイズが 約50バイト あります。
以下が、今回の通信の内訳です。

サーバーが出した時点のパケット

VMが送信したデータに、基本的なヘッダーが付与されます。
ICMPデータ(ペイロード): 1414 byte
IPヘッダー: 20 byte
ICMPヘッダー: 8 byte
小計:1442 byte

NSXオーバーレイを通る時(カプセル化

元のパケット: 1442 byte
Geneveヘッダー(NSXの包装紙): +50 byte
合計:1492 byte

インターネットの出口(物理ルーターの限界)

自宅回線のMTU上限: 1492 byte

結論:計算は嘘をつかない

1414バイトで送った場合:合計 1492 byte(ギリギリ通過!)
1415バイトで送った場合:合計 1493 byte(出口でドロップ!)

普段は気にならない「自宅回線の-8バイト」と「NSXの+50バイト」が組み合わさった結果、合計サイズが物理回線の許容量を超えてしまい、パケットが破棄されていたのです。

トラブルシュート:NSXで直すべきだが…?

原因がわかれば対策はシンプルです。
「通れるサイズになるようにパケットを小さく調整(MSS Clamping)」すれば良いのです。

本来、この設定は仮想ネットワークの出入り口である NSX Tier-0 または Tier-1 Gateway で行うのが王道です。
Gateway Firewall」や「Segment Profile」の設定で TCP MSS Clamping を設定しようと、NSX 4.2.x のUIをくまなく探しましたが見当たりませんでした。
VPNIPsecセクションで、MSS Clampingを有効にして、MSSを設定することができるのですが、今回はVPN通信ではありません。

過去のバージョンでは設定箇所が明確でしたが、UIの変更により設定への到達が難解になっていました(あるいは、特定のプロファイル設定が必要で即座に見つけられませんでした)。
ホームラボの検証を進めるのが最優先事項のため、今回はNSX側での対処を一旦ペンディングとしました。

最終解決:物理ルーター「NVR510」で一括制御

パケットが通る経路上のどこかでサイズを制限できれば問題は解決します。
そこで、インターネットへのラストワンマイルを担う物理ルーターYamaha NVR510 で対応することとしました。

NVR510側で、「ここを通るTCP通信の最大サイズ(MSS)」を強制的に書き換える設定を投入します。

計算式:

ターゲットとするMTU: 1442 (物理1492 - Geneve 50)
TCP/IPヘッダー分: -40 (IP 20 + TCP 20)
設定すべきMSS値: 1402

NVR510への設定コマンド:

# LAN側インターフェースとトンネルインターフェースの両方に適用
ip lan1 tcp mss limit 1402
tunnel select 1
 ip tunnel tcp mss limit 1402
save

設定変更後の確認

設定変更後に、再度アップデートコマンドを実行しました。
すでに1回実施しているのでアップデートするものはありませんが、コマンドは正常終了しました。

[root@web01 ~]#
[root@web01 ~]# dnf -y upgrade
Last metadata expiration check: 2:30:19 ago on Sat 27 Dec 2025 12:33:07 AM EST.
Dependencies resolved.
Nothing to do.
Complete!
[root@web01 ~]#

インバウンド通信も不安定? 最終手段はサーバー設定

NVR510での対策で dnf などの外向き通信(アウトバウンド)は可能になりましたが、実はその後、外部からサーバーへアクセスするインバウンド通信においても若干の不安定さが残る現象に遭遇しました。

ルーターでのMSS調整(TCP MSS Clamping)は強力ですが、あくまでTCP通信の「折衝」に介入するものです。
サーバーのネットワークインターフェース(NIC)自体は「自分は MTU 1500 で送れる」と信じ込んでいるため、UDP通信や特定の条件下では依然としてパケットサイズの不整合が起きる場合があります。
結局、物理的な解決策として、各LinuxサーバーのNIC設定で MTU を小さく設定する対応も実施しました。

[root@web03 ~]# nmcli connection show
NAME   UUID                                  TYPE      DEVICE
ens33  1d532b13-f536-4c30-8956-76c69ff7c229  ethernet  ens33
[root@web03 ~]#
[root@web03 ~]# nmcli connection modify ens33 802-3-ethernet.mtu 1440
[root@web03 ~]#
[root@web03 ~]# nmcli connection up ens33
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/2)
[root@web03 ~]#
[root@web03 ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:96:e2:6e brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.16.3/24 brd 192.168.16.255 scope global dynamic noprefixroute ens33
       valid_lft 28795sec preferred_lft 28795sec
    inet6 fe80::250:56ff:fe96:e26e/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
[root@web03 ~]#

まとめ:ホームラボ構築の教訓

  • 「1500バイト」は当たり前じゃない

自宅回線(PPPoE等)を使う場合、MTUは1492バイト(あるいはそれ以下)になっていることを意識しましょう。

  • カプセル化は「パケットサイズは増える」と認識しておく

NSXなどのオーバーレイ技術を使うと、必ずヘッダー分(約50バイト)パケットが太ります。その分、中身を減らす必要があります。

  • 困ったら「出口」で制御する

NSX側で設定が見つからない場合、物理ルーター側でMSS制限をかけるのも有効な手段です。

もし同じようにNSX環境で「通信はできるのにWebが開かない」「アップデートが落ちる」という現象に遭遇した方は、ぜひ「パケットの太り過ぎ」を疑ってみてください!

【NSX-T API活用】設定内容を「HTMLレポート」で可視化するPythonスクリプトを作ってみた(構成管理・Diff・移行に便利!)

NSXのオーバーレイネットワーク、分散ファイアウォール(DFW)、DHCPなどの基盤構築が完了しました。
本来なら次はロードバランサ(Avi Load Balancer)の構築に進む予定でしたが、設定が増えてくるにつれて「ある悩み」が出てきました。
NSXの設定全体を、もっと見やすく一覧化したい…!」
NSX ManagerのGUIは優秀ですが、ファイアウォールのルールが数百行に及んだり、多数のオブジェクト(グループやサービス)が入り組んでくると、「全体としてどうなっているか」を把握するのが辛くなってきます。画面キャプチャでドキュメントを残すのも限界がありますし、何より「昨日と今日で何が変わったか(Diff)」を取るのが困難です。

そこで今回は、Pythonを使ってNSXAPIを叩き、設定情報を取得して「見やすいHTMLレポート」を自動生成するツールを作成しました。
これが想像以上に便利で、「構成管理」や「移行時の現状調査」にも使える強力なツールになったので、コードのポイントと共に紹介します。

作ったものの概要

今回作成したツール(NSXFW_Report.py)の仕組みは以下の通りです。

  • Python から NSX Policy API を叩く。
  • 分散FW、GWファイアウォール、グループ、セグメントなどの情報を JSON で取得。
  • 取得したデータ内の「ID(UUID/パス)」を「名前(Display Name)」に変換(ここが重要!)。
  • Jinja2 テンプレートエンジンを使って、HTMLファイル にレンダリング

ファイル

ファイル名 内容
NSX-T Firewall Report Generator_12.2.0.py スクリプト本体
nsx_raw_data_debug_20251223_232101.json APIで取得したJSONファイルのサンプル
NSXFW_HomeLab_20251223_232101.html 取得したJSONファイルをもとに生成したHTMLファイル

以下に公開しているので、自由にご利用ください。
NSX_HTML化 - Google ドライブ

使い方

Pythonのインストール

事前にPythonのインストールを行ってください。
GUIでインストールする際には、Pathを通しておいてください。
その後、pip install requests を実行してください(最初の1回だけでOK)

アカウント・環境情報の設定

スクリプトの冒頭で、アカウント・環境情報の設定をしてください。
私の環境では、このように設定しています。

NSX_MANAGER_URL = "https://nsx21.lab.local"
USERNAME = "admin"
PASSWORD = "VMwarevmware1!"

Pythonの実行

スクリプト本体をダブルクリックするか、コマンドプロンプトから実行してください。
正常終了すれば、最後に「処理完了: ファイルを出力しました」と表示され、スクリプト本体と同じフォルダにHTMLファイルが出力されます。
また、取得した情報もJSONで出力します。
もし、この情報が不要であれば、デバッグ設定で、DEBUG_MODE = False としてください。
うまく動作しないときは、スクリプトJSONファイルをAIに読み込ませると、いい感じに修正してくれると思います。

PS C:\work\01_HTML化> python .\NSXFW_Report_v11.1.py
[2025-12-23 23:00:14] [INFO] === NSX-T Firewall Report Generator v11.3.0 (Fix: CIDR & Dups) ===
[2025-12-23 23:00:14] [INFO] Env: NSX-T Report: Home Lab (On-Prem)
[2025-12-23 23:00:14] [INFO] NSX-T APIへの接続を開始します...
[2025-12-23 23:00:14] [INFO] tier-1s の一覧を取得中: https://nsx21.lab.local/policy/api/v1/infra/tier-1s
[2025-12-23 23:00:14] [INFO]   -> 1 個の tier-1s が見つかりました。
[2025-12-23 23:00:14] [INFO] tier-0s の一覧を取得中: https://nsx21.lab.local/policy/api/v1/infra/tier-0s
[2025-12-23 23:00:14] [INFO]   -> 1 個の tier-0s が見つかりました。
[2025-12-23 23:00:14] [INFO] GW FW処理中: T0-GW-01 (tier-0s)...
[2025-12-23 23:00:14] [INFO] GW FW処理中: T1-GW-01 (tier-1s)...
[2025-12-23 23:00:14] [INFO] 共通リソース取得中: Default Domain Groups ...
[2025-12-23 23:00:14] [INFO]   -> 成功: 11 件のグループ定義
[2025-12-23 23:00:14] [INFO] 共通リソース取得中: Services ...
[2025-12-23 23:00:14] [INFO]   -> 成功: 415 件のサービス定義
[2025-12-23 23:00:14] [INFO] 共通リソース取得中: Global Segments ...
[2025-12-23 23:00:14] [INFO]   -> 成功: 2 件のセグメント定義
[2025-12-23 23:00:14] [INFO] ★デバッグ用JSONファイルを出力しました: nsx_raw_data_debug_20251223_230014.json
[2025-12-23 23:00:14] [INFO] HTMLレポートの生成を開始します...
[2025-12-23 23:00:14] [INFO]   -> ページ構築中...
[2025-12-23 23:00:14] [INFO] 処理完了: ファイルを出力しました -> NSXFW_HomeLab_20251223_230014.html
[2025-12-23 23:00:14] [INFO] 総取得ルール数: 5 件
[2025-12-23 23:00:14] [INFO] 出力先: C:\work\01_HTML化\NSXFW_HomeLab_20251223_230014.html

処理が完了しました。Enter キーを押して終了してください...
PS C:\work\01_HTML化>

生成されるHTMLレポート(イメージ)

実際にホームラボ環境から生成したHTMLがこちらです。 ネイティブのGUIよりも情報が凝縮されており、検索もテキストコピーも容易です。

このツールのメリット

単に表示するだけならGUIでも良いのですが、HTML化(テキスト化)することで以下のメリットが生まれます。

  • 「差分(Diff)」が取れる

HTML(テキスト)なので、設定変更前と後でスクリプトを実行し、WinMerge や diff コマンドにかければ、「どのルールが追加・削除されたか」が一発で分かります。これはGUIでは不可能です。

  • オフラインで閲覧可能

HTMLファイル単体で動作するため、NSX Managerにアクセスできない環境でも設定内容を確認できます。客先への納品ドキュメントとしても使えます。

  • 生データ(JSON)も手に入る

デバッグモードで実行すれば、加工前のRaw JSONデータも出力されます。これは将来的な**移行(Migration)**や、バックアップデータとしても非常に有用です。

コードの解説(要点)

スクリプト全体は長くなるので、ロジックの要点をピックアップして解説します。

NSX APIへの接続とデータ取得

requests ライブラリを使用して、NSX ManagerのPolicy APIへアクセスします。 認証はBasic認証を使用し、SSL証明書検証はラボ環境なのでスキップしています。

# APIクライアントの一部抜粋
class NSXClient:
    def get(self, endpoint):
        url = f"https://{self.nsx_manager}{endpoint}"
        response = requests.get(
            url,
            auth=(self.username, self.password),
            verify=False # ラボ用: 証明書検証無効
        )
        return response.json()

# 取得する情報の例
endpoints = {
    "groups": "/policy/api/v1/infra/domains/default/groups",
    "services": "/policy/api/v1/infra/services",
    "dfw_policies": "/policy/api/v1/infra/domains/default/security-policies",
    # ... その他、GW FWやSegmentsなど
}

「パス」から「名前」への変換(名前解決)

APIから返ってくるデータは、基本的に /infra/domains/default/groups/web-group のような「パス」で表現されています。 これを人間が見やすい「グループ名(例: Web-Servers)」に変換する処理を入れています。これがないと、レポートがパスだらけで読みにくくなってしまいます。

# パスと表示名のマッピング辞書を作成
self.path_to_name = {}
for group in groups_data.get('results', []):
    self.path_to_name[group['path']] = group['display_name']

# 実際の変換ロジック(例)
def resolve_name(path):
    return self.path_to_name.get(path, path) # 名前があれば名前を、なければパスをそのまま返す

HTMLへのレンダリング(Jinja2)

データの整形が終わったら、Pythonのテンプレートエンジンである Jinja2 を使ってHTML化します。 CSSもHTML内に埋め込んでいるため、単一のファイルとして完結するようにしています。

# テンプレートにデータを渡してレンダリング
template = Template(html_template_string)
html_output = template.render(
    timestamp=timestamp,
    nsx_manager=args.nsx_manager,
    dfw_policies=processed_data['dfw_policies'],
    # ... 他のデータを渡す
)

実際の出力結果

スクリプトを実行すると、以下のようにセクションごとに整理された情報が出力されます。

「Source」「Destination」「Service」「Action」が一覧化されています。 特にグループの中身(IPアドレスやタグ条件)も、別セクションの「Groups」と突き合わせることで容易に確認できます。

ID Name Source Destination Service Action
1020 Allow Web to DB Grp-Web Grp-DB PostgreSQL ALLOW
1021 Block Any Any Any Any DROP
  • グループ定義 (Inventory Groups)

どのグループに、どんなIPアドレスやタグが紐付いているかも一目瞭然です。

Group Name Criteria / Members
Grp-Web Tag: Web-Tier
Grp-DB Tag: DB-Tier

まとめ

NSXを運用していく上で、「今の設定状態」を瞬時にスナップショットとして残せるこのツールは、ホームラボの運用を劇的に楽にしてくれました。

  • 作業前にスクリプトを実行(Before)
  • 設定変更作業
  • 作業後にスクリプトを実行(After)
  • Diffツールで比較して、意図通りの変更か確認

といった、プロフェッショナルな運用フローが個人環境で実現できます。
APIを活用することで、NSXの可能性はGUIの外側にも大きく広がりますね。

NSX DHCPサービスでIPアドレス管理を自動化する

分散ファイアウォール(DFW)でガチガチに守られた安全なセグメントを手に入れましたが、そこにデプロイするVMIPアドレスを、毎回手動で nmcli コマンドを叩いて static で設定するのでは、せっかくのVCF環境が泣きます。
クラウドなら、VMが起動した瞬間にIPを持っていてほしいですよね。

通常、VLAN環境なら物理ルーター(私の場合はCatalyst 2960)やWindows ServerでDHCPを立てて、ip helper-address で飛ばすのが定石です。
しかし、NSXのオーバーレイネットワークは論理的な空間なので、物理層にあるDHCPサーバーまでパケットを飛ばすのは、設定(DHCP Relay)が少々面倒です。

そこで今回は、NSXのエッジ/ゲートウェイ自体にDHCPサーバー機能を持たせる 検証を行います。
これにより、物理ネットワーク機器の設定変更が一切不要になるので、自宅ラボには最高のソリューションなんです。

DHCPリレーか、ローカルDHCP

NSXDHCPを実現する方法は大きく分けて2つあります。

  • DHCP Relay:既存の物理DHCPサーバーを使う。企業ネットワークならこっちが主流。
  • DHCP Local Server:NSX Edge上でDHCPサービスを動かす。

自宅ラボのCatalyst 2960はL3スイッチ化していますが、オーバーレイセグメントが増えるたびに、CatalystにログインしてDHCPスコープを切るのは正直しんどいです。 VCFライセンスでNSXのフル機能が使える今、迷わず 「DHCP Local Server」 を選びます。
これなら、今後セグメントを増やした時も、NSXの画面ポチポチするだけで完結できます。

DHCPサーバープロファイルの作成

まずは、DHCP機能の「プロファイル」を作ります。
NSX Managerの「ネットワーク」-「ネットワークプロファイル」-「DHCP」から「DHCPプロファイルの追加」をクリックします。

以下の情報を入力し「保存」をクリックします。
前:profile-vlan41
プロファイルタイプ:DHCPサーバ
サーバIPアドレス:192.168.41.2/24
Edgeクラスタ:Edge-Cluster-01
Edgeの自動割り当て:はい


セグメントでDHCPの構成を行う

ここからがNSXのスマートなところです。 一般的なルーターだと「DHCP設定画面」でスコープを切りますが、NSXでは 「セグメント(論理スイッチ)」の設定画面 に統合されています。
「ネットワーク] 」-「セグメント」から対象のオーバーレイセグメント(Seg-192.168.41.0)を編集します。
「サブネット」の下にある「DHCP構成を行う」をクリックします。

DHCPの構成で以下の情報を入力し「適用」をクリックします。
DHCP タイプ:セグメントのDHCPサーバ
DHCPプロファイル:profile-vlan41
DHCPサーバアドレス:192.168.41.2/24
DHCP範囲:192.168.41.16-192.168.41.20
IPv4ゲートウェイ:192.168.41.1/24
リース時間:86400
DNSサーバ:192.168.10.9、8.8.8.8

これで設定完了です。 物理スイッチ(Catalyst)には一切触れていません。

接続検証:VMはIPを取れるのか

では、前回作ったLinux VM(seg41-web01)のネットワーク設定を「DHCP」に変更して再起動していきます。

★固定IPで設定されていることを確認します。

hisato@seg14-web01:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1350 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:96:a6:f5 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.41.21/24 brd 192.168.41.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe96:a6f5/64 scope link
       valid_lft forever preferred_lft forever
hisato@seg14-web01:~$
hisato@seg14-web01:~$ cat /etc/netplan/00-installer-config.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    ens33:
      dhcp4: no
      addresses:
        - 192.168.41.21/24
      routes:
        - to: default
          via: 192.168.41.1
      nameservers:
        addresses: [192.168.10.9, 8.8.8.8]

hisato@seg14-web01:~$

★VIで以下のように編集しました。

hisato@seg14-web01:~$ cat /etc/netplan/00-installer-config.yaml
network:

  version: 2
  renderer: networkd
  ethernets:
    ens33:
      dhcp4: true
#      addresses:
#        - 192.168.41.21/24
#      routes:
#        - to: default
#          via: 192.168.41.1
#      nameservers:
#        addresses: [192.168.10.9, 8.8.8.8]

hisato@seg14-web01:~$

★変更した内容を適用します。

hisato@seg14-web01:~$ sudo netplan apply

** (generate:7251): WARNING **: 14:16:40.110: Permissions for /etc/netplan/00-installer-config.yaml are too open. Netplan configuration should NOT be accessible by others.

** (process:7249): WARNING **: 14:16:40.615: Permissions for /etc/netplan/00-installer-config.yaml are too open. Netplan configuration should NOT be accessible by others.

** (process:7249): WARNING **: 14:16:40.837: Permissions for /etc/netplan/00-installer-config.yaml are too open. Netplan configuration should NOT be accessible by others.
hisato@seg14-web01:~$
hisato@seg14-web01:~$
hisato@seg14-web01:~$

★DHCPでIPを取得しています。
★dynamic ens33 と表示されています。

hisato@seg14-web01:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1350 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:96:a6:f5 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.41.18/24 metric 100 brd 192.168.41.255 scope global dynamic ens33
       valid_lft 86363sec preferred_lft 86363sec
    inet6 fe80::250:56ff:fe96:a6f5/64 scope link
       valid_lft forever preferred_lft forever
hisato@seg14-web01:~$
hisato@seg14-web01:~$

★DNSサーバの設定も取得できています。

hisato@seg14-web01:~$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (ens33)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.168.10.9
       DNS Servers: 192.168.10.9 8.8.8.8
hisato@seg14-web01:~$
hisato@seg14-web01:~$
hisato@seg14-web01:~$
hisato@seg14-web01:~$

★名前解決できることも確認できました。

hisato@seg14-web01:~$ ping www.google.co.jp
PING www.google.co.jp (142.250.196.131) 56(84) bytes of data.
64 bytes from nrt12s36-in-f3.1e100.net (142.250.196.131): icmp_seq=1 ttl=118 time=8.17 ms
64 bytes from nrt12s36-in-f3.1e100.net (142.250.196.131): icmp_seq=2 ttl=118 time=8.43 ms
64 bytes from nrt12s36-in-f3.1e100.net (142.250.196.131): icmp_seq=3 ttl=118 time=10.2 ms
64 bytes from nrt12s36-in-f3.1e100.net (142.250.196.131): icmp_seq=4 ttl=118 time=8.24 ms
^C
--- www.google.co.jp ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 8.165/8.758/10.204/0.839 ms
hisato@seg14-web01:~$
hisato@seg14-web01:~$

ルーティングの不思議とCatalystの役割

ここでネットワークエンジニア視点で面白いのが、Catalyst 2960側はこのDHCP通信を一切関知していない という点です。
VMから出た DHCP Discover パケット(ブロードキャスト)は、ESXiホスト内でGeneveカプセルに包まれ、物理ネットワーク上では単なるユニキャストのUDPパケットとして運ばれ、Edgeノードに到達します。
物理スイッチから見れば「なんか暗号化された通信が通ってるな」程度です。
これで、ip helper-address の設定ミスでDHCPが失敗する、という古典的なトラブルとは無縁になります。

まとめ

ここまでで、いったんNSX関連は完了となります。VCFライセンスにより以下の機能を手に入れることができました。

  • オーバーレイネットワーク:物理構成を変えずにセグメント増設し放題。
  • マイクロセグメンテーション:同じセグメント内でも通信制御が可能。
  • DHCP自動化:VMを作れば勝手にIPが降ってくる。

自宅ラボが、Amazon VPCやAzure VNetのような「クラウド」になりました。
さて、基盤とネットワークは整いました。
次はアプリケーションデリバリーの領域へ進みます。
以前構築したAvi Load Balancerは、22.1.7のNo Orchestratorで止まっていました。
現在の最新版は、31.2.1です。
ここ2,3年、vCenter、Avi、NSXのすべてのライセンスが揃うことがなかったので、やっと連携設定を検証することができます。
自戒をお楽しみに!!