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

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

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

はじめに

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

今回動作させるDockerコンテナアプリケーションとして、オンラインストレージソフトウェアのNextcloudと、そのデータベースにPostgreSQLを使用します。また、Windows環境でDockerを動かすために必要なWindows Subsystem for Linux(以降、WSL)もインストールします。

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

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

この記事の内容

1. Dockerについて

1.1 Dockerとは

Dockerはコンテナと呼ばれる隔離された実行環境を作り管理する、コンテナ型仮想化プラットフォームの一つです。

Dockerはハイバーバイザ型仮想化プラットフォームに比べ、仮想マシンを作る必要がありません。また、コンテナの起動や処理が仮想マシンに比べて早いことが特長です。物理サーバーにインストールせずとも、動かしたいミドルウェアやアプリケーションのコンテナイメージがあれば、簡単に導入・実行できるというメリットがあります。

1.2 DockerをWindowsで利用する時の注意点

DockerはLinuxやMac、Windows環境で利用することが可能です。Windows環境で利用する場合はWSLの導入が必要となります。WindowsでDockerおよびWSLを利用する際には、以下の点に注意する必要があります。

  • WSLにはWSL1とWSL2があります。本記事ではWSL2を利用します。
  • WSL2を利用するにはインストール先のWindows Serverで仮想化機能が有効になっている必要があります。仮想化機能が有効になっているかどうかはPowerShellで以下のコマンドを実行することで確認可能です。コマンド実行結果において、VirtualizationFirmwareEnabledがTrueになっていれば、仮想化機能が有効になっています。

    > Get-WmiObject -Class Win32_Processor | Format-List VirtualizationFirmwareEnabled

    VirtualizationFirmwareEnabled : True ★CPUの個数分表示されます

  • 仮想化機能を有効にするためにはUEFI/BIOSまたはHyper-Vなどの仮想化ホスト側の設定が必要な場合があります。
  • Windows側のNTFSファイルシステムをWSL2内にマウントすることが可能ですが、本記事では使用しません。代わりにNTFSファイルシステム上に仮想ディスクファイルを作成し、それをext4ファイルシステムでフォーマットしたうえでWSL2内でマウントします。
    その理由は、NTFSファイルシステムをDockerコンテナにマウントした場合に、そのマウントポイントはフルアクセス(modeが777)固定となってしまい、NextcloudなどDockerコンテナアプリケーションによってはパーミッションに起因するエラーが発生し、正常に動作しないものがあるためです。
  • Dockerコンテナで外部に公開したポートは、そのままではWindows Serverの外からはアクセスできません。これは、DockerがWindows ServerではなくWSL2のUbuntu上で動作していることが原因です。そのため別途、netshコマンドなどでWindows ServerとWSL2のUbuntuとの間にポート転送設定を行う必要があります。

1.3 CLUSTERPROからDockerを利用する時の注意点

CLUSTERPRO X for WindowsからDockerを利用する際には、以下の点に注意する必要があります。

  • WSL2の自動マウント機能(WSL2の起動時にWindowsのドライブを自動的にWSL2内にマウントする機能)が有効の場合、WSL2を起動するたびにミラーディスクのクラスタパーティションに関連したエラーが出るため、自動マウント機能を無効にすることを推奨します。
  • CLUSTERPRO Xのスクリプトリソース、または、カスタム監視リソースからwslコマンドを実行する時は、既定のローカルシステムアカウント(SYSTEM)では動作しません。Administratorユーザで実行する必要があります(各リソースの[実行ユーザ]に[Administrator]を指定)。

本記事では、これらの点を踏まえてCLUSTERPRO Xと組み合わせた設定手順をご紹介します。

2. HAクラスター構成

今回構築するのはActive-Standby形式のHAクラスター構成となります。

現用系/待機系の切り替えは、本記事ではFIP(フローティングIP)によって行いますが、要件にあわせてVIP(仮想IP)やDNSによる切り替え方式にすることも可能です。

