3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azureで Windows Server Failover Cluster(WSFC)を組んでみた。

Last updated at Posted at 2025-12-14

はじめに

本記事はNSSOL Advent Calendar 2025の15日目の記事になります。

今年のテーマを考えていたとき、今の案件で一緒に働いている方から「WSFC(Windows Server Failover Cluster)」というワードがふと出てきました。

私自身、WSFCを組んだことはなく、そこから「せっかくならAzure上でクラスタを構築してみよう」と思い立ち、さらに今年から取り組み始めたAnsibleも絡めて、今回のテーマに決めました。この記事では以下の3フェーズで構成しています。

フェーズ 内容
フェーズ0:環境準備 Azureリソース・仮想ネットワーク・AD DSの構築
フェーズ1:WSFC構築 共有ディスク/クラウドウィットネス構成のクラスタ構築
フェーズ2:Ansible自動化 WSFCノードへの共通初期設定の自動化

前提知識

①WSFC

Windows Server Failover Cluster(WSFC) とは、Windows Serverに標準搭載されている高可用性機能の一つです。複数のノードで1つのクラスタを構成し、どれかのノードで障害が発生した場合に自動的に別ノードへサービスを引き継ぐことができます。

オンプレミス環境ではSQL Serverやファイルサーバーなどでよく利用されてきた仕組みですが、Azureでも同様に共有ディスクを使うことでクラウド上にWSFCを構築できます。

②クォーラム(Quorum)

WSFCでは、複数のノードが連携して1つのクラスタを構成します。しかし、ネットワーク障害などでノード間の通信が分断された場合、どのノードが「生き残っているクラスタ」として動き続けるか を判断する必要があります。

この「クラスタの過半数を決める仕組み」が クォーラム(Quorum) です。
言い換えると、「誰がリーダーかを投票で決める」ような仕組みです。

クォーラムについて具体例でイメージしてみる。

たとえば、3人で構成されたクラスタを考えます。

ノード 状態
node1 生存
node2 生存
node3 ネットワーク断

このとき、node1 と node2 の2票が残っているため、クラスタは過半数(2/3)を維持して稼働を続ける(=正常)と判断します。一方で、1ノードしか残らない場合(票が半分未満になる場合)は、クラスタは「不整合を防ぐために停止」します。これがスプリットブレイン(split-brain)防止の仕組みです。

③ウィットネス(Witness)

しかし、このクォーラムの「票」が偶数になる場合(例:ノードが2台構成など)、過半数の判定が難しくなります。そこで登場するのが ウィットネス(Witness) です。ウィットネスは「第三の投票者」として動作し、クラスタの可否判定をサポートします。今回は2ノードのため、下記の二種類のWitnessを実装します。

種類 概要
Disk Witness クラスタ共有ディスクに投票情報を格納します。オンプレミス構成などで利用される方式です。
Cloud Witness Azure Storage Account に投票情報を格納します。Azure環境で推奨される構成です。

参考:
クォーラム監視とは? (Microsoft Learn)

フェーズ0 環境準備

Azure上でWSFCを構築するための基盤環境を整備していきます。
このフェーズでは以下を実施します:

  • Azureリソースの作成
  • 仮想マシン(クラスタノード、AD DS)のデプロイ
  • ドメイン参加
  • 共有ディスク(クラスタ用ストレージ)の準備

フェーズ0-1 Azure インフラの準備

まずは、WSFC用の仮想ネットワーク等をAzure上に構築します。

項目 内容 補足・ポイント
リージョン Japan East 同一リージョン内でVM・共有ディスクを配置
リソースグループ名 rg-wsfc-lab-east すべての関連リソースをまとめる
仮想ネットワーク (VNet) 名前:vnet-wsfc-lab
アドレス空間:10.0.0.0/24
サブネット 名前:default
アドレス範囲:10.0.0.0/24
AD DS、WSFCノードを同一サブネット内に配置。
Cloud Witness用 Storage Account 名前:stwsfcwitness01
SKU:Standard汎用v2
冗長性:LRS
クォーラム用。アクセスキー(key1)を控える

