サイト内の現在位置を表示しています。

DockerコンテナのHAクラスターを構築してみました(Windows) ~後編~

CLUSTERPRO オフィシャルブログ ~クラブロ~

はじめに

DockerコンテナベースアプリケーションのHAクラスターを構築してみました。Dockerコンテナの起動・停止、および、監視をCLUSTERPROが行うことで、Dockerアプリケーションを少ないノード数で簡易的に冗長化し、可用性を向上させることが可能となります。アプリケーションがDockerコンテナ形式でのみ提供されているケースでHAクラスタ化が必要になった場合などにご参考にして下さい。

本記事はWindows環境での事前準備からDockerコンテナ作成までを行う「前編」と、Dockerサービスやコンテナ制御のためのCLUSTERPRO設定を行う「後編」に分かれており、今回は「後編」になります。「前編」は popupこちら を参照して下さい。

  • 2023年4月12日追記
    以下のissueと同じと思われる原因により、環境によっては本記事で紹介しているwslコマンドの実行がエラーとなる現象を確認しております。そのためCLUSTERPROのスクリプトリソースによるwslコマンド実行が実現できない可能性があります。

この記事の内容

1. HAクラスター構築手順(CLUSTERPROの設定)

CLUSTERPRO Xのフェールオーバーグループに、仮想ディスクのマウントやDockerサービス、Dockerコンテナの起動・停止を行うスクリプトリソースを追加します。

追加するリソース

・フェールオーバーグループ(failover1)
  - スクリプトリソース(script-DockerService)
  - スクリプトリソース(script-VirtualDisk)
  - スクリプトリソース(script-DockerDB)
  - スクリプトリソース(script-DockerApp)

・監視リソース
  - カスタム監視リソース(genw-DockerService)
  - カスタム監視リソース(genw-VirtualDisk)
  - PostgreSQL監視リソース(psqlw-DockerDB)
  - カスタム監視リソース(genw-DockerApp)

  • 本記事で紹介しているスクリプトは、サンプルであり動作を保証するものではありません。
  • スクリプト中のsleepの値は参考値です。また、異常系処理は簡略化しており、スクリプトリソース非活性化失敗時の終了値チェックは行っていません。実際のご使用にあたっては要件にあわせた十分な検証をお願いします。

1.1 スクリプト実行アカウントの登録

まず、[クラスタプロパティ]の[アカウント]に[Administrator]を登録します。これは、あとで追加するスクリプトの実行ユーザーを、Administratorに設定するために必要となります。

スクリプトリソースは、既定ではローカルシステムアカウント(SYSTEM)として実行されます。しかしwslコマンドはローカルシステムアカウントでは動作しないため、Administratorユーザーで実行するように設定を変更する必要があります。

Cluster WebUIに接続し、クラスタ名の右にある[プロパティ]をクリックします。

クラスターのプロパティ

[アカウント]タブを選択します。

[追加]ボタンをクリックし、Administratorを登録します。

1.2 スクリプトリソース(Dockerサービス)の追加

Dockerサービスの起動・停止を行うためのスクリプトリソースを追加します。

スクリプトリソース(script-DockerService)

- 依存関係タブ
  - 依存するリソース: md-Docker

- 詳細タブ
  - スクリプト一覧
    - Start Script: start.bat
    - Stop Script: stop.bat
    - User Script: Activate_DockerService.ps1
    - User Script: Deactivate_DockerService.ps1

  - 調整
    - 開始の正常な戻り値: 0
    - 実行ユーザ: Administrator


各スクリプトを登録します。
各スクリプトの内容は次の通りです。

- start.bat

rem ***************************************
rem *              start.bat              *
rem ***************************************
if "%CLP_EVENT%" == "RECOVER" exit /b 0

cd %CLP_SCRIPT_PATH%
PowerShell ".\Activate_DockerService.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- stop.bat

rem ***************************************
rem *              stop.bat               *
rem ***************************************

cd %CLP_SCRIPT_PATH%
PowerShell ".\Deactivate_DockerService.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- Activate_DockerService.ps1

wsl -e sudo service docker start
if (! $?) {
  Write-Error "Failed to start docker service."
  exit 2
}

sleep 5
$ip = wsl -e hostname -I | % {$_.Split(" ")[0]}
if (! $?) {
  Write-Error "Failed to get ip address of WSL."
  wsl -e sudo service docker stop
  exit 3
}

netsh interface portproxy add v4tov4 listenaddress=* listenport=80 connectaddress=$ip connectport=80
if (! $?) {
  Write-Error "Failed to set portproxy."
  wsl -e sudo service docker stop
  exit 4
}

exit 0