■ ネットワーク・ハードウェア

・ネットワーク
  - ネットワークアドレス: 172.16.1.0/24
  - フローティングIPアドレス: 172.16.1.100
・HAクラスタ構成サーバー
  - server1
    - IPアドレス: 172.16.1.11
    - ディスク1(OS用): 40GiB
    - ディスク2(ミラーディスク用): 30GiB
  - server2
    - IPアドレス: 172.16.1.21
    - ディスク1(OS用): 40GiB
    - ディスク2(ミラーディスク用): 30GiB


■ OS、CLUSTERPRO

・CLUSTERPRO X 5.0 for Windows(内部バージョン:13.02)
・Windows Server 2022(※)

  • CLUSTERPROで動作確認が完了しており、かつ、WSL2が対応しているWindowsを利用可能です。

【参考】
    popupCLUSTERPRO X for Windows 動作環境
    CLUSTERPRO Server
    > CLUSTERPRO X 5.0

CLUSTERPRO Xの動作環境および、ミラーディスクの要件についてはスタートアップガイドもご参照ください。

【参考】
    popupCLUSTERPRO X システム構築ガイド
   ● CLUSTERPRO X 5.0 > Windows > スタートアップガイド
      → 第4章 CLUSTERPROの動作環境

   ● CLUSTERPRO X 5.0 > Windows > スタートアップガイド
      → 第6章 注意制限事項
          → 6.1 システム構成検討時
              → 6.1.2 ミラーディスク/ハイブリッドディスクの要件について

CLUSTERPRO XとDockerサービス、コンテナやミラーディスクとの関係は次の図の通りとなります。

Windows Server 2022 にWSL2およびDockerをインストールし、PostgreSQLとNextcloudの2個のコンテナを載せます。それぞれのコンテナはCLUSTERPROのスクリプトリソースにより起動・停止を行います。また、各種監視リソースにより、Dockerサービスやコンテナの死活監視を行います。
PostgreSQLはDockerコンテナでなく、直接Windows版アプリケーションをインストールし運用する方法もありますが、本記事ではDockerコンテナ同士の連携の例としてコンテナ版を採用しています。
Nextcloudは、Webブラウザを使用してのファイル共有などを可能にするオンラインストレージサービスを提供します。本記事では、同じDocker上で動作するPostgreSQL用DBコンテナを格納先としてデータが保存されるようにします。

PostgreSQLおよびNextcloudのコンテナのデータをサーバー間でミラーリングするために、CLUSTERPROのミラーディスク上に仮想ディスクを置き、その中にデータを保存します。
ミラーディスク型クラスターについては以下の記事で解説しておりますので、必要に応じてご参照ください。


CLUSTERPRO Xの最終的なリソース構成は次の通りです。

■ CLUSTERPROのリソース構成

・ フェールオーバーグループ(failover1)
  - フローティングIPリソース(fip1)
  - ミラーディスクリソース(md-Docker)
  - スクリプトリソース(script-DockerService)
  - スクリプトリソース(script-VirtualDisk)
  - スクリプトリソース(script-DockerDB)
  - スクリプトリソース(script-DockerApp)

・ 監視リソース
  - フローティングIP監視リソース(fipw1)
  - ミラーディスク監視リソース(mdw-Docker)
  - カスタム監視リソース(genw-DockerService)
  - カスタム監視リソース(genw-VirtualDisk)
  - PostgreSQL監視リソース(psqlw-DockerDB)
  - カスタム監視リソース(genw-DockerApp)
  - ユーザ空間監視リソース(userw)

3. HAクラスター構築手順(Dockerコンテナの作成)

3.1 HAクラスターの事前準備

クラスタを構築するサーバーを2台用意します。
各サーバーで仮想化機能が有効であることを確認します。

WSL2、Docker、Nextcloudのインストールは、オンラインで必要なパッケージをダウンロードしながら行います。そのため各サーバーからインターネットにアクセス可能となるようにネットワークを適切に設定しておきます。

3.2 WSL2のインストール

server1、server2のそれぞれで実施します。

本記事ではシェルのプロンプトを、PowerShellのときは">"、bashのときは"$"で表記します。

PowerShellを起動し、次のコマンドで WSL2をインストールします。ディストリビューションにはUbuntu 20.04を指定します。

> wsl --install -d Ubuntu-20.04


インストール後、OSの再起動を求められるため、再起動を実施します。
再起動後、WSL2が起動した際にUbuntuの既定ユーザおよびパスワード入力を求められますので、任意の文字列を入力します(本記事ではwsluserとします)。
PowerShellを起動し、WSLのバージョンを確認します。以下のように VERSION が2になっていればWSL2であることがわかります。

> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2


WSL2の設定ファイル(wsl.conf)を編集し、WSL2のWindowsドライブ自動マウント機能を無効にします。

> wsl -e sudo vi /etc/wsl.conf


設定ファイル中には以下の内容を入力し、保存します。

[automount]
enabled = false


設定ファイルの内容を反映するために、WSL2をいったん終了します。

> wsl --shutdown

3.3 Dockerのインストール

server1、server2のそれぞれで実施します。

WSL2に入ります。

> wsl


パッケージの更新を行います。

$ sudo apt-get update
$ sudo apt-get upgrade


Dockerリポジトリの登録とインストールを行います。

$ sudo apt-get install ca-certificates curl gnupg lsb-release
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin


※ 上記のUbuntuでのDockerのインストール手順は、次のDocker公式ページを参考にしています。


WSL2の既定ユーザ(wsluser)でdockerコマンドを実行可能にするために、Docker管理者として登録します。

$ sudo usermod -aG docker wsluser


WSL2の既定ユーザが実行するコマンドについて、パスワード無しsudoで実行可能にします。これは、CLUSTERPRO Xのリソースからコマンドを実行する際にパスワード入力を不要にするためです。

$ echo "wsluser ALL=(ALL) NOPASSWD: /usr/sbin/service,/usr/bin/mount,/usr/bin/umount,/usr/bin/mountpoint" | sudo tee /etc/sudoers.d/clusterpro > /dev/null
$ exit

3.4 HAクラスターの構築

server1、server2のそれぞれにCLUSTERPRO X をインストールし、Cluster WebUIを使用してHAクラスターを構築します。

フェールオーバーグループにはフローティングIPリソースと、Dockerコンテナの共有データを置くためのミラーディスクリソースを追加します。

・ フェールオーバーグループ(failover1)
  - フローティングIPリソース(fip1)
    - IPアドレス: 172.16.1.100
  - ミラーディスクリソース(md-Docker)
    - クラスタパーティション: L: (1024MiB)
    - データパーティション: M: (29GiB)

3.5 Docker共有データ用仮想ディスクの作成(server1)

ミラーディスクのデータパーティションであるMドライブ配下に、Dockerコンテナが外部に保存するための領域となる、仮想ディスクを作成します。

Cluster WebUIを使用し、server1でミラーディスクリソース(md-Docker)を起動します。

server1でdiskpartコマンドを実行します。

> diskpart


diskpartのプロンプトで次のコマンドを実行し、Mドライブ上に仮想ディスク M:¥nextcloud.vhdx を作成します。maximumパラメータには、作成する仮想ディスクの容量をMiB単位で指定します。

例) 20GiBの仮想ディスクを作成する
DISKPART> create vdisk file="M:\nextcloud.vhdx" maximum=20480 type=expandable
DISKPART> exit

3.6 WSL2で仮想ディスクをマウント(server1)

server1で、Windowsから仮想ディスクにアクセス可能にするためにマウントします。

> $ret = Mount-DiskImage M:\nextcloud.vhdx


マウントした仮想ディスクをWSL2からもアクセス可能にするために、wslコマンドで認識させます。

> wsl --mount $ret.DevicePath --bare


WSL2に入ります。

> wsl

マウントした仮想ディスクのマウント先(/mnt/data)を作成します。

$ sudo mkdir /mnt/data


lsblkコマンドを実行し、仮想ディスクのデバイス名をサイズで確認します。
今回作成した仮想ディスクは20GiBのため、デバイス名はsdcであることがわかります。

$ sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 256G 0 disk
sdb 8:16 0 256G 0 disk /
sdc 8:32 0 20G 0 disk


デバイス名が判明した仮想ディスクをファイルシステムタイプext4でフォーマットします。 

$ sudo mkfs -t ext4 /dev/sdc


blkidコマンドを実行し、仮想ディスクのUUIDを取得します。
UUID=の後に続く文字列(以下の例ではaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)がUUIDとなります。
このUUIDは後でCLUSTERPROのスクリプトリソース追加時にも必要となるためメモしておきます。
 

$ sudo blkid -s UUID -o export /dev/sdc
DEVNAME=/dev/sdc
UUID=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee


取得したUUIDを指定して、仮想ディスクを/mnt/dataにマウントします。

$ sudo mount UUID=<メモしておいたUUID> /mnt/data

3.7 PostgreSQLのコンテナ作成(server1)

server1で、Dockerサービスを起動します。
WSL2に入った状態で次のコマンドを実行します。

$ sudo service docker start


PostgreSQLのコンテナを、nextcloud-dbの名前で作成します。POSTGRES_PASSWORDには任意のDBのパスワードを指定します。

$ sudo mkdir /mnt/data/nextcloud_db
$ docker run -d \
  --env POSTGRES_DB=nextcloud \
  --env POSTGRES_USER=nextcloud \
  --env POSTGRES_PASSWORD=xxxxxxxx \
  --mount type=bind,source=/mnt/data/nextcloud_db,target=/var/lib/postgresql/data \
  --restart no \
  --name nextcloud-db \
  -p 5432:5432 \
  postgres:15.1

3.8 Nextcloudのコンテナ作成(server1)

server1で、Nextcloudのコンテナを、nextcloudの名前で作成します。POSTGRES_PASSWORDには、PostgreSQL用コンテナ作成時と同じパスワードを指定します。

$ sudo mkdir /mnt/data/nextcloud_data
$ docker run -d \
  --env POSTGRES_HOST=nextcloud-db:5432 \
  --env POSTGRES_DB=nextcloud \
  --env POSTGRES_USER=nextcloud \
  --env POSTGRES_PASSWORD=xxxxxxxx \
  --mount type=bind,source=/mnt/data/nextcloud_data,target=/var/www/html \
  --restart no \
  --name nextcloud \
  --link nextcloud-db \
  -p 80:80 \
  docker.io/library/nextcloud
$ exit


server1で、Webブラウザから http://localhost/ にアクセスし、Nextcloudの画面が表示されることを確認します。

次に、サーバーのIPアドレスに対するHTTPアクセスが、Nextcloudコンテナのhttpポートに転送されるように、PowerShell上で次のコマンドを実行し、ポート転送設定を行います。

> $ip = wsl -e hostname -I | % {$_.Split(" ")[0]}; netsh interface portproxy add v4tov4 listenaddress=* listenport=80 connectaddress=$ip connectport=80


server1で、WebブラウザからフローティングIPアドレスのURLとして http://172.16.1.100/ にアクセスし、Nextcloudの画面が表示されることを確認します。

3.9 Dockerコンテナの停止と仮想ディスクのアンマウント(server1)

server1で、WSL2に入ります。

> wsl


DockerコンテナおよびDockerサービスを停止し、仮想ディスクをアンマウントします。

$ docker stop nextcloud
$ docker stop nextcloud-db
$ sudo service docker stop
$ sudo umount /mnt/data
$ exit

> wsl --shutdown
> Dismount-DiskImage M:\nextcloud.vhdx


次のコマンドを実行し、CLUSTERPROのフェールオーバーグループをserver2に移動します。

> clpgrp -m failover1

3.10 待機系のWSL2に仮想ディスクをマウント(server2)

server2で、仮想ディスクにアクセス可能にするためにマウントします。

> $ret = Mount-DiskImage M:\nextcloud.vhdx


マウントした仮想ディスクをWSL2からもアクセス可能にするために、wslコマンドで認識させます。

> wsl --mount $ret.DevicePath --bare


WSL2に入ります。

> wsl


マウントした仮想ディスク内のファイルシステムを、「3.6 WSL2で仮想ディスクをマウント(server1)」でメモしたUUIDを指定してマウントします。

$ sudo mkdir /mnt/data
$ sudo mount UUID=<メモしておいたUUID> /mnt/data

3.11 PostgreSQLのコンテナ作成(server2)

server2で、Dockerサービスを起動します。

WSL2に入った状態で次のコマンドを実行します。

$ sudo service docker start


PostgreSQLのコンテナを作成します。POSTGRES_PASSWORDには、server1で指定したものと同じ値を指定します。

$ docker run -d \
  --env POSTGRES_DB=nextcloud \
  --env POSTGRES_USER=nextcloud \
  --env POSTGRES_PASSWORD=xxxxxxxx \
  --mount type=bind,source=/mnt/data/nextcloud_db,target=/var/lib/postgresql/data \
  --restart no \
  --name nextcloud-db \
  -p 5432:5432 \
  postgres:15.1

3.12 Nextcloudのコンテナ作成(server2)

server2で、Nextcloudのコンテナを作成します。POSTGRES_PASSWORDには、PostgreSQL用コンテナ作成時と同じパスワードを指定します。

$ docker run -d \
  --env POSTGRES_HOST=nextcloud-db:5432 \
  --env POSTGRES_DB=nextcloud \
  --env POSTGRES_USER=nextcloud \
  --env POSTGRES_PASSWORD=xxxxxxxx \
  --mount type=bind,source=/mnt/data/nextcloud_data,target=/var/www/html \
  --restart no \
  --name nextcloud \
  --link nextcloud-db \
  -p 80:80 \
  docker.io/library/nextcloud
$ exit


server2で、Webブラウザから http://localhost/ にアクセスし、Nextcloudの画面が表示されることを確認します。

次に、server2のIPアドレスに対するHTTPアクセスが、Nextcloudコンテナのhttpポートに転送されるように、PowerShell上で次のコマンドを実行し、ポート転送設定を行います。

> $ip = wsl -e hostname -I | % {$_.Split(" ")[0]}; netsh interface portproxy add v4tov4 listenaddress=* listenport=80 connectaddress=$ip connectport=80


server2で、WebブラウザからフローティングIPアドレスのURLとして http://172.16.1.100/ にアクセスし、Nextcloudの画面が表示されることを確認します。

3.13 Dockerコンテナの停止と仮想ディスクのアンマウント(server2)

server2で、WSL2に入ります。

> wsl


DockerコンテナおよびDockerサービスを停止し、仮想ディスクをアンマウントします。

$ docker stop nextcloud
$ docker stop nextcloud-db
$ sudo service docker stop
$ sudo umount /mnt/data
$ exit

> wsl --shutdown
> Dismount-DiskImage M:\nextcloud.vhdx

まとめ

今回は、HAクラスター用サーバにWSL2およびDockerをインストールし、ミラーディスクにDocker用データを置く形でDockerコンテナを作成する手順までを説明しました。
DockerサービスやDockerコンテナをCLUSTERPROから起動・停止・監視するための、CLUSTERPRO Xの設定を行う手順を、popup「後編」に記載しておりますので、併せてご覧ください。


お問い合わせ

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