フェーズ0-2 仮想マシン(WSFC ノード)構築

次に、クラスタを構成する2台のノードをデプロイします。
同一サブネット内に配置し、後でドメインに参加させます。

項目 内容 備考
ノード名 wsfc-node01 / wsfc-node02 同一ドメインに参加させる
OS Windows Server 2025 Datacenter Azure Edition
リージョン Japan East 同一リージョン内配置
VMサイズ Standard B4ls v2
ストレージ Premium SSD (共有ディスクは別途用意) OSディスク用
NIC 各VMに1枚 WSFCノードをサブネット"default"に配置(node1:10.0.0.4, node2: 10.0.0.5)

フェーズ0-3 Active Directory(AD DS)構築・準備

同じサブネット内にAD DS用のVMをデプロイし、ドメインコントローラを構築します。

項目 内容 備考
ホスト名 wsfc-AD
ドメイン名 wsfc.lab.local
IPアドレス 10.0.0.6
DNS 自身のIP(10.0.0.6)

RDPで接続し、サーバーマネージャーから AD DS と DNS サーバー の役割を追加します。
(今回は日本語化は省略しています。)
image.png

AD DSとDNSサーバを選択します。
image.png

右上の通知(黄色の三角アイコン)から「このサーバーをドメインコントローラーに昇格」を選択します。「新しいフォレストを追加」→ ルートドメイン名に wsfc.lab.local を指定し、DSRMパスワードを設定して進めます。再起動後、DNSが10.0.0.6を返すことを確認します。
(後でクラスタノードからも同様に名前解決できることを確認します。)
image.png

image.png

image.png
クラスタ管理用アカウント svc-wsfc-admin を作成しておきます。
image.png

フェーズ0-4 WSFC ノードのドメイン参加

仮想ネットワークのDNSを 10.0.0.6(AD DS) に変更します。
image.png

各ノードで sysdm.cpl を実行 → コンピュータ名の変更画面を開き、ドメイン名 wsfc.lab.local を入力してドメインに参加します。
image.png
アカウントは svc-wsfc-admin を使用し、参加後に再起動します。
image.png

フェーズ0-5 共有ディスクの作成

クラスタノードが同一ディスクに同時アクセスできるよう、共有ディスクを準備します。
このディスクは後に「クォーラムディスク」や「データディスク」として利用されます。

項目 内容
ディスク名 disk-wsfc-shared01
サイズ 128 GB
タイプ Premium SSD(共有ディスク対応)
LUN 1
接続対象 wsfc-node01, wsfc-node02
使用形式 NTFSフォーマット、ドライブレター:F:

Azureポータル上で共有ディスクを作成します。
image.png

image.png

作成した共有ディスクを、wsfc-node01wsfc-node02 の両方にアタッチします。LUN(Logical Unit Number)は、「このディスクをOSが何番目のディスクとして認識するか」を示す番号です。 WSFCでは、全ノードで「同じディスクを同じLUN番号で認識している」必要があるため、ここでは 1 に統一します。下図は node02 側での設定例です(node01 も同様に設定します)。
image.png

次に、wsfc-node01 にRDP接続し、OS上でディスクの初期化とフォーマットを行います。
この作業は必ず片方(node01)のみで実施してください。
image.png

「ディスクの管理」から以下のように設定します:

  1. 新しいディスクを「オンライン」にする
  2. ディスクを初期化(GPT推奨)
  3. 「新しいシンプル ボリューム」を作成
  4. ファイルシステム:NTFS
  5. ドライブレター:F:
  6. ボリューム名:SharedDisk
    image.png
    image.png

フェーズ1 WSFC構築

このフェーズでは、Azure 上に Windows Server Failover Cluster (WSFC) を実際に構築していきます。 2台のノード (wsfc-node01 / wsfc-node02) と、Active Directory ドメインに参加済みの環境を前提としています。