- Deactivate_DockerService.ps1

netsh interface portproxy delete v4tov4 listenport=80 listenaddress=*
if (! $?) {
  Write-Error "Warning: Failed to unset portproxy."
}

wsl -e sudo service docker stop
if (! $?) {
  Write-Error "Failed to stop docker service."
  exit 2
}

exit 0

次に、[調整]ボタンをクリックします。

スクリプト調整プロパティでは、次の通り値を設定します。

- [開始]の[正常な戻り値]に0
- [実行ユーザ]にAdministrator

スクリプトリソース調整プロパティ

1.3 スクリプトリソース(仮想ディスク)の追加

仮想ディスクのマウント・アンマウントを行うためのスクリプトリソースを追加します。

スクリプトリソース(script-VirtualDisk)

- 依存関係タブ
  - 依存するリソース: script-DockerService

- 詳細タブ
  - スクリプト一覧
    - Start Script: start.bat
    - Stop Script: stop.bat
    - User Script: Config.ps1
    - User Script: Mount_VirtualDisk.ps1
    - User Script: Unmount_VirtualDisk.ps1

  - 調整
    - 開始の正常な戻り値: 0
    - 実行ユーザ: Administrator


各スクリプトを登録します。
各スクリプトの内容は次の通りです。

- start.bat

rem ***************************************
rem *              start.bat              *
rem ***************************************
if "%CLP_EVENT%" == "RECOVER" exit /b 0

cd %CLP_SCRIPT_PATH%
PowerShell ".\Mount_VirtualDisk.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- stop.bat

rem ***************************************
rem *              stop.bat               *
rem ***************************************

cd %CLP_SCRIPT_PATH%
PowerShell ".\Unmount_VirtualDisk.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- Config.ps1

$VHDX_FILE="M:\nextcloud.vhdx"
$DATA_UUID="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
$DATA_DIR="/mnt/data"

※ 上記は例です。「前編」で取得した実際の値を設定します。

- Mount_VirtualDisk.ps1

. ".\Config.ps1"

$retval=0

try {
  $ret = Mount-DiskImage $VHDX_FILE -ErrorAction "Stop"
  sleep 1
} catch {
  Write-Error "Failed to mount vhdx file."
  exit 2
}

try {
  try {
    wsl --mount $ret.DevicePath --bare
    if (! $?) {
      $retval=3
      throw "Failed to attach block devices."
    }
    sleep 3

    wsl -e sudo mount UUID=$DATA_UUID $DATA_DIR
    if (! $?) {
      $retval=4
      throw "Failed to mount device in WSL."
    }
  } catch {
    wsl --unmount
    sleep 10
    Dismount-DiskImage $VHDX_FILE > $null
    throw $_
  }
} catch {
  Write-Error $_
  exit $retval
}

exit 0


- Unmount_VirtualDisk.ps1

. ".\Config.ps1"

wsl -e sudo umount $DATA_DIR
if (! $?) {
  Write-Error "Warning: Failed to unmount device. Force to detach it in the next step."
}

wsl --unmount
if (! $?) {
  Write-Error "Failed to detach all devices."
  exit 2
}

sleep 10
Dismount-DiskImage $VHDX_FILE -ErrorAction "Stop" > $null
if (! $?) {
  Write-Error "Failed to dismount vhdx file."
  exit 3
}

exit 0


[調整]ボタンをクリックし、スクリプト調整プロパティにおいて次の通り値を設定します。

- [開始]の[正常な戻り値]に0
- [実行ユーザ]にAdministrator

1.4 スクリプトリソース(DB用Dockerコンテナ)の追加

DB用Dockerコンテナ(nextcloud-db)の起動・停止を行うためのスクリプトリソースを追加します。

スクリプトリソース(script-DockerDB)

- 依存関係タブ
  - 依存するリソース: script-VirtualDisk

- 詳細タブ
  - スクリプト一覧
    - Start Script: start.bat
    - Stop Script: stop.bat
    - User Script: Activate_DockerDB.ps1
    - User Script: Deactivate_DockerDB.ps1

  - 調整
    - 開始の正常な戻り値: 0
    - 実行ユーザ: Administrator


各スクリプトを登録します。
各スクリプトの内容は次の通りです。

- start.bat

rem ***************************************
rem *              start.bat              *
rem ***************************************
if "%CLP_EVENT%" == "RECOVER" exit /b 0

cd %CLP_SCRIPT_PATH%
PowerShell ".\Activate_DockerDB.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- stop.bat

rem ***************************************
rem *              stop.bat               *
rem ***************************************

cd %CLP_SCRIPT_PATH%
PowerShell ".\Deactivate_DockerDB.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- Activate_DockerDB.ps1

wsl -e docker start nextcloud-db
if (! $?) {
  Write-Error "Failed to start a docker container 'nextcloud-db'."
  exit 2
}
exit 0


- Deactivate_DockerDB.ps1

wsl -e docker stop nextcloud-db
if (! $?) {
  Write-Error "Failed to stop a docker container 'nextcloud-db'."
  exit 2
}
exit 0


[調整]ボタンをクリックし、スクリプト調整プロパティにおいて次の通り値を設定します。

- [開始]の[正常な戻り値]に0
- [実行ユーザ]にAdministrator

1.5 スクリプトリソース(アプリケーション用Dockerコンテナ)の追加

アプリケーション用Dockerコンテナ(nextcloud)の起動・停止を行うためのスクリプトリソースを追加します。

スクリプトリソース(script-DockerApp)

- 依存関係タブ
  - 依存するリソース: script-DockerDB

- 詳細タブ
  - スクリプト一覧
    - Start Script: start.bat
    - Stop Script: stop.bat
    - User Script: Activate_DockerApp.ps1
    - User Script: Deactivate_DockerApp.ps1

  - 調整
    - 開始の正常な戻り値: 0
    - 実行ユーザ: Administrator


各スクリプトを登録します。
各スクリプトの内容は次の通りです。

- start.bat

rem ***************************************
rem *              start.bat              *
rem ***************************************
if "%CLP_EVENT%" == "RECOVER" exit /b 0

cd %CLP_SCRIPT_PATH%
PowerShell ".\Activate_DockerApp.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- stop.bat

rem ***************************************
rem *              stop.bat               *
rem ***************************************

cd %CLP_SCRIPT_PATH%
PowerShell ".\Deactivate_DockerApp.ps1; exit $LASTEXITCODE"
set ret=%ERRORLEVEL%
echo ret: %ret%
exit /b %ret%


- Activate_DockerApp.ps1

wsl -e docker start nextcloud
if (! $?) {
  Write-Error "Failed to start a docker container 'nextcloud'."
  exit 2
}
exit 0


- Deactivate_DockerApp.ps1

wsl -e docker stop nextcloud
if (! $?) {
  Write-Error "Failed to stop a docker container 'nextcloud'."
  exit 2
}
exit 0


[調整]ボタンをクリックし、スクリプト調整プロパティにおいて次の通り値を設定します。

- [開始]の[正常な戻り値]に0
- [実行ユーザ]にAdministrator

1.6 カスタム監視リソース(Dockerサービス)の追加

Dockerサービスの監視を行うためのカスタム監視リソースを追加します。

カスタム監視リソース(genw-DockerService)

- 監視(共通)タブ
  - 監視タイミング: 活性時
  - 対象リソース: script-DockerService

- 監視(固有)タブ
  - ファイル: genw.bat
  - 実行ユーザ: Administrator

- 回復動作タブ
  - 回復動作: カスタム設定
  - 回復対象: script-DockerService


スクリプトを登録します。
スクリプトの内容は次の通りです。

- genw.bat

rem ***************************************
rem *               genw.bat              *
rem ***************************************
echo START
PowerShell -Command "wsl -e sudo service docker status; if (! $?) { exit 1 }; exit 0"
set ret=%ERRORLEVEL%
echo ret: %ret%
echo EXIT
exit /b %ret%


[実行ユーザ]に、[Administrator]を選択します。

1.7 カスタム監視リソース(仮想ディスク)の追加

仮想ディスクの監視を行うためのカスタム監視リソースを追加します。

カスタム監視リソース(genw-VirtualDisk)

- 監視(共通)タブ
  - 監視タイミング: 活性時
  - 対象リソース: script-VirtualDisk

- 監視(固有)タブ
  - ファイル: genw.bat
  - 実行ユーザ: Administrator

- 回復動作タブ
  - 回復動作: カスタム設定
  - 回復対象: script-VirtualDisk


スクリプトを登録します。
スクリプトの内容は次の通りです。

※ 4行目の変数DATA_DIRには、「1.3 スクリプトリソース(仮想ディスク)の追加」のConfig.ps1で指定したものと同じ値を設定します。

- genw.bat

rem ***************************************
rem *               genw.bat              *
rem ***************************************
set DATA_DIR=/mnt/data

echo START
PowerShell -Command "wsl -e sudo mountpoint %DATA_DIR%; if (! $?) { exit 1 }; exit 0"
set ret=%ERRORLEVEL%
echo ret: %ret%
echo EXIT
exit /b %ret%


[実行ユーザ]に、[Administrator]を選択します。

1.8 PostgreSQL監視リソースの追加

DB用Dockerコンテナ(nextcloud-db)の監視を行うためのPostgreSQL監視リソースを追加します。

PostgreSQL監視リソース(psqlw-DockerDB)

- 監視(共通)タブ
  - 監視タイミング: 活性時
  - 対象リソース: script-DockerDB

- 監視(固有)タブ
  - 監視レベル: レベル2(update/selectでの監視)
  - データベース名: nextcloud
  - IPアドレス: 127.0.0.1
  - ポート番号: 5432
  - ユーザ名: nextcloud
  - パスワード: xxxxxxxx (PostgreSQL用コンテナ作成時と同じパスワードを指定)
  - 監視テーブル名: PSQLWATCH

- 回復動作タブ
  - 回復動作: 回復対象に対してフェイルオーバ実行
  - 回復対象: script-DockerDB


PostgreSQL監視リソースがlibpq.dllを必要とするため、popupPostgreSQL Downloads から、PostgreSQLのパッケージをダウンロードします(本記事執筆時点では postgresql-15.1-1-windows-x64.exe)。インストール時は、"Command Line Tools"のみを選択し、インストールを実行します。

PostgreSQLのインストール(Select Components画面)

システム環境変数に、libpq.dllのあるディレクトリへのパス(既定でのインストールの場合、C:\Program Files\PostgreSQL\15\bin)を追加します。

1.9 カスタム監視リソース(アプリケーション用Dockerコンテナ)の追加

アプリケーション用Dockerコンテナ(nextcloud)の監視を行うためのカスタム監視リソースを追加します。
http://localhost:80/login のURLにアクセスし、成功すれば正常と判断します。

カスタム監視リソース(genw-DockerApp)

- 監視(共通)タブ
  - 監視タイミング: 活性時
  - 対象リソース: script-DockerApp

- 監視(固有)タブ
  - ファイル: genw.bat
  - 実行ユーザ: Administrator

- 回復動作タブ
  - 回復動作: カスタム設定
  - 回復対象: script-DockerApp


スクリプトを登録します。
スクリプトの内容は次の通りです。

- genw.bat

rem ***************************************
rem *               genw.bat              *
rem ***************************************
echo START
PowerShell -Command "try { $ret = Invoke-WebRequest -Uri http://127.0.0.1:80/login -UseBasicParsing -ErrorAction Stop; if ($ret.StatusCode -ne '200') { exit 1 } } catch { exit 99 }; exit 0"
set ret=%ERRORLEVEL%
echo ret: %ret%
echo EXIT
exit /b %ret%


[実行ユーザ]に、[Administrator]を選択します。

2. 動作確認

クライアントマシンから、HAクラスター化されたDockerコンテナのサービスにフローティングIP経由でアクセスできること、障害時にも問題なく使用可能であることを確認します。

  • 1.
    server1でフェールオーバーグループ(failover1)を起動します。
  • 2.
    クライアントマシンのブラウザからフローティングIP(172.16.1.100)にアクセスし、Nextcloudに接続できることを確認します。
  • 3.
    Nextcloudでログインし、オンラインストレージ上に適当なファイルを保存します。
  • 4.
    Cluster WebUIからserver1をシャットダウンします。フェールオーバーグループがserver1からserver2に移動します。
  • 5.
    クライアントマシンのブラウザからフローティングIP(172.16.1.100)にアクセスし、3.で保存したファイルを開けることを確認します。
DockerコンテナのHAクラスター化により、片方のサーバがダウンした場合でも残りのサーバにフェールオーバーし、引き継がれたデータにアクセス可能であることを確認できました。

さいごに

今回は、Windows上で、DockerコンテナベースアプリケーションのHAクラスターを構築してみました。

DockerのHAクラスター化を行うことで、Dockerの利点を生かしつつ耐障害性、可用性を向上させることが可能となります。Windowsでは、WSLとあわせて使用するにあたり、本記事で取り上げた通り若干注意すべき点がありますが、本手順を参考にHAクラスターを構築してください。

本記事の構成をご検討の際は、CLUSTERPROのpopup試用版を用いて検証した後、ご提案・構築ください。

お問い合わせ

本記事に関するお問い合わせは、popupお問い合わせ窓口までお問い合わせください。
  • 本記事で紹介しているスクリプトの内容についてのお問い合わせ、および、お客様環境に合わせたカスタマイズにつきましてはCLUSTERPRO導入支援サービスにて承っておりますので、上記窓口の"ご購入前のお問い合わせ"フォームまでお問い合わせください。
  • CLUSTERPRO以外のソフトウェアのサポートについてはそれぞれの購入元にお問い合わせください。