2026年9月20日
2026年9月20日
Azure Load BalancerでWordPressを複数VMに分散する設定(Azure CLI)
Azure Load Balancer は、インターネットから来た TCP/UDP の通信を、複数の仮想マシン(VM)に振り分けるサービスです。WordPress を2台以上の VM で動かし、1台が止まってもサイトを表示し続けたいときや、負荷を分けたいときに使います。
この記事では、Azure CLI で公開用の Azure Load Balancer(Standard)を作り、WordPress を動かす VM を振り分け先に登録する手順を説明します。コマンドは2026年11月時点の Microsoft Learn のクイックスタートと Azure CLI のリファレンスに沿っています。
最初に知っておくこと
- Standard を使う: Basic Load Balancer は2025年9月30日に廃止されました。新しく作るのは Standard です。Standard のロードバランサーと公開 IP アドレスは、ネットワークセキュリティグループ(NSG)で許可しない限り、外からの通信を通しません。
- レイヤー4で振り分ける: Azure Load Balancer は TCP/UDP の単位で振り分けるだけで、HTTPS の復号や URL ごとの振り分けはしません。証明書は各 VM に置きます。ロードバランサーで HTTPS を終端したい、URL で振り分けたい、WAF を使いたいといった場合は、Azure Application Gateway や Azure Front Door を検討します。
- 料金がかかる: Standard Load Balancer は、規則の数や処理したデータ量に応じて課金されます。公開 IP アドレスや NAT ゲートウェイも別に課金されるので、作る前に Azure の料金ページで確認してください。
WordPress側で準備すること
ロードバランサーは、リクエストを VM のどれか1台に送ります。どの VM に届いても同じ内容を返せるよう、WordPress 側を次のようにそろえておく必要があります。
| 項目 | 1台構成との違い | 対応の例 |
|---|---|---|
| データベース | 各 VM に DB があると、内容がばらばらになる | すべての VM から同じ DB に接続する(Azure Database for MySQL フレキシブル サーバー、または DB 専用の VM) |
アップロードした画像など(wp-content/uploads) |
1台にアップロードした画像が、ほかの VM には無い | 共有ストレージ(Azure Files など)をマウントする、またはメディアをクラウドストレージに置くプラグインを使う |
| WordPress 本体・テーマ・プラグイン | 管理画面から更新すると、その1台だけが変わる | 管理画面からの更新やインストールは止め(DISALLOW_FILE_MODS)、デプロイの仕組みで全 VM に同じファイルを配る |
wp-config.php |
認証用キー(ソルト)が VM ごとに違うと、ログインが切れる | すべての VM で同じ wp-config.php を使う |
| HTTPS の証明書 | 各 VM で HTTPS を受ける | 同じ証明書を全 VM に置く |
ログイン状態は Cookie で管理されるため、wp-config.php の認証用キーがそろっていれば、リクエストが別の VM に届いてもログインは保たれます。PHP のセッションを使うプラグインがある場合は、後述の「送信元 IP で同じ VM に送る」設定を検討します。
Let's Encrypt の HTTP での認証は、認証用のリクエストがロードバランサー経由で別の VM に届き、失敗することがあります。DNS での認証で取得した証明書を全 VM に配るなどの方法を取ってください。
前提
- Azure CLI が使えること(Azure Cloud Shell の Bash を使えば準備は不要です)
- WordPress を動かす Ubuntu の VM が2台あり、同じ仮想ネットワークのサブネットにあること(この記事では、リソースグループ
wp-lb-rg、仮想ネットワークwp-vnet、サブネットbackend-subnet、VMwp-vm1・wp-vm2として書きます) - VM には公開 IP アドレスを付けない(外からの通信はロードバランサー経由だけにする)
名前は自分の環境に合わせて変えてください。最初に変数にしておくと、以降のコマンドをそのまま使えます。
RG=wp-lb-rg
LOCATION=japaneast
VNET=wp-vnet
SUBNET=backend-subnet
LB=wp-lb
手順1: 正常性プローブ用のページを各VMに用意する
ロードバランサーは、各 VM に定期的に問い合わせ(正常性プローブ)を送り、応答しない VM には通信を送らなくなります。HTTP のプローブは、応答が 200 のときだけ 正常と判断します。WordPress のトップページは、HTTPS へのリダイレクト(301)やエラーを返すことがあるため、プローブ専用の静的なファイルを用意します。
各 VM で次を実行します。
sudo mkdir -p /var/www/health
echo ok | sudo tee /var/www/health/lb-health.html
HTTP のプローブはホスト名を付けずに送られるため、ポート80の既定のサーバー(default_server)で、このファイルをリダイレクトせずに返すようにします。Nginx の場合の例です。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# ロードバランサーの正常性プローブ用(リダイレクトしない)
location = /lb-health.html {
root /var/www/health;
}
# それ以外は HTTPS へ
location / {
return 301 https://example.com$request_uri;
}
}
sudo nginx -t で文法を確かめてから、sudo systemctl reload nginx で読み込み直します。VM の中で curl -i http://127.0.0.1/lb-health.html を実行し、200 OK が返ることを確認しておきます。
手順2: 公開IPアドレスとロードバランサーを作る
az network public-ip create \
--resource-group $RG \
--name wp-lb-ip \
--sku Standard \
--zone 1 2 3
az network lb create \
--resource-group $RG \
--name $LB \
--sku Standard \
--public-ip-address wp-lb-ip \
--frontend-ip-name wp-lb-frontend \
--backend-pool-name wp-lb-pool
--zone 1 2 3 は、可用性ゾーンをまたいで使える(ゾーン冗長の)公開 IP アドレスにする指定です。ゾーンに対応していないリージョンでは外します。
手順3: 正常性プローブを作る
az network lb probe create \
--resource-group $RG \
--lb-name $LB \
--name wp-health \
--protocol http \
--port 80 \
--path /lb-health.html
Azure CLI で作ったプローブの間隔は、既定で15秒です。プローブの送信元は 168.63.129.16 で、NSG の既定の規則(AllowAzureLoadBalancerInBound)で許可されています。VM の中でファイアウォール(ufw など)を使っている場合は、このアドレスからのポート80への通信も許可してください。
手順4: 負荷分散規則を作る
HTTP(80)と HTTPS(443)の2つの規則を作ります。どちらも同じプローブで VM の状態を判断します。
az network lb rule create \
--resource-group $RG \
--lb-name $LB \
--name wp-http \
--protocol tcp \
--frontend-port 80 \
--backend-port 80 \
--frontend-ip-name wp-lb-frontend \
--backend-pool-name wp-lb-pool \
--probe-name wp-health \
--disable-outbound-snat true \
--idle-timeout 15 \
--enable-tcp-reset true
az network lb rule create \
--resource-group $RG \
--lb-name $LB \
--name wp-https \
--protocol tcp \
--frontend-port 443 \
--backend-port 443 \
--frontend-ip-name wp-lb-frontend \
--backend-pool-name wp-lb-pool \
--probe-name wp-health \
--disable-outbound-snat true \
--idle-timeout 15 \
--enable-tcp-reset true
--frontend-port 443 --backend-port 443: ロードバランサーは HTTPS を復号しないので、443 番はそのまま各 VM の 443 番に渡します(443 を 80 に渡すと HTTPS として通じません)。--idle-timeout: 通信が無いまま接続を保つ時間(分)で、4〜30 の範囲で指定します。--load-distribution: 既定(Default)では接続ごとに VM を選びます。PHP のセッションなどで同じ訪問者を同じ VM に送りたい場合はSourceIPを指定します。
手順5: NSGで80番と443番を許可する
Standard のロードバランサーでは、NSG で許可した通信だけが VM に届きます。NSG を作り、HTTP と HTTPS を許可して、VM のサブネットに関連付けます。
az network nsg create \
--resource-group $RG \
--name wp-nsg
az network nsg rule create \
--resource-group $RG \
--nsg-name wp-nsg \
--name allow-web \
--protocol tcp \
--direction inbound \
--source-address-prefix '*' \
--source-port-range '*' \
--destination-address-prefix '*' \
--destination-port-ranges 80 443 \
--access allow \
--priority 200
az network vnet subnet update \
--resource-group $RG \
--vnet-name $VNET \
--name $SUBNET \
--network-security-group wp-nsg
SSH(22番)はこの規則では開けていません。VM の管理には Azure Bastion などを使い、SSH をインターネットに開けないようにします。
手順6: VMを振り分け先(バックエンドプール)に入れる
バックエンドプールには、VM のネットワークインターフェース(NIC)の IP 構成を登録します。az vm create で作った VM は、NIC や IP 構成の名前が VM 名から自動で付けられているので、名前を調べてから登録します。次のループは、2台の VM について NIC と IP 構成の名前を調べ、バックエンドプールに加えます(NIC が同じリソースグループにある前提です)。
for VM in wp-vm1 wp-vm2; do
NIC_ID=$(az vm nic list --resource-group $RG --vm-name $VM --query "[0].id" --output tsv)
NIC_NAME=$(az network nic show --ids $NIC_ID --query name --output tsv)
IPCONFIG=$(az network nic show --ids $NIC_ID --query "ipConfigurations[0].name" --output tsv)
az network nic ip-config address-pool add \
--resource-group $RG \
--nic-name $NIC_NAME \
--ip-config-name $IPCONFIG \
--lb-name $LB \
--address-pool wp-lb-pool
done
手順7: VMからの外向きの通信をNATゲートウェイで確保する
公開 IP アドレスの無い VM を Standard のロードバランサーのバックエンドプールに入れると、Azure が用意する既定の外向き通信が使えなくなります。この状態では、VM から WordPress やパッケージの更新を取りに行けません。手順4で --disable-outbound-snat true にしているので、外向きの通信は NAT ゲートウェイで用意します。
az network public-ip create \
--resource-group $RG \
--name wp-nat-ip \
--sku Standard \
--zone 1 2 3
az network nat gateway create \
--resource-group $RG \
--name wp-nat-gateway \
--public-ip-addresses wp-nat-ip \
--idle-timeout 10
az network vnet subnet update \
--resource-group $RG \
--vnet-name $VNET \
--name $SUBNET \
--nat-gateway wp-nat-gateway
手順8: 動作を確認してDNSを向ける
ロードバランサーの公開 IP アドレスを調べます。
LB_IP=$(az network public-ip show \
--resource-group $RG \
--name wp-lb-ip \
--query ipAddress \
--output tsv)
echo $LB_IP
正常性プローブ用のページと、サイトにアクセスします(example.com は自分のドメインに変えます。DNS を切り替える前なので、--resolve でロードバランサーの IP アドレスに向けています)。
curl -i http://$LB_IP/lb-health.html
curl -I --resolve example.com:443:$LB_IP https://example.com/
1台の VM で Nginx を止めて、もう1台からサイトが表示され続けることも確かめておきます。問題がなければ、ドメインの A レコードをロードバランサーの公開 IP アドレスに変えます。
運用の注意
- 更新は全VMで同じに: WordPress やプラグインの更新は、デプロイの仕組みで全 VM に同時に配ります。1台だけ違う版が残ると、アクセスのたびに表示や動作が変わります。
- WP-Cron の重複: WP-Cron はアクセスのあった VM で動きます。予約投稿などの定期処理を決まった時刻に動かしたい場合は、
DISABLE_WP_CRONを有効にし、1台だけでサーバーの cron から実行します。 - 訪問者の IP アドレス: Azure Load Balancer は送信元の IP アドレスを書き換えないため、WordPress やアクセスログには訪問者の IP アドレスがそのまま記録されます。
- 後片付け: 試しに作っただけなら、
az group delete --name $RGでリソースグループごと削除できます。VM や DB も同じリソースグループにある場合は一緒に消えるので注意してください。
まとめ
- Basic は廃止済みなので、Standard の Azure Load Balancer を使う
- WordPress 側は、DB・アップロードファイル・コード・
wp-config.php・証明書を全 VM でそろえる - HTTP のプローブは 200 だけを正常とみなすため、リダイレクトしない専用ページを
default_serverで返す - 80 と 443 をそれぞれ同じ番号で VM に渡し、NSG で許可する
- バックエンドプールの VM の外向き通信は NAT ゲートウェイで用意する
関連記事: