第10章 DRBDとLVMの使用

目次

10.1. LVMの基礎
10.2. DRBDの下位デバイスとして論理ボリュームを使用する
10.3. DRBD同期中の自動LVMスナップショットの使用
10.4. DRBDリソースを物理ボリュームとして構成する
10.5. 新しいDRBDボリュームを既存のボリュームグループへ追加する
10.6. DRBDを使用する入れ子のLVM構成
10.6.1. Switching the VG to the other node
10.7. Pacemakerによる高可用性LVM

この章では、DRBDの管理とLVM2について説明します。特に、次のような項目を取り上げます。

上述の用語についてよく知らない場合は、「LVMの基礎」を参照してくださいまた、ここで説明する内容にとどまらず、LVMについてさらに詳しく理解することをお勧めします。

10.1. LVMの基礎

LVM2は、Linuxデバイスマッパフレームワークのコンテキストにおける論理ボリューム管理の実装です。元のLVM実装とは名前と略語を除き、実際には何の共通点もありません。古い実装(現在ではLVM1と呼ばれる)は時代遅れとみなされているため、ここでは取り上げません。

LVMを使用する際には、次に示す基本的なコンセプトを理解することが重要です。

物理ボリューム(PV). PV (Physical Volume: 物理ボリューム)はLVMによってのみ管理される配下のブロックデバイスです。ハードディスク全体または個々のパーティションがPVになります。ハードディスクにパーティションを1つだけ作成して、これを独占的にLinux LVMで使用するのが一般的です。

[注記]注記

パーティションタイプ"Linux LVM" (シグネチャは 0x8E)を使用して、LVMが独占的に使用するパーティションを識別できます。ただし、これは必須ではありません。PVの初期化時にデバイスに書き込まれるシグネチャによってLVMがPVを認識します。

ボリュームグループ (VG). VG (Volume Group: ボリュームグループ)はLVMの基本的な管理単位です。VGは1つまたは複数のPVで構成されます。各VGは一意の名前を持ちます。実行時にPVを追加したり、PVを拡張して、VGを大きくすることができます。

Logical Volume (LV). 実行時にVG内にLV (Logical Volume: 論理ボリューム)を作成することにより、カーネルの他の部分がこれらを通常のブロックデバイスとして使用できます。このように、LVはファイルシステムの格納をはじめ、ブロックデバイスと同様のさまざまな用途に使用できます。オンライン時にLVのサイズを変更したり、1つのPVから別のPVに移動したりすることができます(PVが同じVGに含まれる場合)。

スナップショット論理ボリューム (SLV). スナップショットはLVの一時的なポイントインタイムコピーです。元のLV(コピー元ボリューム)のサイズが数百GBの場合でも、スナップショットは一瞬で作成できます。通常、スナップショットは元のLVと比べてかなり小さい領域しか必要としません。

図10.1 LVM overview

width=100%

10.2. DRBDの下位デバイスとして論理ボリュームを使用する

Linuxでは、既存の論理ボリュームは単なるブロックデバイスであるため、これをDRBDの下位デバイスとして使用できます。この方法でLVを使用する場合は、通常通りにLVを作成してDRBD用に初期化するだけです。

次の例では、LVM対応システムの両方のノードに foo というボリュームグループがすでに存在します。このボリュームグループの論理ボリュームを使用して、r0 というDRBDリソースを作成します。

まず、次のコマンドで論理ボリュームを作成します。

lvcreate --name bar --size 10G foo
 Logical volume "bar" created

このコマンドはDRBDクラスタの両方のノードで実行する必要があります。これで、いずれかのノードに /dev/foo/bar というブロックデバイスが作成されます。

次に、新しく作成したボリュームをリソース構成に加えます。

resource r0 {
  ...
  on alice {
    device /dev/drbd0;
    disk   /dev/foo/bar;
    ...
  }
  on bob {
    device /dev/drbd0;
    disk   /dev/foo/bar;
    ...
  }
}

これでリソースを起動できます。手順はLVM対応以外のブロックデバイスと同様です。

10.3. DRBD同期中の自動LVMスナップショットの使用

