AzureでWebサーバー・DBサーバー・管理サーバーをVNet単位で分離していくと、必ずこの壁にぶつかります。VPNゲートウェイを使う方法もありますが、構成が複雑でコストもかかります。
この記事では、VPN不要でVNetどうしを直接繋げるVNetピアリングの仕組みと、ハブアンドスポーク構成をazコマンドで組み上げる手順を実機ログ付きで解説します。Ubuntu 24.04 LTS / RHEL 9.4 のLinux VMで動作確認済みです。
この記事のポイント
・VNetピアリングはVPN不要でVNet間をAzureバックボーンで直結できる低コスト構成
・ピアリングは双方向(A側とB側の両方)を設定しないと通信が通らない
・az network vnet peering create コマンドでピアリングを追加できる
・ハブアンドスポーク構成で複数VNetをセキュアに一元管理できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
VNetピアリングとは何か(VPN不要でVNetを直結する仕組み)
Azureでは、VNet(Virtual Network)ごとにアドレス空間が分離されています。異なるVNet上のVMは、デフォルトではお互いに通信できません。VNet間の通信を可能にする手段には大きく2種類あります。
・VPNゲートウェイ(VNet-to-VNet):暗号化トンネルをインターネット越しに張る。オンプレミスとの接続にも使えるが、ゲートウェイのコストが別途かかる
・VNetピアリング:Azure内部のネットワーク骨格(バックボーン)でVNetを直結する。ゲートウェイ不要・低遅延・低コスト
VNetピアリングはAzureのバックボーンを使うためインターネットを経由せず、遅延はほぼゼロに近くなります。同一リージョン内の「VNetピアリング」と、異なるリージョンをまたぐ「グローバルVNetピアリング」の2種類があります。
重要な特性:ピアリングは推移的でない
VNet A、VNet B、VNet C の3つがある場合、A-B間、B-C間にピアリングを張っても、AとCは通信できません。AとCを繋ぐには、AとCの間にも別途ピアリングを設定する必要があります。この「非推移性」がハブアンドスポーク構成を選ぶ主な理由になります。
ハブアンドスポーク構成で複数VNetを一元管理する
非推移的なピアリングを複数のVNet間でフルメッシュに張ろうとすると、VNet数Nに対してN×(N-1)/2本のピアリングが必要になります。VNetが5つなら10本、10つなら45本と急増します。これを解決するのがハブアンドスポーク構成です。
・ハブVNet:Azure Firewallやジャンプサーバーを置く中央VNet。全スポークからの通信がここを経由する
・スポークVNet:用途別に分けたVNet(Web層・DB層・開発環境など)。ハブとのみピアリングを張る
スポークが増えても追加するピアリングは「ハブ-スポーク」の2本だけです。スポーク同士は直接通信せずハブ経由で制御するため、セキュリティポリシーの一元管理も容易になります。
本記事では、ハブVNet1つとスポークVNet1つのシンプルな構成で実践します。
| VNet名 | アドレス空間 | サブネット | 配置するVM |
|---|---|---|---|
| hub-vnet | 10.0.0.0/16 | hub-subnet(10.0.0.0/24) | hub-vm(ジャンプサーバー) |
| spoke-vnet | 10.1.0.0/16 | spoke-subnet(10.1.0.0/24) | spoke-vm(Webサーバー) |
実践:VNetとサブネットを作成する
1. リソースグループとハブVNetの作成
まずリソースグループを作成し、ハブVNetを配置します。# リソースグループを作成 az group create \ --name rg-hub-spoke \ --location japaneast # ハブVNetとサブネットを作成 az network vnet create \ --name hub-vnet \ --resource-group rg-hub-spoke \ --address-prefix 10.0.0.0/16 \ --subnet-name hub-subnet \ --subnet-prefix 10.0.0.0/24
{ "newVNet": { "addressSpace": { "addressPrefixes": ["10.0.0.0/16"] }, "location": "japaneast", "name": "hub-vnet", "provisioningState": "Succeeded", "subnets": [ { "addressPrefix": "10.0.0.0/24", "name": "hub-subnet", "provisioningState": "Succeeded" } ] } }
2. スポークVNetの作成
続いてスポーク側のVNetを作成します。アドレス空間は hub-vnet と重複しないようにしてください(重複するとピアリングを設定できません)。# スポークVNetとサブネットを作成 az network vnet create \ --name spoke-vnet \ --resource-group rg-hub-spoke \ --address-prefix 10.1.0.0/16 \ --subnet-name spoke-subnet \ --subnet-prefix 10.1.0.0/24
3. ジャンプサーバーとWebサーバーのVMを作成する
ハブにジャンプサーバー(hub-vm)、スポークにWebサーバー(spoke-vm)を配置します。# ハブ側:ジャンプサーバー(パブリックIPあり) az vm create \ --resource-group rg-hub-spoke \ --name hub-vm \ --image Ubuntu2404 \ --vnet-name hub-vnet \ --subnet hub-subnet \ --admin-username azureuser \ --generate-ssh-keys \ --size Standard_B1s # スポーク側:Webサーバー(パブリックIPなし) az vm create \ --resource-group rg-hub-spoke \ --name spoke-vm \ --image Ubuntu2404 \ --vnet-name spoke-vnet \ --subnet spoke-subnet \ --admin-username azureuser \ --generate-ssh-keys \ --public-ip-address "" \ --size Standard_B1s
--public-ip-address "" を付けてパブリックIPを付与しません。ハブのジャンプサーバー経由でしかアクセスできない構成にするためです。ピアリング接続を双方向で設定する
VNetピアリングは必ず双方向に設定します。A側からB側へのピアリングだけ設定しても通信は通りません。B側からA側へのピアリングもセットで作成する必要があります。1. ハブからスポーク方向のピアリング
# スポークVNetのリソースIDを取得 SPOKE_ID=$(az network vnet show \ --resource-group rg-hub-spoke \ --name spoke-vnet \ --query id -o tsv) # ハブ側からスポーク方向のピアリングを作成 az network vnet peering create \ --name hub-to-spoke \ --resource-group rg-hub-spoke \ --vnet-name hub-vnet \ --remote-vnet $SPOKE_ID \ --allow-vnet-access
--allow-vnet-access を付けることで、ピアリング先のVNetアドレス空間への通信が許可されます。2. スポークからハブ方向のピアリング
# ハブVNetのリソースIDを取得 HUB_ID=$(az network vnet show \ --resource-group rg-hub-spoke \ --name hub-vnet \ --query id -o tsv) # スポーク側からハブ方向のピアリングを作成 az network vnet peering create \ --name spoke-to-hub \ --resource-group rg-hub-spoke \ --vnet-name spoke-vnet \ --remote-vnet $HUB_ID \ --allow-vnet-access
3. ピアリング状態を確認する
両方向のピアリングがConnected になっていることを確認します。# ハブ側のピアリング状態を確認 az network vnet peering list \ --resource-group rg-hub-spoke \ --vnet-name hub-vnet \ -o table
Name PeeringState ProvisioningState AllowVnetAccess ------------ -------------- ------------------- ----------------- hub-to-spoke Connected Succeeded True
az network vnet peering list \ --resource-group rg-hub-spoke \ --vnet-name spoke-vnet \ -o table
Name PeeringState ProvisioningState AllowVnetAccess ------------ -------------- ------------------- ----------------- spoke-to-hub Connected Succeeded True
PeeringState: Connected になっていれば設定完了です。
Azure対応セミナーの詳細を見る >>
ピアリング越しのSSH接続で疎通確認する
ハブVMに接続し、そこからスポークVMへSSHを通してみます。これがジャンプサーバー経由のアクセスパターンです。まずhub-vmのパブリックIPを取得します。
# hub-vmのパブリックIPを確認 az vm show \ --resource-group rg-hub-spoke \ --name hub-vm \ --show-details \ --query publicIps -o tsv
20.xxx.xxx.145
# spoke-vmのプライベートIPを確認 az vm show \ --resource-group rg-hub-spoke \ --name spoke-vm \ --show-details \ --query privateIps -o tsv
10.1.0.4
# 自分のPCからhub-vmにSSH(エージェント転送を有効化) ssh -A azureuser@20.xxx.xxx.145 # hub-vmからspoke-vmにSSH(プライベートIPで接続) azureuser@hub-vm:~$ ssh azureuser@10.1.0.4
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-1021-azure x86_64) * Documentation: https://help.ubuntu.com Last login: Thu Jul 3 09:12:33 2026 from 10.0.0.4 azureuser@spoke-vm:~$
10.0.0.4(hub-subnetのアドレス)になっていることが確認できます。VNetピアリングを通じてVNet間の通信が実現したことが証明されました。VNet内のポート疎通をコマンドでより詳しく確認したい場合は、Linux ポート確認の全コマンドも活用できます。
ピアリングを使う際の注意点
VNetピアリングを本番環境で使う際に知っておきたいポイントをまとめます。・アドレス空間の重複禁止:ピアリングするVNet同士のCIDRが重複していると設定できません。設計段階でアドレス計画を立てておくことが重要です
・推移性がない:A・B・Cが連鎖していても、AとCは通信できません。ハブアンドスポーク構成ではハブを経由させることで解決します
・双方向設定が必須:片方だけ設定するとPeeringStateが「Initiated」のまま「Connected」になりません
・グローバルVNetピアリングのコスト:異なるリージョン間のピアリングはデータ転送コストが発生します。同一リージョン内と比べてコストが高くなる点に注意してください
VNet間のDNS名前解決には、Azure Private DNSゾーンを使った設定が別途必要になります。Linuxでの基本的なDNS設定については、Linux DNS 設定の基本も参考になります。
トラブルシュート(ピアリングが通らない時)
1. NSGのインバウンドルールを確認する
ピアリング自体がConnected でも、NSG(ネットワークセキュリティグループ)がSSHを拒否していると通信できません。VMのNSGを確認します。# spoke-vmに紐づくNSGを確認 az network nsg list \ --resource-group rg-hub-spoke \ -o table
Location Name ProvisioningState ---------- ------------- ------------------- japaneast spoke-vmNSG Succeeded
# VNetからのSSH(22番ポート)を許可するルールを追加 az network nsg rule create \ --resource-group rg-hub-spoke \ --nsg-name spoke-vmNSG \ --name allow-ssh-from-vnet \ --priority 300 \ --direction Inbound \ --access Allow \ --protocol Tcp \ --source-address-prefix VirtualNetwork \ --destination-port-range 22
2. PeeringStateが「Connected」にならない場合
ピアリングのPeeringStateがInitiated のままになっているときは、逆方向のピアリングがまだ作成されていない状態です。# 両方向の状態を確認する az network vnet peering list \ --resource-group rg-hub-spoke \ --vnet-name hub-vnet \ --query "[].{name:name,state:peeringState}" \ -o table az network vnet peering list \ --resource-group rg-hub-spoke \ --vnet-name spoke-vnet \ --query "[].{name:name,state:peeringState}" \ -o table
Initiated・もう一方が存在しない場合は、逆方向の az network vnet peering create コマンドを実行してください。3. アドレス空間が重複している場合
ピアリング作成時に次のエラーが出た場合は、アドレス空間が重複しています。(VNetPeeringAddressSpaceOverlap) The peering could not be added. The address space of 'spoke-vnet' overlaps with 'hub-vnet'.
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| VNetを作成する | az network vnet create --name <名前> --address-prefix <CIDR> |
| ピアリングを作成する | az network vnet peering create --name <名前> --vnet-name <VNet> --remote-vnet <ID> |
| ピアリング状態を確認する | az network vnet peering list --vnet-name <VNet> -o table |
| NSGルールを追加する | az network nsg rule create --nsg-name <NSG名> --priority <優先度> |
| VMのプライベートIPを確認する | az vm show --name <VM名> --show-details --query privateIps |
Azure対応セミナーの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:AzureのBastionでパブリックIPなしにLinux VMへSSH接続する方法|踏み台サーバー不要のセキュア接続手順
- 前のページへ:AzureのPrivate DNSゾーンを設定する方法|VNet内の名前解決をazコマンドで構成する
- この記事の属するカテゴリ:Azureへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます