マルチライター ディスクを使用して Linux 上で SQL Server フェイルオーバー クラスタ インスタンスを構成する

Compute Engine の 2 つの異なるゾーンで SQL Server の高可用性を実現するには、マルチライター ディスクを使用する Linux 上に SQL Server フェイルオーバー クラスタ インスタンス(FCI)をデプロイします。従来の共有なしアーキテクチャとは異なり、この構成では、異なるゾーンのノードを同じディスクに同時に接続できます。このガイドでは、Google Cloud Hyperdisk の低レイテンシの同期レプリケーションを使用して、Compute Engine の Linux に可用性の高い SQL Server FCI をデプロイする方法について説明します。

この設計により、ゾーンでサービスが停止した場合でも、SQL Server の可用性が維持されます。クラスタ オーケストレーション用の Pacemaker と Compute Engine のクロスゾーン復元力を組み合わせることで、共有ストレージのシンプルさを必要とするミッション クリティカルなデータベース ワークロードに、堅牢で高性能なソリューションを提供できます。

マルチライター ディスクで高可用性を実装するメリット

Linux で Always On 可用性グループ(AG)の代わりにマルチライター ディスクを使用する SQL Server FCI を使用すると、複数のデータコピーの管理の複雑さと、AG 構成で発生する同期オーバーヘッドが解消されます。

共有ボリューム アーキテクチャは、各ノードで完全なデータレプリカを使用する AG アーキテクチャと比較して、ストレージ効率も優れています。共有ボリュームを使用すると、ミラーリング シナリオでディスク費用を削減することもできます。

このアーキテクチャの主なハイライト

  • ゾーン冗長性: ノード障害やゾーン停止というまれな事態が発生した場合のデータ保護。
  • 管理の簡素化: Always On 可用性グループと比較して、複数のデータコピーの管理の複雑さが軽減されます。
  • ストレージ効率: データとログに単一の共有ボリュームを使用し、マルチライター機能を使用して最適化します。
  • Linux ネイティブ オーケストレーション: 業界標準の高可用性拡張機能(HAE)を使用して、シームレスなフェイルオーバーを実現します。

オンプレミス環境では、フェイルオーバーが発生したときに、WSFC が ARP 通知を実行して、IP アドレスの変更をネットワーク機器に通知できます。ただし、Google Cloudは ARP のアナウンスメントを無視します。したがって、内部ロードバランサを実装する必要があります(Windows Server フェイルオーバー クラスタリングの実行を参照)。

アーキテクチャ

この記事は、SQL Server、Active Directory、Compute Engine の基本的な知識があることを前提としています。

目標

このチュートリアルでは、目標を達成するために次のタスクを行う方法について説明します。

  • Linux に SQL Server デプロイを作成します。
  • マルチライター ディスクを作成、アタッチ、構成します。
  • Pacemaker クラスタを構成します。
  • ロードバランサを設定します。
  • フェイルオーバー テストを実行します。

費用

このチュートリアルでは、以下を含む、 Google Cloudの課金対象となるコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

始める前に

  1. このチュートリアルでは Google Cloud プロジェクトが必要です。新しいプロジェクトを作成することも、すでに作成済みのプロジェクトを選択することもできます。

    1. Google Cloud コンソールのプロジェクト セレクタページで、 Google Cloud プロジェクトを選択または作成します。

      プロジェクトの選択または作成に必要なロール

      • プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
      • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。

      プロジェクト セレクタに移動

    2. Google Cloud プロジェクトに対して課金が有効になっていることを確認します

    3. Google Cloud コンソールで Cloud Shell をアクティブにします。

      Cloud Shell をアクティブにする

プロジェクトとネットワークを準備する

SQL Server FCI をデプロイするために Google Cloud プロジェクトと VPC を準備するには、次の操作を行います。

  1. Google Cloud コンソールで、[Cloud Shell をアクティブにする] Cloud Shell をアクティブにします。 ボタンをクリックして Cloud Shell を開きます。

    Google Cloud コンソールに移動

  2. デフォルトのプロジェクト ID を設定します。

    gcloud config set project PROJECT_ID
    

    PROJECT_ID は、 Google Cloud プロジェクトの ID に置き換えます。

  3. デフォルトのリージョンを設定します。

    gcloud config set compute/region REGION
    

    REGION は、デプロイするリージョンの ID に置き換えます。

クラスタノードを作成する

2 つの VM をクラスタノードとしてデプロイし、3 つ目の VM を専用クライアントとしてデプロイして、接続とフェイルオーバーのパフォーマンスを検証します。

  1. 残りのコマンドで使用する次の変数を初期化します。

    BOOT_DISK_SIZE=50
    BOOT_IOPS=10000
    BOOT_THROUGHPUT=400
    DATA_IOPS=10000
    DATA_THROUGHPUT=400
    DATA_DISK_SIZE=200
    REGION=$(gcloud config get-value compute/region)
    ZONE1=$REGION-a
    ZONE2=$REGION-b
    SUBNET=SUBNET_NAME
    MACHINE_TYPE=c3-standard-8
    VPC_NAME=VPC_NAME
    
  2. 2 つのリージョン ディスク(1 つはデータディスク、もう 1 つはログ用)を作成します。両方のインスタンスがディスクにアクセスできるようにするには、--access-mode=READ_WRITE_MANY フラグを使用して、両方のディスクでマルチライター モードを有効にします。

    gcloud compute disks create sqlfci-mw-data-disk \
    --size=$DATA_DISK_SIZE \
    --type=hyperdisk-balanced-high-availability \
    --region=$REGION \
    --replica-zones=$ZONE1,$ZONE2 \
    --provisioned-iops=$DATA_IOPS \
    --provisioned-throughput=$DATA_THROUGHPUT \
    --access-mode=READ_WRITE_MANY
    
    gcloud compute disks create sqlfci-mw-log-disk \
    --size=$DATA_DISK_SIZE \
    --type=hyperdisk-balanced-high-availability \
    --region=$REGION \
    --replica-zones=$ZONE1,$ZONE2 \
    --provisioned-iops=$DATA_IOPS \
    --provisioned-throughput=$DATA_THROUGHPUT \
    --access-mode=READ_WRITE_MANY
    
  3. Linux VM を作成し、作成したマルチライター ディスクをアタッチします。

    gcloud compute instances create node-1 \
    --boot-disk-size=$BOOT_DISK_SIZE \
    --boot-disk-type=hyperdisk-balanced \
    --boot-disk-provisioned-iops=$BOOT_IOPS \
    --boot-disk-provisioned-throughput=$BOOT_THROUGHPUT \
    --zone $ZONE1 \
    --machine-type $MACHINE_TYPE \
    --subnet $SUBNET \
    --image-family ubuntu-2204-lts \
    --image-project ubuntu-os-cloud \
    --disk="name=sqlfci-mw-data-disk,scope=regional,mode=rw" \
    --disk="name=sqlfci-mw-log-disk,scope=regional,mode=rw" \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw \
    --tags=sqlfci
    
    gcloud compute instances create node-2 \
    --boot-disk-size=$BOOT_DISK_SIZE \
    --boot-disk-type=hyperdisk-balanced \
    --boot-disk-provisioned-iops=$BOOT_IOPS \
    --boot-disk-provisioned-throughput=$BOOT_THROUGHPUT \
    --zone $ZONE2 \
    --machine-type $MACHINE_TYPE \
    --subnet $SUBNET \
    --image-family ubuntu-2204-lts \
    --image-project ubuntu-os-cloud \
    --disk="name=sqlfci-mw-data-disk,scope=regional,mode=rw" \
    --disk="name=sqlfci-mw-log-disk,scope=regional,mode=rw" \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw \
    --tags=sqlfci
    
  4. 接続のテストに使用する Windows クライアント VM cl-node を作成します。

    gcloud compute instances create cl-node \
    --boot-disk-size=100 \
    --boot-disk-type=hyperdisk-balanced \
    --machine-type $MACHINE_TYPE \
    --image-family windows-2025 \
    --image-project windows-cloud \
    --zone $ZONE1 \
    --subnet $SUBNET \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw
    

内部ロードバランサを作成する

  1. クラスタとロードバランサの IP アドレスを予約します。

    gcloud compute addresses create sqlfci-lb-ipaddress \
    --region=$REGION \
    --subnet=$SUBNET \
    --purpose="SHARED_LOADBALANCER_VIP"
    CLUSTER_ADDRESS=$(gcloud compute addresses describe sqlfci-lb-ipaddress \
    --region $REGION \
    --format=value\(address\)) && \
    echo "Cluster IP address: $CLUSTER_ADDRESS"
    
  2. クラスタのヘルスチェックを作成します。

    gcloud compute health-checks create tcp sqlfci-healthcheck \
    --port="60008" \
    --region=$REGION \
    --check-interval=3 \
    --timeout=2 \
    --unhealthy-threshold=2 \
    --healthy-threshold=5
    
  3. ヘルスチェック ポートへの接続を許可するには、ファイアウォール ルールを作成します。

    gcloud compute firewall-rules create "allow-sqlfci-healthcheck-60008" \
    --allow "tcp:60008" \
    --target-tags sqlfci \
    --network $VPC_NAME \
    --source-ranges="35.191.0.0/16,130.211.0.0/22" \
    --priority="1000"
    

    詳細については、ヘルスチェックのファイアウォール ルールをご覧ください。

  4. クラスタノードのインスタンス グループを作成します。

    gcloud compute instance-groups unmanaged create sqlfci-1-uig \
    --zone=$ZONE1
    gcloud compute instance-groups unmanaged add-instances sqlfci-1-uig \
    --zone=$ZONE1 \
    --instances=node-1
    
    gcloud compute instance-groups unmanaged create sqlfci-2-uig \
    --zone=$ZONE2
    gcloud compute instance-groups unmanaged add-instances sqlfci-2-uig \
    --zone=$ZONE2 \
    --instances=node-2
    
  5. ロードバランサのバックエンド サービスを作成します。

    gcloud compute backend-services create sqlfci-backend-services \
    --region=$REGION \
    --load-balancing-scheme="INTERNAL" \
    --protocol="TCP" \
    --health-checks=sqlfci-healthcheck \
    --health-checks-region=$REGION
    
    gcloud compute backend-services add-backend sqlfci-backend-services \
    --region=$REGION \
    --instance-group=sqlfci-1-uig \
    --instance-group-zone=$ZONE1
    
    gcloud compute backend-services add-backend sqlfci-backend-services \
    --region=$REGION \
    --instance-group=sqlfci-2-uig \
    --instance-group-zone=$ZONE2
    
  6. ロードバランサの転送ルールを作成します。

    gcloud compute forwarding-rules create "sqlfci-forwarding-rule" \
    --load-balancing-scheme=INTERNAL \
    --network=$VPC_NAME \
    --subnet=$SUBNET \
    --region=$REGION \
    --address=$CLUSTER_ADDRESS \
    --ip-protocol="TCP" \
    --ports="ALL" \
    --backend-service=sqlfci-backend-services \
    --backend-service-region=$REGION
    
  7. Cloud Storage バケットを作成して、プライマリ クラスタノードからセカンダリ クラスタノードにファイルを転送します。

    gcloud storage buckets create gs://BUCKET_NAME \
    --location=$REGION \
    --public-access-prevention
    

    BUCKET_NAME は、作成するバケットの名前に置き換えます。

    詳細については、バケットを作成するをご覧ください。

必要なソフトウェアをインストールする

フェイルオーバー クラスタに参加する 2 つの Linux VM(node-1node-2)に、SQL Server エンジンとクラスタ管理をダウンロード、インストール、構成します。

  1. SSH を使用して各 VM に接続します。詳細については、Linux VM に接続するSSH ネットワーク アクセスを制御する際のベスト プラクティスをご覧ください。

  2. node-1node-2hosts file を更新します。

    1. 編集用に hosts file を開きます。

      sudo vi /etc/hosts
      
    2. 各 Linux VM の内部 IP アドレスを見つけて、ホストエントリをファイルの末尾に追加します。

      Compute Engine に移動

      NODE1_INTERNAL_IP node-1
      NODE2_INTERNAL_IP node-2
      

      NODE1_INTERNAL_IPNODE2_INTERNAL_IP は、各 Linux VM の内部 IP アドレスに置き換えます。

  3. VM 間の通信を確認します。Always On 可用性グループに参加するすべての VM は、他の VM と通信できる必要があります。各 Linux VM に戻り、各 VM からコマンドを実行して、すべての VM が相互に通信できることを確認します。

    ping -c 4 node-1
    ping -c 4 node-2
    

    出力は次のようになります。

    PING node-1 (10.128.0.37) 56(84) bytes of data.
    64 bytes from node-1 (10.128.0.37): icmp_seq=1 ttl=128 time=1.91 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=2 ttl=128 time=0.234 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=3 ttl=128 time=0.249 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=4 ttl=128 time=0.263 ms
    
  4. SQL Server 2025 をインストールします。

    1. SQL Server リポジトリをシステムに追加します。

      curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
      curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2025.list | sudo tee /etc/apt/sources.list.d/mssql-server-2025.list
      sudo apt-get update
      
    2. SQL Server をインストールします。

      sudo apt-get install -y mssql-server
      
    3. SQL Server デベロッパー ツールをインストールします。フェイルオーバー クラスタに参加する 2 つの Linux VM に SQL Server ツールをダウンロードしてインストールします。

      curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
      sudo apt-get update
      
      sudo ACCEPT_EULA=Y apt-get install -y mssql-tools18 unixodbc-dev
      
  5. Pacemaker をインストールします。Pacemaker は、Corosync クラスタ エンジンで使用されるオープンソースの高可用性リソース マネージャー ソフトウェアです。このセクションでは、両方のクラスタ VM に Pacemaker をインストールします。

    1. node-1node-2 に Pacemaker をインストールします。

      sudo apt-get install -y pacemaker pcs fence-agents resource-agents pacemaker-cli-utils crmsh
      
    2. Pacemaker 用の SQL Server リソース エージェントをインストールします。

      sudo apt-get install -y mssql-server-ha
      
  6. VM でファイアウォールが有効になっている場合は、SQL Server のファイアウォールを開きます。

    1. 次のコマンドを実行して、Uncomplicated Firewall がインストールされて有効になっているかどうかを確認します。

      sudo ufw status
      
    2. ステータスが有効になっている場合は、次のコマンドを実行してポートを開きます。ファイアウォール サービスが実行されていない場合は、この手順を無視できます。

      sudo ufw allow 1433
      sudo ufw allow 5022
      sudo ufw reload
      

プライマリ データベース ノードを構成する

このセクションでは、2 つのマルチライター ディスクを初期化し、ボリューム グループと論理グループを使用して各ディスクを設定します。

LVM を構成します。

LVM の設定を構成します。

  1. 既存の構成をバックアップします。

    sudo cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.bak
    
  2. システム ID ソースを更新します。

    sudo sed -i 's/^\(\s*system_id_source\s*=\s*\)"none"/\1"uname"/' /etc/lvm/lvm.conf
    
  3. 変更が正常に完了したことを確認します。

    grep 'system_id_source *= *"uname"' /etc/lvm/lvm.conf
    
  4. LVM ボリューム グループと論理ボリュームを構成します。

    sudo pvcreate /dev/nvme0n2 /dev/nvme0n3
    sudo pvs
    sudo vgcreate vgdata /dev/nvme0n2
    sudo lvcreate -l 100%FREE -n lvdata vgdata
    sudo vgcreate vglogtmp /dev/nvme0n3
    sudo lvcreate -l 70%FREE  -n lvlog vglogtmp
    sudo lvcreate -l 100%FREE -n lvtmp vglogtmp
    sudo vgs -o+systemid
    
  5. 64 KB のブロックサイズで xfs ファイル システムを使用してボリュームをフォーマットします。

    sudo mkfs.xfs -d su=64k,sw=1 -L data /dev/vgdata/lvdata -f
    sudo mkfs.xfs -d su=64k,sw=1 -L dblog /dev/vglogtmp/lvlog -f
    sudo mkfs.xfs -d su=64k,sw=1 -L tmp /dev/vglogtmp/lvtmp -f
    
  6. ボリュームが作成されたことを確認します。

    sudo lvs
    

ディスクをマウントしてフォーマットする

共有ディスクのマウント ポイントを設定し、mssql ユーザーにアクセス権を付与します。

  1. 新しいボリュームのマウント ポイントを作成します。

    sudo mkdir /mssql
    sudo mkdir -p /mssql/db_data
    sudo mkdir -p /mssql/db_log
    sudo mkdir -p /mssql/db_temp
    
  2. LVM ボリュームをマウント ポイントにマウントします。

    sudo mount /dev/vgdata/lvdata /mssql/db_data
    sudo mount /dev/vglogtmp/lvlog /mssql/db_log
    sudo mount /dev/vglogtmp/lvtmp /mssql/db_temp
    
  3. mssql ユーザーをマウント ポイントの所有者として設定します。

    sudo chown mssql:mssql /mssql/db_data
    sudo chown mssql:mssql /mssql/db_log
    sudo chown mssql:mssql /mssql/db_temp
    
  4. SQL Server を構成します。

    1. マスター データベースを共有ストレージに再配置する変数を設定し、mssql-conf ツールを実行します。

      sudo MSSQL_MASTER_DATA_FILE="/mssql/db_data/master.mdf" MSSQL_MASTER_LOG_FILE="/mssql/db_data/mastlog.ldf" /opt/mssql/bin/mssql-conf setup
      
    2. SQL Server のエディションとして [Developer] エディションを選択し、ライセンス契約に同意します。

      Developer エディションにはすべてのエンタープライズ機能が含まれていますが、本番環境以外でのみ使用できます。詳しくは、SQL Server のエディションMicrosoft ライセンスをご覧ください。

    3. SA アカウントのパスワードを指定します。

    4. mssql-server サービスが実行されていることを確認します。

      systemctl status mssql-server --no-pager
      

SQL Server と Pacemaker を構成する

  1. Pacemaker 用の SQL Server ユーザーを作成します。SA_PASSWORD は SQL Server の SA アカウントのパスワードに置き換え、PA_PASSWORDpacemaker アカウントに使用するパスワードに置き換えます。

    QUERY="
    CREATE LOGIN [pacemaker] with PASSWORD= N'PA_PASSWORD';
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemaker];
    GO"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  2. Pacemaker のログインとパスワードを SQL Server のシークレット フォルダに追加します。

    {
      echo 'pacemaker'
      echo PA_PASSWORD'
    } | sudo tee /var/opt/mssql/secrets/passwd > /dev/null
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    
  3. 新しいデータ、ログ、一時ファイルの場所を使用するように SQL Server の構成を更新します。また、SQL Server の推奨設定も行います。

    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /mssql/db_data
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdumpdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf traceflag 9944 3979 on
    sudo /opt/mssql/bin/mssql-conf set control.alternatewritethrough 0
    sudo /opt/mssql/bin/mssql-conf set control.writethrough 1
    

TempDB を共有ディスクに移動する

  1. TempDB ファイルのリストを取得し、それを使用して Alter クエリを作成します。このクエリは、次の手順で TempDB ファイルの新しい場所を設定するために使用されます。

    QUERY="
    SET NOCOUNT ON;
    SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + f.name + '],' + ' FILENAME = ''/mssql/db_temp/' + f.name + CASE WHEN f.type = 1 THEN '.ldf' ELSE '.mdf' END + ''');' FROM sys.master_files f WHERE f.database_id = DB_ID(N'tempdb');"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  2. 前のコマンドの出力をキャプチャします。この出力を使用して、次に実行するコマンドを作成します。

    QUERY="QUERY_OUTPUT"
    

    出力を使用するクエリの例:

    QUERY="
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev], FILENAME = '/mssql/db_temp/tempdev.mdf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [templog], FILENAME = '/mssql/db_temp/templog.ldf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev2], FILENAME = '/mssql/db_temp/tempdev2.mdf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev3], FILENAME = '/mssql/db_temp/tempdev3.mdf');"
    

  3. 生成された SQL コマンドを実行して、TempDB ファイルを移動します。

    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  4. 変更を反映させるために、SQL Server サービスを再起動します。

    sudo systemctl restart mssql-server.service
    
  5. TempDB ファイルが作成されたことを確認します。

    ls -l /mssql/db_temp/
    
  6. SQL Server サービスが実行されていることを確認します。

    systemctl status mssql-server --no-pager
    

HAProxy を構成する

  1. hacluster の新しいパスワードを設定します。

    sudo passwd hacluster
    
  2. 設定を完了し、ネットワーク ロードバランサが正しく設定されているかどうかをテストするには、両方のクラスタノードに HAProxy tcp listener をインストールして構成します。

    1. HAProxy をインストールします。

      sudo apt-get install haproxy
      
    2. Y」と入力してインストールを完了します。

    3. haproxy.cfg ファイルを編集します。

      sudo vi /etc/haproxy/haproxy.cfg
      
    4. haproxy.cfg filedefaults セクションで、モードを tcp に変更します。

    5. haproxy.cfg ファイルの末尾に次のセクションを追加します。

      #---------------------------------------------------------------
      # Set up health check listener for SQL Server Availability Group
      #---------------------------------------------------------------
      listen healthcheck
      bind *:60008
      
  3. HAProxy サービスを起動します。

    sudo systemctl start haproxy.service
    sudo systemctl status haproxy.service
    
  4. HAProxy サービスを停止して無効にします。

    sudo systemctl stop haproxy.service
    sudo systemctl disable haproxy.service
    
  5. 次のコマンドを使用して、マシンキーファイルを Cloud Storage にアップロードします。

    sudo gcloud storage cp /var/opt/mssql/secrets/machine-key gs://BUCKET_NAME/
    

    BUCKET_NAME は、作成したバケットの名前に置き換えます。

  6. SQL Server サービスを停止して無効にします。この時点から、サービスはクラスタによって制御されます。

    sudo systemctl stop mssql-server.service
    sudo systemctl disable mssql-server.service
    
  7. 共有ストレージのマウントを解除します。

    sudo umount /mssql/db_data
    sudo umount /mssql/db_log
    sudo umount /mssql/db_temp
    
  8. 既存のデフォルト クラスタ構成をクリーンアップします。

    sudo pcs cluster destroy
    

セカンダリ ノードを構成する

  1. LVM ボリュームのマウント ポイントを作成します。このディスクは node-1 と共有されているため、ディスクをフォーマットする必要はありません。node-1 を構成したときに、ディスクをフォーマットして LVM ボリュームを構成しました。

    sudo mkdir /mssql
    sudo mkdir -p /mssql/db_data
    sudo mkdir -p /mssql/db_log
    sudo mkdir -p /mssql/db_temp
    
    sudo chown mssql:mssql /mssql/db_data
    sudo chown mssql:mssql /mssql/db_log
    sudo chown mssql:mssql /mssql/db_temp
    
  2. SQL Server を構成します。

    1. マスター データベースを共有データディスクに再配置するには、次の変数を設定してから、mssql-conf ツールを実行して変更を適用します。

      sudo MSSQL_MASTER_DATA_FILE="/mssql/db_data/master.mdf" MSSQL_MASTER_LOG_FILE="/mssql/db_data/mastlog.ldf" /opt/mssql/bin/mssql-conf setup
      
    2. SQL Server のエディションとして [Developer] エディションを選択し、ライセンス契約に同意します。

      Developer エディションにはすべてのエンタープライズ機能が含まれていますが、本番環境以外でのみ使用できます。詳しくは、SQL Server のエディションMicrosoft ライセンスをご覧ください。

    3. SA アカウントのパスワードを指定します。

    4. mssql-server サービスが実行されていることを確認します。

      systemctl status mssql-server --no-pager
      
  3. Pacemaker クラスタの SQL Server ユーザーを作成します。SA_PASSWORD は SQL Server の SA アカウントのパスワードに置き換え、PA_PASSWORDpacemaker アカウントに使用するパスワードに置き換えます。

    QUERY="
    CREATE LOGIN [pacemaker] with PASSWORD= N'PA_PASSWORD';
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemaker];
    GO"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  4. Pacemaker のログインとパスワードを SQL Server のシークレット フォルダに追加します。

    {
      echo 'pacemaker'
      echo 'PA_PASSWORD'
    } | sudo tee /var/opt/mssql/secrets/passwd > /dev/null
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    
  5. 新しいデータ、ログ、一時ファイルの場所を使用するように SQL Server の構成を更新します。SQL Server の推奨設定も設定します。

    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /mssql/db_data
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdumpdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf traceflag 9944 3979 on
    sudo /opt/mssql/bin/mssql-conf set control.alternatewritethrough 0
    sudo /opt/mssql/bin/mssql-conf set control.writethrough 1
    
  6. TempDB を共有データ ディスクに移動します。

    1. TempDB ファイルのリストを取得し、それを使用して Alter クエリを作成します。

      QUERY="
      SET NOCOUNT ON;
      SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + f.name + '],' + ' FILENAME = ''/mssql/db_temp/' + f.name + CASE WHEN f.type = 1 THEN '.ldf' ELSE '.mdf' END + ''');' FROM sys.master_files f WHERE f.database_id = DB_ID(N'tempdb');"
      
      /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
      
    2. 前のコマンドの出力をキャプチャします。この出力を使用して、次に実行するコマンドを作成します。

      QUERY="QUERY_OUTPUT"
      

      出力を使用したクエリの例:

      QUERY="
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev], FILENAME = '/mssql/db_temp/tempdev.mdf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [templog], FILENAME = '/mssql/db_temp/templog.ldf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev2], FILENAME = '/mssql/db_temp/tempdev2.mdf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev3], FILENAME = '/mssql/db_temp/tempdev3.mdf');"
      
    3. TempDB ファイルを移動するには、生成された SQL コマンドを実行します。

      /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
      
    4. 変更を有効にするには、SQL Server サービスを再起動します。

      sudo systemctl restart mssql-server.service
      
    5. SQL Server サービスが実行されていることを確認します。

      sudo systemctl status mssql-server --no-pager
      
    6. TempDB ファイルが作成されたことを確認します。

      ls -l /mssql/db_temp/
      
  7. SQL Server サービスを停止して一時的に無効にします。

    sudo systemctl stop mssql-server.service
    sudo systemctl disable mssql-server.service
    
  8. 両方のノードで SQL Server に同じ鍵が使用されるようにするには、node-1 からマシンキーファイルをダウンロードします。

    sudo rm /var/opt/mssql/secrets/machine-key
    sudo gcloud storage cp gs://BUCKET_NAME/machine-key /var/opt/mssql/secrets/machine-key
    sudo chown mssql:mssql /var/opt/mssql/secrets/machine-key
    sudo chmod 0600  /var/opt/mssql/secrets/machine-key
    
  9. LVM の設定を構成します。

    1. 既存の構成をバックアップします。

      sudo cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.bak
      
    2. システム ID ソースを更新します。

      sudo sed -i 's/^\(\s*system_id_source\s*=\s*\)"none"/\1"uname"/' /etc/lvm/lvm.conf
      

      次のコマンドを実行して変更を確認します。

      cat /etc/lvm/lvm.conf | grep uname
      

      出力は次のようになります。

      #     Set the system ID from the hostname (uname) of the system.
      system_id_source = "uname"
      
    3. 変更が正常に完了したことを確認します。

      grep 'system_id_source *= *"uname"' /etc/lvm/lvm.conf
      
  10. hacluster の新しいパスワードを設定します。

    sudo passwd hacluster
    
  11. 設定を完了し、ネットワーク ロードバランサが正しく設定されているかどうかをテストするには、両方のクラスタノードに HAProxy tcp listener をインストールして構成します。

    1. HAProxy をインストールします。

      sudo apt-get install haproxy
      

    2. [Y] を選択してインストールを完了します。

    3. haproxy.cfg ファイルを編集します。

      sudo vi /etc/haproxy/haproxy.cfg
      
    4. haproxy.cfg file のデフォルト セクションで、モードを tcp に変更します。

    5. haproxy.cfg ファイルの末尾に次のセクションを追加します。

      #---------------------------------------------------------------
      # Set up health check listener for SQL Server Availability Group
      #---------------------------------------------------------------
      listen healthcheck
      bind *:60008
      
    6. HAProxy サービスを起動します。

      sudo systemctl start haproxy.service
      sudo systemctl status haproxy.service
      
  12. HAProxy サービスを停止して無効にします。

    sudo systemctl stop haproxy.service
    sudo systemctl disable haproxy.service
    
  13. 既存のデフォルト クラスタ構成をクリーンアップします。

    sudo pcs cluster destroy
    

クラスタ構成を完成させる

node-1 に戻って、クラスタの構成を続行します。

  1. hacluster ユーザーとして認証します。

    sudo pcs host auth node-1 node-2 -u hacluster -p "HA_PASSWORD"
    
  2. ubuntu_fci というクラスタを作成します。

    sudo pcs cluster setup ubuntu_fci node-1 addr="NODE1_INTERNAL_IP" node-2 addr="NODE2_INTERNAL_IP" --start --enable
    
  3. 2 つのノードクラスタに no-quorum-policy を設定します。

    sudo pcs property set no-quorum-policy="ignore"
    
  4. 仮想 IP アドレス クラスタ リソースを作成します。

    sudo pcs resource create pcs-cluster-vip ocf:heartbeat:IPaddr2 ip="CLUSTER_ADDRESS" cidr_netmask=32 nic=ens3 op monitor interval=30s
    

    CLUSTER_ADDRESS は、前に予約した IP アドレスに置き換えます。

  5. すべての共有ボリュームのクラスタ リソース オブジェクトを作成します。

    sudo pcs resource create vgdata ocf:heartbeat:LVM-activate vgname=vgdata vg_access_mode=system_id activation_mode=exclusive
    sudo pcs resource create vglogtmp ocf:heartbeat:LVM-activate vgname=vglogtmp vg_access_mode=system_id activation_mode=exclusive
    sudo pcs resource create data_dir ocf:heartbeat:Filesystem device="/dev/mapper/vgdata-lvdata" directory="/mssql/db_data" fstype="xfs"
    sudo pcs resource create log_dir ocf:heartbeat:Filesystem device="/dev/mapper/vglogtmp-lvlog" directory="/mssql/db_log" fstype="xfs"
    sudo pcs resource create tmp_dir ocf:heartbeat:Filesystem device="/dev/mapper/vglogtmp-lvtmp" directory="/mssql/db_temp" fstype="xfs"
    
  6. リソース グループを作成し、作成したすべてのオブジェクトを新しいグループに追加します。

    sudo pcs resource group add sql_group pcs-cluster-vip vgdata vglogtmp data_dir log_dir tmp_dir
    
  7. Microsoft SQL Server サービスのクラスタ リソースを作成し、既存のリソース グループに追加します。

    sudo pcs resource create sql_fci ocf:mssql:fci  op stop timeout=60s --group sql_group
    
  8. HAProxy のクラスタ リソースを作成し、同じグループに追加します。

    sudo pcs resource create pcs-healthcheck systemd:haproxy.service op monitor interval=20s timeout=30s --group sql_group
    
  9. リソースの起動順序を制御するクラスタ制約を作成します。

    sudo pcs constraint order set  pcs-cluster-vip vgdata vglogtmp data_dir log_dir tmp_dir sql_fci pcs-healthcheck
    

STONITH フェンスを設定する

STONITH は、HA クラスタ内のノードの整合性を維持するためのフェンシング戦略です。STONITH サービスはノードレベルで動作し、応答しないノードや不明な状態のノードからクラスタを保護します。 Google Cloudの Compute Engine 専用の fence_gce フェンシング デバイスをおすすめします。

フェンシング デバイスを設定する

  1. fence_gce - Compute Engine のフェンス エージェントが node-1 にインストールされているかどうかを確認します。

    sudo pcs stonith list | grep fence_gce
    

    詳しくは以下をご覧ください。

  2. クラスタ フェンシング リソースを構成します。

    sudo pcs stonith create node-1-fence fence_gce \
    plug=node-1 \
    zone=ZONE1 \
    project=PROJECT_ID \
    pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30 \
    op monitor interval="300s" timeout="120s" \
    op start interval="0" timeout="60s"
    
    sudo pcs stonith create node-2-fence fence_gce \
    plug=node-2 \
    zone=ZONE2 \
    project=PROJECT_ID \
    pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30 \
    op monitor interval="300s" timeout="120s" \
    op start interval="0" timeout="60s"
    

    ZONE1ZONE2 は、Linux VM がデプロイされているゾーンに置き換え、PROJECT_ID はプロジェクト ID に置き換えます。

  3. フェンシング エージェントのステータスは、status コマンドを実行して確認できます。

    sudo fence_gce -o status -n node-1 --zone=ZONE1
    sudo fence_gce -o status -n node-2 --zone=ZONE2
    

    出力は次のようになります。

    Status: ON
    

ZONE1ZONE2 は、Linux VM がデプロイされているゾーンに置き換えます。

  1. フェンシング デバイスのロケーション制約を作成して、目的のインスタンスでのみ実行されるようにします。

    sudo pcs constraint location node-1-fence avoids node-1
    sudo pcs constraint location node-2-fence avoids node-2
    
  2. Pacemaker クラスタでフェンシングを有効にし、クラスタ フェンシング タイムアウトを設定します。

    sudo pcs -f stonith_cfg property set stonith-enabled=true
    sudo pcs property set stonith-timeout="300s"
    
  3. クラスタの起動プロセスをクリーンアップします。

    sudo pcs resource cleanup
    
  4. クラスタのステータスを確認します。

    sudo crm status
    

    出力は次のようになります。

      Cluster Summary:
        * Stack: corosync
        * Current DC: node-1 (version 2.1.2-ada5c3b36e2) - partition with quorum
        * Last updated: Tue Jun  2 21:36:47 2026
        * Last change:  Mon Apr 27 12:31:58 2026 by root via crm_resource on node-1
        * 2 nodes configured
        * 10 resource instances configured
    
      Node List:
        * Online: [ node-1 node-2 ]
    
      Full List of Resources:
        * Resource Group: sql_group:
          * pcs-cluster-vip   (ocf:heartbeat:IPaddr2):         Started node-2
          * vgdata    (ocf:heartbeat:LVM-activate):    Started node-2
          * vglogtmp  (ocf:heartbeat:LVM-activate):    Started node-2
          * data_dir  (ocf:heartbeat:Filesystem):      Started node-2
          * log_dir   (ocf:heartbeat:Filesystem):      Started node-2
          * tmp_dir   (ocf:heartbeat:Filesystem):      Started node-2
          * sql_fci   (ocf:mssql:fci):                 Started node-2
          * pcs-healthcheck   (systemd:haproxy.service):       Started node-2
        * node-1-fence       (stonith:fence_gce):     Started node-2
        * node2-fence        (stonith:fence_gce):     Started node-1
    

フェンシング デバイスをテストする

フェンシング デバイスの設定後、次の手順でテストすることをおすすめします。

  1. node-2 でフェンスを停止します。

    1. node-1 に接続し、次のコマンドを実行して、クラスタから node-2 に関連付けられたフェンス デバイスをテストします。

      fence_gce -o off -n node-2 --zone=ZONE2
      

      出力は次のようになります。

      Success: Powered OFF
      
    2. クラスタのステータスを確認します。

      sudo crm status
      

      出力は次のようになります。

        Cluster Summary:
          * Stack: corosync
          * Current DC: node-1 (version 2.1.2-ada5c3b36e2) - partition with quorum
          * Last updated: Tue Jun  2 21:52:00 2026
          * Last change:  Mon Apr 27 12:31:58 2026 by root via crm_resource on node-1
          * 2 nodes configured
          * 10 resource instances configured
    
        Node List:
          * Online: [ node-1 ]
          * OFFLINE: [ node-2 ]
    
        Full List of Resources:
          * Resource Group: sql_group:
            * pcs-cluster-vip   (ocf:heartbeat:IPaddr2): Started node-1
            * vgdata    (ocf:heartbeat:LVM-activate):    Started node-1
            * vglogtmp  (ocf:heartbeat:LVM-activate):    Started node-1
            * data_dir  (ocf:heartbeat:Filesystem):      Started node-1
            * log_dir   (ocf:heartbeat:Filesystem):      Started node-1
            * tmp_dir   (ocf:heartbeat:Filesystem):      Started node-1
            * sql_fci   (ocf:mssql:fci):                 Started node-1
            * pcs-healthcheck   (systemd:haproxy.service):       Started node-1
          * node-1-fence       (stonith:fence_gce):     Stopped
          * node-2-fence        (stonith:fence_gce):     Started node-1
    
    1. また、Compute Engine で node-2 が無効になっていることも確認できます。

      Compute Engine に移動

  2. node-2 でフェンスを再起動します。

    1. node-1 に戻り、次のコマンドを実行してインスタンスを再起動します。

      fence_gce -o on -n node-2 --zone=ZONE2
      

      出力は次のようになります。

      Success: Powered ON
      
    2. Pacemaker と Compute Engine でクラスタのステータスを確認します。しばらくすると、node-2 がオンラインに戻ります。

       $ sudo crm status
      

フェイルオーバーをテストする

これで、フェイルオーバーが想定どおりに機能するかどうかをテストする準備が整いました。

  1. VM インスタンスにユーザー名とパスワードを作成します。
  2. リモート デスクトップを使用して VM に接続し、前のステップで作成したユーザー名とパスワードを使用してログインします。
  3. リモート デスクトップを使用して cl-node の Windows VM に接続します。
  4. PowerShell セッションを開きます。
  5. 次のスクリプトを実行してサーバーに接続します。このスクリプトは、5 秒ごとに可用性グループ リスナーを使用して SQL Server に接続し、サーバー名を照会します。

    while ($True){
      try {
        $Conn = New-Object System.Data.SqlClient.SqlConnection
        $Conn.ConnectionString = "Server=CLUSTER_ADDRESS;User ID=sa;Password=SA_PASSWORD;Initial Catalog=master"
        $Conn.Open()
    
        $Cmd =  $Conn.CreateCommand()
        $Cmd.CommandText = "SELECT SERVERPROPERTY('ComputerNamePhysicalNetBIOS')"
    
        $Result = $Cmd.ExecuteReader()
        if ($Result.Read()) {
          $currentNode = $Result.GetString(0)
          Write-Host "Current Node: $currentNode at $(Get-Date)"
        }
    
        $Conn.Close()
        Start-Sleep -Seconds 5
      }
      catch {
          Write-Host "SQL Connection Failed at $(Get-Date). Retrying..."
          Start-Sleep -Seconds 15 # Wait before retrying
      }
    }
    

    CLUSTER_ADDRESS はリスナーの IP アドレスに置き換え、SA_PASSWORD は SQL Server の SA アカウントのパスワードに置き換えます。

    出力は次のようになります。

      Current Node: node-1 at 06/09/2026 20:24:35
      Current Node: node-1 at 06/09/2026 20:24:40
      Current Node: node-1 at 06/09/2026 20:24:45
      Current Node: node-1 at 06/09/2026 20:24:50
      Current Node: node-1 at 06/09/2026 20:24:55
    

    スクリプトを実行したままにします。

  6. node-2 へのフェイルオーバーをトリガーします。node-1 から SSH ターミナルに戻り、次のコマンドを実行します。

    sudo pcs resource move sql_group node-2
    
  7. cl-node の PowerShell セッションに戻ります。

    1. 実行中のスクリプトの出力を確認して、フェイルオーバーの結果として、サーバー名が node-1 から node-2 に変更されたことを確認します。

    出力は次のようになります。

      Current Node: node-1 at 06/09/2026 20:28:51
      Current Node: node-1 at 06/09/2026 20:28:56
      SQL Connection Failed at 06/09/2026 20:29:16. Retrying...
      Current Node: node-2 at 06/09/2026 20:29:31
      Current Node: node-2 at 06/09/2026 20:29:36
    
  8. node-1 へのフェイルバックを開始します。node-1 のコマンドラインで、次のコマンドを実行します。

    sudo pcs resource move sql_group node-1
    
  9. cl-node で PowerShell に戻ります。Ctrl+C を押してスクリプトを停止します。

クリーンアップ

チュートリアルが終了したら、作成したリソースをクリーンアップして、割り当ての使用を停止し、課金されないようにできます。次のセクションで、リソースを削除または無効にする方法を説明します。

プロジェクトの削除

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. Google Cloud コンソールで [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