ここでのゴールは以下のとおりです。

  • フェイルオーバークラスタ機能のインストール
  • クラスタ構成の検証と作成
  • DNN(Distributed Network Name)によるクラスタ名構成
  • クォーラム設定(Disk Witness → Cloud Witness への切り替え)

フェーズ1-1 フェイルオーバークラスタ機能のインストール

まず、各ノード(wsfc-node01 / wsfc-node02)にフェイルオーバークラスタ機能をインストールします。

  1. サーバーマネージャーを起動
  2. メニューから 「Manage(管理)」→「Add Roles and Features(役割と機能の追加)」 を選択
  3. 「機能の選択」で 「Failover Clustering」 にチェック
  4. 「Include Management Tools(管理ツールを含む)」 にもチェック
  5. 「次へ」→「インストール」で完了
    image.png

フェーズ1-2 クラスター構成の検証

Failover Cluster Managerを起動し、右ペインから 「Validate Configuration(構成の検証)」 を選択します。 両ノードを指定し、すべての検証テストを実行します。
image.png
image.png
image.png
結果が 「Success」 であれば正常です。
以下のようなネットワーク構成に関する Warning(警告) が出ても問題ありません。

Warnings

  • Node wsfc-node02.wsfc.lab.local is reachable from Node wsfc-node01.wsfc.lab.local by only one pair of network interfaces.
    It is possible that this network path is a single point of failure for communication within the cluster.
    Please verify that this single path is highly available, or consider adding additional networks to the cluster.

  • Node wsfc-node01.wsfc.lab.local is reachable from Node wsfc-node02.wsfc.lab.local by only one pair of network interfaces.
    It is possible that this network path is a single point of failure for communication within the cluster.
    Please verify that this single path is highly available, or consider adding additional networks to the cluster.

この警告は、「ノード間の通信経路が1本しか存在しない=単一障害点になる可能性がある」ことを示すものです。MSのドキュメントにあるように警告は無視して問題ありません。オンプレミス環境では、ハートビート用ネットワークを別に設けて冗長化するのが推奨されていますが、Azure 環境では1本の仮想ネットワーク(VNet)内で十分に冗長性が確保されているためです。

参考:
Configure Windows Server Failover Cluster on Azure - Microsoft Learn

フェーズ1-3 クラスター構成の作成

構成検証が終わったら、同じくFailover Cluster Managerで 「Create Cluster(クラスターの作成)」 を選択します。

  1. ノードに以下を追加
    • wsfc-node01
    • wsfc-node02
  2. クラスター名を指定
    • WSFCCluster01

image.png

💡 WSFCでは共有ディスクの排他制御(Exclusive Access)を行うため、
どのノードが「所有者(Owner)」かが常に明確に決まります。

現在は wsfc-node01 が所有者なので、node02 からはディスクが「オフライン」として見えます。
image.png

補足: 管理用クラスターへの仮想 IP は不要(Windows Server 2019以降)

Azure 上で Windows Server 2019 以降の OS でクラスターを作成した場合、 Failover Cluster Manager からクラスターを作成すると DNN (Distributed Network Name) が自動的に構成されます。

Microsoft のサポートブログでも説明されているとおり、Windows Server 2019 以降では:

  • Azure 上かどうかを OS が自動検出する
  • 管理用クラスター(コアリソース)には 仮想 IP アドレス リソースが作成されない
  • クラスター名は DNN として、各ノードの IP に DNS ラウンドロビンで登録される

そのため、管理用クラスターに接続するための仮想 IPは不要です。

参考:

例外:仮想 IP を使うファイルサーバーなどのアプリケーション ロール

