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、VM wp-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 ゲートウェイで用意する

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