DRBDが同期をしている間、SyncTarget の状態は同期が完了するまでは Inconsistent (不整合)の状態です。この状況では SyncSource で(修復できない)障害があった場合に残念なことになります。正常なデータを持つノードが死に、誤った情報を持つノードが残ってしまいます。

LVM論理ボリュームをDRBDに渡す際には、同期の開始時に自動スナップショットを作成し、またこれを完了後に自動削除する方法によって、この問題を軽減することができます

再同期中に自動でスナップショットをするには、リソース設定に以下の行を追加します。

DRBD同期前の自動スナップショット作成. 

resource r0 {
  handlers {
    before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh";
    after-resync-target "/usr/lib/drbd/unsnapshot-resync-target-lvm.sh";
  }
}

2つのスクリプトはDRBDが呼び出した ハンドラ に自動で渡す $DRBD_RESOURCE$ 環境変数を解析します。snapshot-resync-target-lvm.sh スクリプトは、同期の開始前に、リソースが含んでいるボリュームのLVMスナップショットを作成します。そのスクリプトが失敗した場合、同期は 開始されません

同期が完了すると、unsnapshot-resync-target-lvm.sh スクリプトが必要のなくなったスナップショットを削除します。スナップショットの削除に失敗した場合、スナップショットは残り続けます。

[重要]重要

できる限り不要なスナップショットは確認するようにしてください。スナップショットが満杯だと、スナップショット自身と 元のボリューム の障害の原因になります。

SyncSource に修復できない障害が起きて、最新のスナップショットに復帰したいときには、いつでも lvconvert -M コマンドで行えます。

10.4. DRBDリソースを物理ボリュームとして構成する

DRBDリソースを物理ボリュームとして使用するためには、DRBDデバイスにPVのシグネチャを作成する必要があります。リソースが現在プライマリロールになっているノードで、 次のいずれかのコマンドを実行します。

# pvcreate /dev/drbdX

または

# pvcreate /dev/drbd/by-res/<resource>/0
[注記]注記

この例では、ボリュームリソースが1つであることを前提にしています。

次に、LVMがPVシグネチャをスキャンするデバイスのリストにこのデバイスを加えます。このためには、通常は /etc/lvm/lvm.conf という名前のLVM設定ファイルを編集する必要があります。devices セクションで filter というキーワードを含む行を見つけて編集します。すべての のPVをDRBDデバイスに格納する場合には、次ように filter オプションを編集します。

filter = [ "a|drbd.*|", "r|.*|" ]

このフィルタ表現がDRBDデバイスで見つかったPVシグネチャを受け入れ、それ以外のすべてを拒否(無視)します。

[注記]注記

デフォルトではLVMは /dev にあるすべてのブロックデバイスのPVシグネチャをスキャンします。これは filter=["a|.*|"] に相当します。

LVMのPVでスタックリソースを使用する場合は、より明示的にフィルタ構成を指定する必要があります。対応する下位レベルリソースや下位デバイスでPVシグネチャを無視している場合、LVMはスタックリソースでPVシグネチャを検出する必要があります。次の例では、下位レベルDRBDリソースは0から9のデバイスを使用し、スタックリソースは10以上のデバイスを使用しています。

filter = [ "a|drbd1[0-9]|", "r|.*|" ]

このフィルタ表現は、/dev/drbd10 から /dev/drbd19 までのDRBDのデバイスで見つかったPVシグニチャを受け入れ、それ以外のすべてを拒否(無視)します。

lvm.conf ファイルを変更したら vgscan コマンドを実行します。LVMは構成キャッシュを破棄し、デバイスを再スキャンしてPVシグネチャを見つけます。

システム構成に合わせて、別の filter 構成を使用することもできます。重要なのは、次の2つです。

  • PVとして使用するデバイスに、DRBDのデバイスを許容する
  • 対応する下位レベルデバイスを拒否(除外)して、LVMが重複したPVシグネチャを見つけることを回避する。

さらに、次の設定で、LVMのキャッシュを無効にする必要があります。

write_cache_state = 0

LVMのキャッシュを無効にした後、/etc/lvm/cache/.cache を削除して、古いキャッシュを削除してください。

対向ノードでも、上記の手順を繰り返します。

[重要]重要

システムのルートファイルシステムがLVM上にある場合、bootの際にボリュームグループはイニシャルRAMディスク(initrd)から起動します。そのため、LVMツールはinitrdイメージに含まれる lvm.conf ファイルを検査します。そのため、lvm.conf に変更を加えたら、ディストリビューションに応じてユーティリティ(mkinitrdupdate-initramfs など)で確実にアップデートしなければなりません。

新しいPVを構成したら、ボリュームグループに追加するか、 新しいボリュームグループを作成します。このとき、DRBDリソースがプライマリロールになっている必要があります。

# vgcreate <name> /dev/drbdX
[注記]注記

同じボリュームグループ内にDRBD物理ボリュームとDRBD以外の物理ボリュームを混在させることができますが、これはお勧めできません。また、混在させても実際には意味がないでしょう。

VGを作成したら、 lvcreate コマンドを使用して、(DRBD以外を使用するボリュームグループと同様に)ここから論理ボリュームを作成します。

10.5. 新しいDRBDボリュームを既存のボリュームグループへ追加する

新しいDRBDでバックアップした物理ボリュームを、ボリュームグループへ追加したいといった事があるでしょう。その場合には、新しいボリュームは既存のリソース設定に追加しなければなりません。そうすることでVG内の全PVのレプリケーションストリームと書き込みの適合度が確保されます。

[重要]重要

LVMボリュームグループを「Pacemakerによる高可用性LVM」で説明しているようにPacemakerで管理している場合には、DRBD設定の変更前にクラスタメンテナンスモードになっている事が 必須 です。

追加ボリュームを加えるには、リソース設定を次のように拡張します。

resource r0 {
  volume 0 {
    device    /dev/drbd1;
    disk      /dev/sda7;
    meta-disk internal;
  }
  volume 1 {
    device    /dev/drbd2;
    disk      /dev/sda8;
    meta-disk internal;
  }
  on alice {
    address   10.1.1.31:7789;
  }
  on bob {
    address   10.1.1.32:7789;
  }
}

DRBD設定が全ノード間で同じである事を確認し、次のコマンドを発行します。

# drbdadm adjust r0

これによって、リソース r0 の新規ボリューム 1 を有効にするため、暗黙的に drbdsetup new-minor r0 1 が呼び出されます。新規ボリュームがレプリケーションストリームに追加されると、イニシャライズやボリュームグループへの追加ができるようになります。

# pvcreate /dev/drbd/by-res/<resource>/1
# lvextend <name> /dev/drbd/by-res/<resource>/1

で新規PVの /dev/drbd/by-res/<resource>/1<name> VGへ追加され、VG全体にわたって書き込みの忠実性を保護します。

10.6. DRBDを使用する入れ子のLVM構成

論理ボリュームをDRBDの下位デバイスとして使用し、かつ、同時にDRBDデバイス自体を物理ボリュームとして使用することもできます。例として、次のような構成を考えてみましょう。

  • /dev/sda1/dev/sdb1 という2つのパーティションがあり、これらを物理ボリュームとして使用します。
  • 2つのPVが local というボリュームグループに含まれます。
  • このGVに10GiBの論理ボリュームを作成し、r0 という名前を付けます。
  • このLVがDRBDリソースのローカル下位デバイスになります。名前は同じ r0 で、デバイス /dev/drbd0 に対応します。
  • このデバイスが replicated というもう1つのボリュームグループの唯一のPVになります。
  • このVGには foo (4GiB)と bar (6GiB)というさらに2つの論理ボリュームが含まれます。