一方で、仮想 IP アドレスを前提としたアプリケーション ロール を Azure VM 上の WSFC で公開する場合は話が変わります。

  • Azure の仮想ネットワークでは、VM に割り当てられた IP 以外のアドレスはそのままでは使えない

  • そのため、WSFC のアプリケーション ロールで使用する「仮想 IP アドレス」を
    Azure Load Balancer のフロントエンド IP として割り当てる必要がある

  • その際に フローティング IP を有効化 し、LB のフロントエンド IP が仮想 IP として機能するように構成します (Azure 上で DHCP サーバを構成する場合も同様の手法を用います)

  • LB のバックエンド プールには全ノードを登録し、ProbePort パラメーターとヘルス プローブを組み合わせて 「仮想 IP の所有者ノードだけにトラフィックを流す」構成にします

つまり:

  • 管理用クラスター名(コアリソース) → LB 不要(DNN で十分)
  • アプリケーション ロールの仮想 IP(例:ファイルサーバーのクラスター IP) → LB 必要

という整理になります。

フェーズ1-4 クォーラム構成 (共有ディスク方式)

ここでは、まず Disk Witness(共有ディスクをWitnessとして使用する構成) を設定します。Disk Witness は、クラスター共有ディスク上に投票情報を格納する方式です。
共有ストレージを利用できる場合に選択します。

ポイント

  • クォーラムの構成を確認するには、Get-ClusterQuorum コマンドレットを使用します。
  • 共有ディスクの所有ノードが切り替わると、ディスクのオンライン状態も自動で移動します。
  • Azure 共有ディスク(Shared Disk)を使用している場合、SCSI Persistent Reservation により排他制御が行われます。

image.png
image.png
image.png
image.png
Assigned to をみると、Disk Witnessになっていることが分かる。
image.png

フェーズ1-5 クォーラム構成 (クラウドウィットネス)

次に、Azure 上でシンプルに構成できる Cloud Witness へ切り替えます。
これは、Azure Storage Account 上にクラスター投票情報(witness blob)を格納する方式です。
「Select Quorum Configuration Option」で Advanced quorum configuration を選択
→ 「Select Quorum Witness」で Configure a cloud witness を選択
→ Azure Storage Account 名とアクセスキーを入力します。
image.png
image.png
image.png
設定後、共有ディスク(Cluster Disk 1)は「Available Storage」カテゴリに戻ります。
これは Disk Witness としての役割が解除されたことを示します。
image.png
ストレージの中身。
image.png

補足

  • Cloud Witness は Azure Storage に対して HTTPS(TCP 443)で通信を行います。
  • 閉域構成で利用する場合は、必要に応じてプロキシ/Firewall の通信許可設定が必要です。

フェーズ2 Ansibleで作業を自動化

ここからは、これまで手動で行ってきたクラスタ構築の一連の作業を Ansible で自動化していきます。

フェーズ2-1 WSFCノードへの共通初期設定をAnsibleで