この構成を有効にするために、次の手順を行います。

  • /etc/lvm/lvm.conf で適切な filter オプションを設定します。

    filter = ["a|sd.*|", "a|drbd.*|", "r|.*|"]

    このフィルタ表現が、SCSIおよびDRBDデバイスで見つかったPVシグネチャを受け入れ、その他すべてを拒否(無視)します。

    lvm.conf ファイルを変更したら vgscan コマンドを実行します。LVMは構成キャッシュを破棄し、デバイスを再スキャンしてPVシグネチャを見つけます。

  • LVMキャッシュ無効の設定

    write_cache_state = 0

    LVMのキャッシュを無効にした後、/etc/lvm/cache/.cache を削除して、古いキャッシュを削除してください。

  • ここで、2つのSCSIパーティションをPVとして初期化します。

    # pvcreate /dev/sda1
    Physical volume "/dev/sda1" successfully created
    # pvcreate /dev/sdb1
    Physical volume "/dev/sdb1" successfully created
  • 次に、初期化した2つのPVを含む local という名前の下位レベルVGを作成します。

    # vgcreate local /dev/sda1 /dev/sda2
    Volume group "local" successfully created
  • これで、DRBDの下位デバイスとして使用する論理ボリュームを作成できます。

    # lvcreate --name r0 --size 10G local
    Logical volume "r0" created
  • 対向ノードに対して、ここまでのすべての手順を繰り返します。
  • /etc/drbd.conf を編集して、r0 という名前の新しいリソースを作成します。

    resource r0 {
      device /dev/drbd0;
      disk /dev/local/r0;
      meta-disk internal;
      on <host> { address <address>:<port>; }
      on <host> { address <address>:<port>; }
    }

    新しいリソース構成を作成したら、忘れずに drbd.conf の内容を対向ノードにコピーします。

  • 「リソースを初めて有効にする」に従って(両方のノードの)リソースを初期化します。
  • 一方のノードリソースを昇格します。

    # drbdadm primary r0
  • リソースを昇格したノードで、DRBDデバイスを新しい物理ボリュームとして初期化します。

    # pvcreate /dev/drbd0
    Physical volume "/dev/drbd0" successfully created
  • 初期化したPVを使用して、同じノードに replicated というVGを作成します。

    # vgcreate replicated /dev/drbd0
    Volume group "replicated" successfully created
  • 最後に、新しく作成したこのVG内に新しい論理ボリュームを作成します。

    VG:

    # lvcreate --name foo --size 4G replicated
    Logical volume "foo" created
    # lvcreate --name bar --size 6G replicated
    Logical volume "bar" created

これで、論理ボリューム foobar をローカルノードで /dev/replicated/foo/dev/replicated/bar として使用できます。

10.6.1. Switching the VG to the other node

他のノードでも使用できるように、プライマリノードで次のコマンドを実行します。

# vgchange -a n replicated
0 logical volume(s) in volume group "replicated" now active
# drbdadm secondary r0

次に他のノード(まだセカンダリの)でコマンドを発行します。

# drbdadm primary r0
# vgchange -a y replicated
2 logical volume(s) in volume group "replicated" now active

これでブロックデバイス /dev/replicated/foo/dev/replicated/bar が他の(現在はプライマリの)ノードで有効になります。

10.7. Pacemakerによる高可用性LVM

対向ノード間でのボリュームグループの転送と、対応する有効な論理ボリュームの作成のプロセスは自動化することができます。Pacemakerの LVM リソースエージェントはまさにこのために作られています。

既存のPacemaker管理下にあるDRBDの下位デバイスのボリュームグループをレプリケートするために、crm シェルで次のコマンドを実行してみましょう。

DRBDの下位デバイスのLVMボリュームグループに関するPacemaker設定. 

primitive p_drbd_r0 ocf:linbit:drbd \
  params drbd_resource="r0" \
  op monitor interval="29s" role="Master" \
  op monitor interval="31s" role="Slave"
ms ms_drbd_r0 p_drbd_r0 \
  meta master-max="1" master-node-max="1" \
       clone-max="2" clone-node-max="1" \
       notify="true"
primitive p_lvm_r0 ocf:heartbeat:LVM \
  params volgrpname="r0"
colocation c_lvm_on_drbd inf: p_lvm_r0 ms_drbd_r0:Master
order o_drbd_before_lvm inf: ms_drbd_r0:promote p_lvm_r0:start
commit

この設定を反映させると、現在のDRBDリソースのプライマリ(マスター)ロールがどちらであっても、Pacemakerは自動的に r0 ボリュームグループを有効にします。