このフェーズでは、クラスタノードとなる2台のVM(wsfc-node03 / wsfc-node04 を対象に、 Windows Server の初期構成から WSFC 機能のインストール、クォーラム構成までを自動化します。

前提として、以下の状態を準備しておきます。

  • 2台のノードを Azure 上にデプロイ済み
  • 共有ディスクは両ノードにアタッチ済み(事前に node03 側でフォーマット済み)
  • ドメイン未参加の状態からスタートする
  • WinRMは有効化済み

💡 補足
Ansible で Windows Server を操作するためには、各ノードで WinRM (Windows Remote Management) を有効化しておく必要があります。この設定によって、Ansible コントロールノードから WinRM 経由で Windows ノードに接続できるようになります。
今回はHTTP(5985) 接続で実装します。

# 管理者権限でPowerShellを実行

# WinRMサービスを有効化
winrm quickconfig -q

# 自動起動に設定
Set-Service WinRM -StartMode Automatic

# ファイアウォールでポート5985を開放 
netsh advfirewall firewall add rule name="WinRM HTTP" dir=in action=allow protocol=TCP localport=5985

# 設定内容を確認
winrm enumerate winrm/config/listener

Ansibleでは、この前提をもとに以下の処理を自動化します:

  • WSFC機能のインストール
  • クラスター構成(DNN設定含む)
  • クォーラム構成(Cloud Witness 方式)

これにより、手動構築と同等の結果を再現性高く・短時間で再構築できることを目指します。

フェーズ2-2 インベントリファイルの作成と疎通確認

node03と04を追加したインベントリファイルをAnsibleのコントロールノード(10.0.0.9)上で作成します。

all:
  hosts:
    wsfc-node03:
      ansible_host: 10.0.0.7
      ansible_user: azureuser
      ansible_password: "<デプロイ時に設定した管理者ユーザーのパスワード>"
      ansible_connection: winrm
      ansible_port: 5985
      ansible_winrm_transport: ntlm

    wsfc-node04:
      ansible_host: 10.0.0.8
      ansible_user: azureuser
      ansible_password: "<デプロイ時に設定した管理者ユーザーのパスワード>"
      ansible_connection: winrm
      ansible_port: 5985
      ansible_winrm_transport: ntlm

💡 補足
HTTPS(5986) 接続を使う場合は、ansible_winrm_scheme: https と証明書設定を追加します。
セキュリティ上、パスワードは ansible-vault で暗号化しておくのが推奨です

ansible.windows コレクションを入れたうえで、疎通確認コマンドを実行します。

[azureuser@wsfc-Ansible ~]$ ansible all -i inventory.yml -m win_ping
wsfc-node03 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
wsfc-node04 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

フェーズ2-3 ドメイン参加 Playbook

まず# Active Directory 用コレクションをインストールします。

ansible-galaxy collection install microsoft.ad

ドメイン参加用のPlaybookであるjoin_domain.ymlを作成します。作成したらplaybookを実行します。

---
- name: Join WSFC nodes to domain
  hosts: all
  gather_facts: no

  # microsoft.ad コレクションを利用
  collections:
    - microsoft.ad

  vars:
    wsfc_domain: "wsfc.lab.local"
    wsfc_domain_user: "wsfc\\svc-wsfc-admin"
    wsfc_domain_password: "<フェーズ0で作成したドメインユーザーのパスワード>"

  tasks:
    - name: Join domain
      membership:
        dns_domain_name: "{{ wsfc_domain }}"
        hostname: "{{ inventory_hostname }}"
        domain_admin_user: "{{ wsfc_domain_user }}"
        domain_admin_password: "{{ wsfc_domain_password }}"
        state: domain
        reboot: true
#playbook実行コマンド
ansible-playbook -i inventory.yml join_domain.yml

結果はこんな感じで出ればOKです。

[azureuser@wsfc-Ansible ~]$ ansible-playbook -i inventory.yml join_domain.yml

PLAY [Join WSFC nodes to domain] ****************************************************************************************************************************

TASK [Join domain] ******************************************************************************************************************************************
changed: [wsfc-node03]
changed: [wsfc-node04]

PLAY RECAP **************************************************************************************************************************************************
wsfc-node03                : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
wsfc-node04                : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

フェーズ2-4 WSFC 前提構成 Playbook

サーバマネージャーで行った「WSFC に必要な機能インストール 」を行うplaybookであるinstall_wsfc_prereqs.ymlを作成します。同じく作成したら実行します。

---
- name: Install WSFC prerequisites on cluster nodes
  hosts: all
  gather_facts: no
  tasks:
    - name: Install Failover Clustering feature
      ansible.windows.win_feature:
        name:
          - Failover-Clustering
        state: present
        include_management_tools: yes
      register: wsfc_feat

    - name: Reboot if required
      ansible.windows.win_reboot:
      when: wsfc_feat.reboot_required

フェーズ2-5 クラスター構成 Playbook

ここでは、クラスターの構成(DNN構成+Cloud Witnessクォーラム)を自動化します。
Playbook名は create_wsfc_cluster.yml としました。

---
- name: Create WSFC cluster (Azure / DNN)
  hosts: wsfc-node03
  gather_facts: no

  become: yes
  become_method: runas
  become_user: "wsfc\\svc-wsfc-admin"
  vars:
    ansible_become_password: "<クラスター管理用ユーザーのパスワード>"

  tasks:
    - name: Create cluster if not exists
      ansible.windows.win_powershell:
        script: |
          $ErrorActionPreference = 'Stop'

          $clusterName = 'WSFCCluster02'
          $nodes       = @('wsfc-node03','wsfc-node04')

          Import-Module FailoverClusters

          if (-not (Get-Cluster -Name $clusterName -ErrorAction SilentlyContinue)) {
            New-Cluster `
              -Name $clusterName `
              -Node $nodes `
              -NoStorage `
              -AdministrativeAccessPoint Dns
          }
      register: cluster_create

    - name: Set quorum to Cloud Witness
      ansible.windows.win_powershell:
        script: |
          $ErrorActionPreference = 'Stop'

          $clusterName = 'WSFCCluster02'
          $saName      = 'stwsfcwitness02'
          $saKey       = '<ストレージアカウントのアクセスキー>'

          Import-Module FailoverClusters

          $quorum = Get-ClusterQuorum -Cluster $clusterName
          if ($quorum.QuorumResource -ne 'Cloud Witness') {
            Set-ClusterQuorum `
              -Cluster $clusterName `
              -CloudWitness `
              -AccountName $saName `
              -AccessKey $saKey
          }
      when: cluster_create is succeeded

※実運用では ansible_become_password や Storage Account のアクセスキーは
ansible-vault などで暗号化して管理することを推奨します。

💡 補足:権限エラーでハマったポイント

最初にこのPlaybookを実行した際、以下のようなエラーに遭遇しました。

You do not have administrative privileges on the server 'wsfc-node04.wsfc.lab.local'.
Requested registry access is not allowed.

つまり、クラスター作成に利用するドメインアカウントwsfc\svc-wsfc-admin
各ノードのローカル Administrators グループに追加されていないのが原因でした。

これを解消するには、各ノードで次のコマンドを実行し、svc-wsfc-adminをローカル管理者に追加する必要があります。

Add-LocalGroupMember -Group "Administrators" -Member "wsfc\svc-wsfc-admin"

この追加後にPlaybookを再実行すると、クラスターが正常に構成されました。

Playbook 実行後、いずれかのノード(例:wsfc-node03)に RDP し、PowerShell からクラスタ状態を確認します。

PS C:\Windows\system32> Get-Cluster

Name
----
WSFCCluster02

PS C:\Windows\system32> Get-ClusterNode

Name        State Type
----        ----- ----
wsfc-node03 Up    Node
wsfc-node04 Up    Node


PS C:\Windows\system32> Get-ClusterQuorum

Cluster              QuorumResource
-------              --------------
WSFCCluster02        Cloud Witness

クラスターマネージャーからも右ペインのConnect to Clusterを選択し、<CLuster on this server...>を選択して接続することでクラスターの状態を確認できます。
image.png
※最後に共有ディスクの追加だけGUIで行いました。
image.png

まとめ

実際にやってみて強く感じたのは、自動化するには「手作業でやっていること」を一度きちんと言語化して分解し、それをコードとして表現し直す必要があるということでした。
これは思っている以上に骨が折れる作業で、少なくとも準備フェーズだけ見れば、GUI でポチポチ構成した方が圧倒的に早いですし、わかりやすいなと思います。

それでも、一度 Playbook に落とし込んでしまえば、同じ構成を何度でも再現でき、「環境を壊してやり直す」「パラメータだけ変えて検証を繰り返す」といったことが怖くなくなるように思います。 初期の労力と引き換えに、長い目で見ればかなりの効率化と安心感を得られることを、この一年でAnsible等のIaCツールに触れて実感しました。

来年もadvent calenderに投稿できたらいいなと思っています!
ここまで読んでいただき、ありがとうございました!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?