Product SiteDocumentation Site

第 12 章 高度な管理

12.1. RAID と LVM
12.1.1. ソフトウェア RAID
12.1.2. LVM
12.1.3. RAID それとも LVM?
12.2. 仮想化
12.2.1. Xen
12.2.2. LXC
12.2.3. KVM を使った仮想化
12.3. 自動インストール
12.3.1. Fully Automatic Installer (FAI)
12.3.2. Debian-Installer の事前設定
12.3.3. Simple-CDD、一体型の解決策
12.4. 監視
12.4.1. Munin のセットアップ
12.4.2. Nagios のセットアップ
この章では、前章までに説明した一部の側面を異なる視点からもう一度取り上げます。すなわち、1 台のコンピュータにインストールするのではなく、大規模な配備システムについて学びます。さらに、初回インストール時に RAID や LVM ボリュームを作成するのではなく、手作業でこれを行う方法について学びます。こうすることで初回インストール時の選択を訂正することが可能です。最後に、監視ツールと仮想化技術について議論します。その結果として、この章はより熟練した管理者を対象にしており、ホームネットワークに責任を負う個人を対象にしていません。

12.1. RAID と LVM

第 4 章「インストールではインストーラの視点から RAID と LVM の技術を説明し、インストーラを使って初回インストール時に RAID や LVM を簡単に配備する方法について説明しました。初回インストールが終わったら、管理者は再インストールという手間のかかる最終手段を行使することなく、より大きなストレージ領域の要求に対処しなければいけません。すなわち、管理者は RAID と LVM ボリュームを操作するために必要なツールを理解しなければいけません。
RAID and LVM are both techniques to abstract the mounted volumes from their physical counterparts (actual hard-disk drives or partitions thereof); the former ensures the security and availability of the data in case of hardware failure by introducing redundancy, the latter makes volume management more flexible and independent of the actual size of the underlying disks. In both cases, the system ends up with new block devices, which can be used to create filesystems or swap space, without necessarily having them mapped to one physical disk. RAID and LVM come from quite different backgrounds, but their functionality can overlap somewhat, which is why they are often mentioned together.
RAID と LVM のどちらの場合も、カーネルはハードディスクドライブやパーティションに対応するブロックデバイスファイルとよく似たブロックデバイスファイルを提供します。アプリケーションやカーネルの別の部分がそのようなデバイスのあるブロックにアクセスを要求する場合、適切なサブシステムが要求されたブロックを物理層のブロックに対応付けます。設定に依存して、アプリケーション側から見たブロックは単独か複数の物理ディスクに保存されます。このブロックの物理的場所は論理デバイス内のブロックの位置と直接的に対応するものではないかもしれません。

12.1.1. ソフトウェア RAID

RAID means Redundant Array of Independent Disks. The goal of this system is to prevent data loss and ensure availability in case of hard disk failure. The general principle is quite simple: data are stored on several physical disks instead of only one, with a configurable level of redundancy. Depending on this amount of redundancy, and even in the event of an unexpected disk failure, data can be losslessly reconstructed from the remaining disks.
RAID は専用ハードウェア (SCSI や SATA コントローラカードに統合された RAID モジュール) またはソフトウェア抽象化 (カーネル) を使って実装することが可能です。ハードウェアかソフトウェアかに関わらず、十分な冗長性を備えた RAID システムはディスク障害があっても利用できる状態を透過的に継続することが可能です。従って、スタックの上層 (アプリケーション) はディスク障害にも関わらず、引き続きデータにアクセスできます。もちろん「信頼性低下状態」は性能に影響をおよぼし、冗長性を低下させます。このため、もう一つ別のディスク障害が起きるとデータを失うことになります。このため実践的には、管理者は信頼性低下状態を障害の起きたディスクが交換されるまでの間だけに留めるように努力します。新しいディスクが配備されると、RAID システムは要求されたデータを再構成することが可能です。こうすることで信頼性の高い状態に戻ります。信頼性低下状態か再構成状態にある RAID アレイのアクセス速度は低下する可能性がありますが、この点を除けばアプリケーションがディスク障害に気が付くことはないでしょう。
RAID がハードウェアで実装された場合、その設定は通常 BIOS セットアップツールによってなされます。カーネルは RAID アレイを標準的な物理ディスクとして機能する単一のディスクとみなします。RAID アレイのデバイス名は (ドライバに依存して) 違うかもしれません。
本書ではソフトウェア RAID だけに注目します。

12.1.1.1. さまざまな RAID レベル

実際のところ RAID の種類は 1 種類だけではなく、そのレベルによって識別される複数の種類があります。すなわち、設計と提供される冗長性の度合いが異なる複数の RAID レベルが存在します。より冗長性を高くすれば、より障害に強くなります。なぜなら、より多くのディスクで障害が起きても、システムを動かし続けることができるからです。これに応じて、与えられた一連のディスクに対して利用できる領域が小さくなります。すなわち、あるサイズのデータを保存するために必要なディスク領域のサイズが多くなります。
リニア RAID
Even though the kernel's RAID subsystem allows creating “linear RAID”, this is not proper RAID, since this setup doesn't involve any redundancy. The kernel merely aggregates several disks end-to-end and provides the resulting aggregated volume as one virtual disk (one block device). That is about its only function. This setup is rarely used by itself (see later for the exceptions), especially since the lack of redundancy means that one disk failing makes the whole aggregate, and therefore all the data, unavailable.
RAID-0
同様に RAID-0 にも冗長性がありません。しかしながら、RAID-0 は順番通り単純に物理ディスクを連結する構成ではありません。すなわち、物理ディスクはストライプ状に分割され、仮想デバイスのブロックは互い違いになった物理ディスクのストライプに保存されます。たとえば 2 台のディスクから構成されている RAID-0 セットアップでは、偶数を付番されたブロックは最初の物理ディスクに保存され、奇数を付番されたブロックは 2 番目の物理ディスクに保存されます。
This system doesn't aim at increasing reliability, since (as in the linear case) the availability of all the data is jeopardized as soon as one disk fails, but at increasing performance: during sequential access to large amounts of contiguous data, the kernel will be able to read from both disks (or write to them) in parallel, which increases the data transfer rate. The disks are utilized entirely by the RAID device, so they should have the same size not to lose performance.
RAID-0 use is shrinking, its niche being filled by LVM (see later).
RAID-1
RAID-1 は「RAID ミラーリング」としても知られ、最も簡単で最も広く使われています。RAID-1 の標準的な構成では、同じサイズの 2 台の物理ディスクを使い、物理ディスクと同じサイズの論理ボリュームが利用できるようになります。データを両方のディスクに保存するため、「ミラー」と呼ばれています。一方のディスクに障害があっても、他方のディスクからデータを利用することが可能です。もちろん、非常に重要なデータ用に RAID-1 を 2 台以上の構成にすることも可能ですが、これはハードウェア費用と利用できる保存領域の比率に直接的な影響をおよぼします。
RAID-1 は高価であるにも関わらず (良くても物理ストレージ領域のたった半分しか使えないにも関わらず)、広く実運用されています。RAID-1 は簡単に理解でき、簡単にバックアップできます。なぜなら両方のディスクが全く同じ内容を持っているため、片方を一時的に取り外しても運用システムに影響をおよぼさないからです。通常 RAID-1 を使うことで、読み込み性能は好転します。なぜなら、カーネルはデータの半分をそれぞれのディスクから並行して読むことができるからです。これに対して、書き込み性能はそれほど悪化しません。N 台のディスクからなる RAID-1 アレイの場合、データは N-1 台のディスク障害に対して保護されます。
RAID-4
RAID-4 は広く使われていません。RAID-4 は実データを保存するために N 台のディスクを使い、冗長性情報を保存するために 1 台の「パリティ」ディスクを使います。「パリティ」ディスクに障害が起きた場合、システムは他の N 台からデータを再構成することが可能です。N 台のデータディスクのうち、最大で 1 台に障害が起きた場合、残りの N-1 台と「パリティ」ディスクには、要求されたデータを再構成するために十分な情報が含まれます。
RAID-4 は高価過ぎるというわけではありません。なぜならディスク 1 台につきたった N 分の 1 台分の追加費用で済むからです。また RAID-4 を使うと読み込み性能が大きく低下するというわけでもありません。しかしながら、RAID-4 は書き込み性能に深刻な影響をおよぼします。加えて、N 台の実データ用ディスクのどのディスクに書き込んでもパリティディスクに対する書き込みが発生するので、パリティディスクは実データ用ディスクに比べて書き込み回数が増えます。その結果、パリティディスクは極めて寿命が短くなります。RAID-4 アレイのデータは (N+1 台のディスクのうち) 1 台の障害に対して保護されます。
RAID-5
RAID-5 は RAID-4 の非対称性問題を対処したものです。すなわち、パリティブロックは N+1 台のディスクに分散して保存され、特定のディスクが特定の役割を果たすことはありません。
読み込みと書き込み性能は RAID-4 と同様です。繰り返しになりますが、RAID-5 システムは (N+1 台のディスクのうち) 最大で 1 台までに障害が起きても動作します。
RAID-6
RAID-6 は RAID-5 の拡張と考えられます。RAID-6 では、N 個の連続するブロックに対して 2 個の冗長性ブロックを使います。この N+2 個のブロックは N+2 台のディスクに分散して保存されます。
RAID-6 は RAID-4 と RAID-5 に比べて少し高価ですが、RAID-6 を使うことで安全性はさらに高まります。なぜなら、(N+2 台中の) 最大で 2 台までの障害に対してデータを守ることが可能だからです。書き込み操作は 1 つのデータブロックと 2 つの冗長性ブロックを書き込むことに対応しますから、RAID-6 の書き込み性能は RAID-4 と RAID-5 に比べてさらに悪化します。
RAID-1+0
This isn't strictly speaking, a RAID level, but a stacking of two RAID groupings. Starting from 2×N disks, one first sets them up by pairs into N RAID-1 volumes; these N volumes are then aggregated into one, either by “linear RAID” or (increasingly) by LVM. This last case goes farther than pure RAID, but there is no problem with that.
RAID-1+0 は複数のディスク障害を乗り切ることが可能です。具体的に言えば、上に挙げた 2×N アレイの場合、最大で N 台までの障害に耐えます。ただし、各 RAID-1 ペアを構成するディスクの両方に障害が発生してはいけません。
RAID レベルを選ぶ際には、各用途からの制限および要求を考慮する必要があるのは明らかです。1 台のコンピュータに異なる設定を持つ複数の RAID アレイを配置することが可能である点に注意してください。

12.1.1.2. RAID の設定

RAID ボリュームを設定するには mdadm パッケージが必要です。mdadm パッケージには RAID アレイを作成したり操作するための mdadm コマンド、システムの他の部分に RAID アレイを統合するためのスクリプトやツール、監視システムが含まれます。
以下の例では、多数のディスクを持つサーバをセットアップします。ディスクの一部は既に利用されており、残りは RAID をセットアップするために利用できるようになっています。最初の状態で、以下のディスクとパーティションが存在します。
  • sdb ディスク (4 GB) は全領域を利用できます。
  • sdc ディスク (4 GB) は全領域を利用できます。
  • sdd ディスクは sdd2 パーティション (約 4 GB) だけを利用できます。
  • sde ディスク (4 GB) は全領域を利用できます。
RAID-0 とミラー (RAID-1) の 2 つのボリュームを作るために上記の物理ディスクを使います。それでは RAID-0 ボリュームから作っていきましょう。
# mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sdb /dev/sdc
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
# mdadm --query /dev/md0
/dev/md0: 8.00GiB raid0 2 devices, 0 spares. Use mdadm --detail for more detail.
# mdadm --detail /dev/md0
/dev/md0:
           Version : 1.2
     Creation Time : Tue Jun 25 08:47:49 2019
        Raid Level : raid0
        Array Size : 8378368 (7.99 GiB 8.58 GB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

       Update Time : Tue Jun 25 08:47:49 2019
             State : clean 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

        Chunk Size : 512K

Consistency Policy : none

              Name : mirwiz:0  (local to host debian)
              UUID : 146e104f:66ccc06d:71c262d7:9af1fbc7
            Events : 0

    Number   Major   Minor   RaidDevice State
       0       8       32        0      active sync   /dev/sdb
       1       8       48        1      active sync   /dev/sdc
# mkfs.ext4 /dev/md0
mke2fs 1.44.5 (15-Dec-2018)
Discarding device blocks: done                            
Creating filesystem with 2094592 4k blocks and 524288 inodes
Filesystem UUID: 413c3dff-ab5e-44e7-ad34-cf1a029cfe98
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

# mkdir /srv/raid-0
# mount /dev/md0 /srv/raid-0
# df -h /srv/raid-0
Filesystem      Size  Used Avail Use% Mounted on
/dev/md0        7.9G   36M  7.4G   1% /srv/raid-0
The mdadm --create command requires several parameters: the name of the volume to create (/dev/md*, with MD standing for Multiple Device), the RAID level, the number of disks (which is compulsory despite being mostly meaningful only with RAID-1 and above), and the physical drives to use. Once the device is created, we can use it like we'd use a normal partition, create a filesystem on it, mount that filesystem, and so on. Note that our creation of a RAID-0 volume on md0 is nothing but coincidence, and the numbering of the array doesn't need to be correlated to the chosen amount of redundancy. It is also possible to create named RAID arrays, by giving mdadm parameters such as /dev/md/linear instead of /dev/md0.
同様のやり方で RAID-1 を作成します。注意するべき違いは作成後に説明します。
# mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdd2 /dev/sde
mdadm: Note: this array has metadata at the start and
    may not be suitable as a boot device.  If you plan to
    store '/boot' on this device please ensure that
    your boot-loader understands md/v1.x metadata, or use
    --metadata=0.90
mdadm: largest drive (/dev/sdd2) exceeds size (4192192K) by more than 1%
Continue creating array? y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md1 started.
# mdadm --query /dev/md1
/dev/md1: 4.00GiB raid1 2 devices, 0 spares. Use mdadm --detail for more detail.
# mdadm --detail /dev/md1
/dev/md1:
           Version : 1.2
     Creation Time : Tue Jun 25 10:21:22 2019
        Raid Level : raid1
        Array Size : 4189184 (4.00 GiB 4.29 GB)
     Used Dev Size : 4189184 (4.00 GiB 4.29 GB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

       Update Time : Tue Jun 25 10:22:03 2019
             State : clean, resyncing 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : resync

     Resync Status : 93% complete

              Name : mirwiz:1  (local to host debian)
              UUID : 7d123734:9677b7d6:72194f7d:9050771c
            Events : 16

    Number   Major   Minor   RaidDevice State
       0       8       64        0      active sync   /dev/sdd2
       1       8       80        1      active sync   /dev/sde
# mdadm --detail /dev/md1
/dev/md1:
[...]
          State : clean
[...]
いくつかの注意点があります。最初に、mdadm は物理デバイス同士のサイズが異なる点を指摘しています。さらに、このことによりサイズが大きい側のデバイスの一部の領域が使えなくなるため、確認が求められています。
さらに重要なことは、ミラーの状態に注意することです。RAID ミラーの正常な状態とは、両方のディスクが全く同じ内容を持っている状態です。しかしながら、ボリュームを最初に作成した直後の RAID ミラーは正常な状態であることを保証されません。このため、RAID サブシステムは RAID ミラーの正常な状態を保証するために、RAID デバイスが作成されたらすぐに同期化作業を始めます。しばらくの後 (必要な時間はディスクの実サイズに依存します)、RAID アレイは「active」または「clean」状態に移行します。同期化作業中、ミラーは信頼性低下状態で、冗長性は保証されない点に注意してください。同期化作業中にディスク障害が起きると、すべてのデータを失うことにつながる恐れがあります。しかしながら、最近作成された RAID アレイの最初の同期化作業の前に大量の重要なデータがこの RAID アレイに保存されていることはほとんどないでしょう。信頼性低下状態であっても /dev/md1 を利用することが可能で、ファイルシステムを作成したり、データのコピーを取ったりすることが可能という点に注意してください。
RAID-1 アレイを構成するディスクの 1 台に障害が発生した場合、何が起きるかを見て行きましょう。mdadm--fail オプションを付けることで、ディスク障害を模倣することが可能です。
# mdadm /dev/md1 --fail /dev/sde
mdadm: set /dev/sde faulty in /dev/md1
# mdadm --detail /dev/md1
/dev/md1:
[...]
       Update Time : Tue Jun 25 11:03:44 2019
             State : clean, degraded 
    Active Devices : 1
   Working Devices : 1
    Failed Devices : 1
     Spare Devices : 0

Consistency Policy : resync

              Name : mirwiz:1  (local to host debian)
              UUID : 7d123734:9677b7d6:72194f7d:9050771c
            Events : 20

    Number   Major   Minor   RaidDevice State
       -       0        0        0      removed
       1       8       80        1      active sync   /dev/sdd2

       0       8       64        -      faulty   /dev/sde
RAID-1 ボリュームの内容はまだアクセスすることが可能ですが (そして、RAID-1 ボリュームがマウントされていた場合、アプリケーションはディスク障害に気が付きませんが)、データの安全性はもはや保証されません。つまり sdd ディスクにも障害が発生した場合、データは失われます。この危険性を避けるために、障害の発生したディスクを新しいディスク sdf に交換します。
# mdadm /dev/md1 --add /dev/sdf
mdadm: added /dev/sdf
# mdadm --detail /dev/md1
/dev/md1:
[...]
      Raid Devices : 2
     Total Devices : 3
       Persistence : Superblock is persistent

       Update Time : Tue Jun 25 11:09:42 2019
             State : clean, degraded, recovering 
    Active Devices : 1
   Working Devices : 2
    Failed Devices : 1
     Spare Devices : 1

Consistency Policy : resync

    Rebuild Status : 27% complete

              Name : mirwiz:1  (local to host debian)
              UUID : 7d123734:9677b7d6:72194f7d:9050771c
            Events : 26

    Number   Major   Minor   RaidDevice State
       2       8       96        0      spare rebuilding   /dev/sdf
       1       8       80        1      active sync   /dev/sdd2

       0       8       64        -      faulty   /dev/sde
# [...]
[...]
# mdadm --detail /dev/md1
/dev/md1:
[...]
       Update Time : Tue Jun 25 11:10:47 2019
             State : clean 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 1
     Spare Devices : 0

Consistency Policy : resync

              Name : mirwiz:1  (local to host debian)
              UUID : 7d123734:9677b7d6:72194f7d:9050771c
            Events : 39

    Number   Major   Minor   RaidDevice State
       2       8       96        0      active sync   /dev/sdd2
       1       8       80        1      active sync   /dev/sdf

       0       8       64        -      faulty   /dev/sde
繰り返しになりますが、ボリュームはまだアクセスすることが可能とは言うもののボリュームが信頼性低下状態ならば、カーネルは自動的に再構成作業を実行します。再構成作業が終了したら、RAID アレイは正常状態に戻ります。ここで、システムに sde ディスクをアレイから削除することを伝えることが可能です。削除することで、2 台のディスクからなる古典的な RAID ミラーになります。
# mdadm /dev/md1 --remove /dev/sde
mdadm: hot removed /dev/sde from /dev/md1
# mdadm --detail /dev/md1
/dev/md1:
[...]
    Number   Major   Minor   RaidDevice State
       2       8       96        0      active sync   /dev/sdd2
       1       8       80        1      active sync   /dev/sdf
この後、今後サーバの電源を切った際にドライブを物理的に取り外したり、ハードウェア設定がホットスワップに対応しているならばドライブをホットリムーブすることが可能です。一部の SCSI コントローラ、多くの SATA ディスク、USB や Firewire で接続された外部ドライブなどはホットスワップに対応しています。

12.1.1.3. 設定のバックアップ

RAID ボリュームに関連するメタデータのほとんどはアレイを構成するディスク上に直接保存されています。このため、カーネルはアレイとその構成要素を検出し、システムの起動時に自動的にアレイを組み立てることが可能です。しかしながら、この設定をバックアップすることを推奨します。なぜなら、この検出機構は不注意による間違いを防ぐものではないからです。そして、注意して取り扱うべき状況ではまさに検出機構がうまく働かないことが見込まれます。上の例で、sde ディスク障害が本物で (模倣でない)、sde ディスクを取り外す前にシステムを再起動した場合、sde ディスクは再起動中に検出され、システムに復帰します。カーネルは 3 つの物理ディスクを検出し、それぞれのディスクが同じ RAID ボリュームの片割れであると主張します。さらに別の混乱する状況が考えられます。2 台のサーバで使われていた RAID ボリュームを片方のサーバに集約することを考えてみましょう。ディスクが移動される前、各アレイは正常に実行されていました。カーネルはアレイを検出して、適切なペアを組み立てることが可能です。しかし、片方のサーバに移動されたディスクが前のサーバでは md1 に組み込まれており、さらに新しいサーバが既に md1 という名前のアレイを持っていた場合、どちらか一方の名前が変えられます。
このため、参考情報に過ぎないとは言うものの、設定を保存することは重要です。設定を保存する標準的な方法は /etc/mdadm/mdadm.conf ファイルを編集することです。以下に例を示します。

例 12.1 mdadm 設定ファイル

# mdadm.conf
#
# !NB! Run update-initramfs -u after updating this file.
# !NB! This will ensure that initramfs has an uptodate copy.
#
# Please refer to mdadm.conf(5) for information about this file.
#

# by default (built-in), scan all partitions (/proc/partitions) and all
# containers for MD superblocks. alternatively, specify devices to scan, using
# wildcards if desired.
DEVICE /dev/sd*

# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes

# automatically tag new arrays as belonging to the local system
HOMEHOST <system>

# instruct the monitoring daemon where to send mail alerts
MAILADDR root

# definitions of existing MD arrays
ARRAY /dev/md0 metadata=1.2 name=mirwiz:0 UUID=146e104f:66ccc06d:71c262d7:9af1fbc7
ARRAY /dev/md1 metadata=1.2 name=mirwiz:1 UUID=7d123734:9677b7d6:72194f7d:9050771c

# This configuration was auto-generated on Tue, 25 Jun 2019 07:54:35 -0400 by mkconf
最も役に立つ設定項目の 1 つに DEVICE オプションがあります。これは起動時にシステムが RAID ボリュームの構成情報を自動的に探すデバイスをリストします。上の例では、値をデフォルト値 partitions containers からデバイスファイルを明示したリストに置き換えました。なぜなら、パーティションだけでなくすべてのディスクをボリュームとして使うように決めたからです。
上の例における最後の 2 行を使うことで、カーネルはアレイに割り当てるボリューム番号を安全に選ぶことが可能です。ディスク本体に保存されたメタ情報はボリュームをもう一度組み上げるのに十分ですが、ボリューム番号を定義する (そして /dev/md* デバイス名にマッチすることを確認する) には不十分です。
幸いなことに、以下のコマンドを実行すればこの行を自動的に生成することが可能です。
# mdadm --misc --detail --brief /dev/md?
ARRAY /dev/md0 metadata=1.2 name=mirwiz:0 UUID=146e104f:66ccc06d:71c262d7:9af1fbc7
ARRAY /dev/md1 metadata=1.2 name=mirwiz:1 UUID=7d123734:9677b7d6:72194f7d:9050771c
最後の 2 行の内容はボリュームを構成するディスクのリストに依存しません。このため、障害の発生したディスクを新しいディスクに交換した際に、これをもう一度生成する必要はありません。逆に、RAID アレイを作成および削除した際に、必ずこの設定ファイルを注意深く更新する必要があります。

12.1.2. LVM

LVM (論理ボリュームマネージャ) は物理ディスクから論理ボリュームを抽象化するもう一つの方法で、信頼性を増加させるのではなく柔軟性を増加させることに注目しています。LVM を使うことで、アプリケーションから見る限り透過的に論理ボリュームを変更することが可能です。LVM を使うことで、たとえば新しいディスクを追加し、データを新しいディスクに移行し、古いディスクを削除することがボリュームをアンマウントせずに可能です。

12.1.2.1. LVM の概念

LVM の柔軟性は 3 つの概念から構成された抽象化レベルによって達成されます。
1 番目の概念は PV (物理ボリューム) です。PV はハードウェアに最も近い要素です。具体的に言えば、PV はディスクのパーティション、ディスク全体、その他の任意のブロックデバイス (たとえば、RAID アレイ) などの物理的要素を指します。物理的要素を LVM の PV に設定した場合、物理的要素へのアクセスは必ず LVM を介すべきという点に注意してください。そうでなければ、システムが混乱します。
A number of PVs can be clustered in a VG (Volume Group), which can be compared to disks both virtual and extensible. VGs are abstract, and don't appear in a device file in the /dev hierarchy, so there is no risk of using them directly.
3 番目の概念は LV (論理ボリューム) です。LV は VG の中の 1 つの塊です。さらに VG をディスクに例えたのと同様の考え方を使うと、LV はパーティションに例えられます。LV はブロックデバイスとして /dev に現れ、他の物理パーティションと同様に取り扱うことが可能です (一般的に言えば、LV にファイルシステムやスワップ領域を作成することが可能です)。
ここで重要な事柄は VG を LV に分割する場合に物理的要素 (PV) はいかなる制約も要求しないという点です。1 つの PV (たとえばディスク) から構成される VG を複数の LV に分割できます。同様に、複数の PV から構成される VG を 1 つの大きな LV として提供することも可能です。制約事項がたった 1 つしかないのは明らかです。それはある VG から分割された LV のサイズの合計はその VG を構成する PV のサイズの合計を超えることができないという点です。
しかしながら、ある VG を構成する PV 同士の性能を同様のものにしたり、その VG から分割された LV 同士に求められる性能を同様のものにしたりすることは通常理に適った方針です。たとえば、利用できるハードウェアに高速な PV と低速な PV がある場合、高速な PV から構成される VG と低速な PV から構成される VG に分けると良いでしょう。こうすることで、高速な PV から構成される VG から分割された LV を高速なデータアクセスを必要とするアプリケーションに割り当て、低速な PV から構成される VG から分割された LV を負荷の少ない作業用に割り当てることが可能です。
いかなる場合でも、LV は特定の PV を使用するわけではないという点を覚えておいてください。ある LV に含まれるデータの物理的な保存場所を操作することも可能ですが、普通に使っている限りその必要はありません。逆に、VG を構成する PV 群の構成要素が変化した場合、ある LV に含まれるデータの物理的な保存場所は対象の LV の分割元である VG の中ひいてはその VG を構成する PV 群の構成要素の中を移動することがあります (もちろん、データの移動先は対象の LV の分割元の VG を構成する PV 群の構成要素の中に限られます)。

12.1.2.2. LVM の設定

典型的な用途に対する LVM の設定過程を、段階的に見て行きましょう。具体的に言えば、複雑なストレージの状況を単純化したい場合を見ていきます。通常、長く複雑な一時的措置を繰り返した挙句の果てに、この状況に陥ることがあります。説明目的で、徐々にストレージを変更する必要のあったサーバを考えます。このサーバでは、PV として利用できるパーティションが複数の一部使用済みディスクに分散しています。より具体的に言えば、以下のパーティションを PV として利用できます。
  • sdb ディスク上の sdb2 パーティション (4 GB)。
  • sdc ディスク上の sdc3 パーティション (3 GB)。
  • sdd ディスク (4 GB) は全領域を利用できます。
  • sdf ディスク上の sdf1 パーティション (4 GB) および sdf2 パーティション (5 GB)。
加えて、sdbsdf が他の 2 台に比べて高速であると仮定しましょう。
今回の目標は、3 種類の異なるアプリケーション用に 3 つの LV を設定することです。具体的に言えば、5 GB のストレージ領域が必要なファイルサーバ、データベース (1 GB)、バックアップ用の領域 (12 GB) 用の LV を設定することです。ファイルサーバとデータベースは高い性能を必要とします。しかし、バックアップはアクセス速度をそれほど重要視しません。これらの要件により、各アプリケーションに設定する LV の使用する PV が決定されます。さらに LVM を使いますので、PV の物理的サイズからくる制限はありません。このため、PV 群として利用できる領域のサイズの合計だけが制限となります。
LVM の設定に必要なツールは lvm2 パッケージとその依存パッケージに含まれています。これらのパッケージをインストールしたら、3 つの手順を踏んで LVM を設定します。各手順は LVM の概念の 3 つの抽象化レベルに対応します。
最初に、pvcreate を使って PV を作成します。
# pvcreate /dev/sdb2
  Physical volume "/dev/sdb2" successfully created.
# pvdisplay
  "/dev/sdb2" is a new physical volume of "4.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb2
  VG Name               
  PV Size               4.00 GiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               z4Clgk-T5a4-C27o-1P0E-lIAF-OeUM-e7EMwq

# for i in sdc3 sdd sdf1 sdf2 ; do pvcreate /dev/$i ; done
  Physical volume "/dev/sdc3" successfully created.
  Physical volume "/dev/sdd" successfully created.
  Physical volume "/dev/sdf1" successfully created.
  Physical volume "/dev/sdf2" successfully created.
# pvdisplay -C
  PV         VG Fmt  Attr PSize  PFree 
  /dev/sdb2     lvm2 ---   4.00g  4.00g
  /dev/sdc3     lvm2 ---   3.00g  3.00g
  /dev/sdd      lvm2 ---   4.00g  4.00g
  /dev/sdf1     lvm2 ---   4.00g  4.00g
  /dev/sdf2     lvm2 ---  <5.00g <5.00g
ここまでは順調です。PV はディスク全体およびディスク上の各パーティションに対して設定することが可能という点に注意してください。上に示した通り、pvdisplay コマンドは既存の PV をリストします。出力フォーマットは 2 種類あります。
vgcreate を使って、これらの PV から VG を構成しましょう。高速なディスクの PV から vg_critical VG を構成します。さらに、これ以外の低速なディスクの PV から vg_normal VG を構成します。
# vgcreate vg_critical /dev/sdb2 /dev/sdf1
  Volume group "vg_critical" successfully created
# vgdisplay
  --- Volume group ---
  VG Name               vg_critical
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               7.99 GiB
  PE Size               4.00 MiB
  Total PE              2046
  Alloc PE / Size       0 / 0   
  Free  PE / Size       2046 / 7.99 GiB
  VG UUID               wAbBjx-d82B-q7St-0KFf-z40h-w5Mh-uAXkNZ

# vgcreate vg_normal /dev/sdc3 /dev/sdd /dev/sdf2
  Volume group "vg_normal" successfully created
# vgdisplay -C
  VG          #PV #LV #SN Attr   VSize   VFree  
  vg_critical   2   0   0 wz--n-   7.99g   7.99g
  vg_normal     3   0   0 wz--n- <11.99g <11.99g
繰り返しになりますが、vgdisplay コマンドはかなり簡潔です (そして vgdisplay には 2 種類の出力フォーマットがあります)。同じ物理ディスク上にある 2 つの PV から 2 つの異なる VG を構成することが可能である点に注意してください。また、vg_ 接頭辞を VG の名前に使っていますが、これは慣例に過ぎない点に注意してください。
We now have two “virtual disks”, sized about 8 GB and 12 GB respectively. Let's now carve them up into “virtual partitions” (LVs). This involves the lvcreate command, and a slightly more complex syntax:
# lvdisplay
# lvcreate -n lv_files -L 5G vg_critical
  Logical volume "lv_files" created.
# lvdisplay
  --- Logical volume ---
  LV Path                /dev/vg_critical/lv_files
  LV Name                lv_files
  VG Name                vg_critical
  LV UUID                W6XT08-iBBx-Nrw2-f8F2-r2y4-Ltds-UrKogV
  LV Write Access        read/write
  LV Creation host, time debian, 2019-11-30 22:45:46 -0500
  LV Status              available
  # open                 0
  LV Size                5.00 GiB
  Current LE             1280
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           254:0

# lvcreate -n lv_base -L 1G vg_critical
  Logical volume "lv_base" created.
# lvcreate -n lv_backups -L 11.98G vg_normal
  Rounding up size to full physical extent 11.98 GiB
  Logical volume "lv_backups" created.
# lvdisplay -C
  LV         VG          Attr     LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync  Convert
  lv_base    vg_critical -wi-a---  1.00g                                           
  lv_files   vg_critical -wi-a---  5.00g                                           
  lv_backups vg_normal   -wi-a--- 11.98g
LV を作成する場合、2 種類のパラメータが必要です。このため、必ず 2 種類のパラメータをオプションとして lvcreate に渡します。作成する LV の名前を -n オプションで指定し、サイズを -L オプションで指定します。また、操作対象の VG をコマンドに伝えることが必要です。これはもちろん最後のコマンドラインパラメータです。
LV が作成され、ブロックデバイスファイルとして /dev/mapper/ に現れます。
# ls -l /dev/mapper
合計 0
crw------- 1 root root 10, 236  6月 10 16:52 control
lrwxrwxrwx 1 root root       7  6月 10 17:05 vg_critical-lv_base -> ../dm-1
lrwxrwxrwx 1 root root       7  6月 10 17:05 vg_critical-lv_files -> ../dm-0
lrwxrwxrwx 1 root root       7  6月 10 17:05 vg_normal-lv_backups -> ../dm-2
# ls -l /dev/dm-*
brw-rw---T 1 root disk 253, 0  6月 10 17:05 /dev/dm-0
brw-rw---- 1 root disk 253, 1  6月 10 17:05 /dev/dm-1
brw-rw---- 1 root disk 253, 2  6月 10 17:05 /dev/dm-2
ブロックデバイスファイルを分かり易くするために、VG に対応するディレクトリの中に便利なシンボリックリンクが作成されます。
# ls -l /dev/vg_critical
合計 0
lrwxrwxrwx 1 root root 7  6月 10 17:05 lv_base -> ../dm-1
lrwxrwxrwx 1 root root 7  6月 10 17:05 lv_files -> ../dm-0
# ls -l /dev/vg_normal
合計 0
lrwxrwxrwx 1 root root 7  6月 10 17:05 lv_backups -> ../dm-2
LV は標準的なパーティションと全く同様に取り扱われます。
# mkfs.ext4 /dev/vg_normal/lv_backups
mke2fs 1.44.5 (15-Dec-2018)
Discarding device blocks: done                            
Creating filesystem with 3140608 4k blocks and 786432 inodes
Filesystem UUID: b9e6ed2f-cb37-43e9-87d8-e77568446225
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

# mkdir /srv/backups
# mount /dev/vg_normal/lv_backups /srv/backups
# df -h /srv/backups
Filesystem                        Size  Used Avail Use% Mounted on
/dev/mapper/vg_normal-lv_backups   12G   41M   12G   1% /srv/backups
# [...]
[...]
# cat /etc/fstab
[...]
/dev/vg_critical/lv_base    /srv/base       ext4 defaults 0 2
/dev/vg_critical/lv_files   /srv/files      ext4 defaults 0 2
/dev/vg_normal/lv_backups   /srv/backups    ext4 defaults 0 2
アプリケーションにしてみれば、無数の小さなパーティションがわかり易い名前を持つ 1 つの大きな 12 GB のボリュームにまとめられたことになります。

12.1.2.3. 経時変化に伴う LVM の利便性

LVM のパーティションや物理ディスクを統合する機能は便利ですが、これは LVM のもたらす主たる利点ではありません。時間経過に伴い LVM のもたらす柔軟性が特に重要になる時とは LV のサイズを増加させる必要が生じた時でしょう。ここまでの例を使い、LV に新たに巨大なファイルを保存したいけれども、ファイルサーバ用の LV はこの巨大なファイルを保存するには狭すぎると仮定しましょう。vg_critical から分割できる全領域はまだ使い切られていないので、lv_files のサイズを増やすことが可能です。LV のサイズを増やすために lvresize コマンドを使い、LV のサイズの変化にファイルシステムを対応させるために resize2fs を使います。
# df -h /srv/files/
Filesystem                        Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_files  4.9G  4.2G  485M  90% /srv/files
# lvdisplay -C vg_critical/lv_files
  LV       VG          Attr     LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync  Convert
  lv_files vg_critical -wi-ao-- 5.00g
# vgdisplay -C vg_critical
  VG          #PV #LV #SN Attr   VSize VFree
  vg_critical   2   2   0 wz--n- 7.99g 1.99g
# lvresize -L 6G vg_critical/lv_files
  Size of logical volume vg_critical/lv_files changed from 5.00 GiB (1280 extents) to 6.00 GiB (1536 extents).
  Logical volume vg_critical/lv_files successfully resized.
# lvdisplay -C vg_critical/lv_files
  LV       VG          Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_files vg_critical -wi-ao---- 6.00g
# resize2fs /dev/vg_critical/lv_files
resize2fs 1.44.5 (15-Dec-2018)
Filesystem at /dev/vg_critical/lv_files is mounted on /srv/files; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vg_critical/lv_files is now 1572864 (4k) blocks long.

# df -h /srv/files/
Filesystem                        Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_files  5.9G  4.2G  1.5G  75% /srv/files
同様の方法でデータベースをホストしている lv_base のサイズを増加させます。以下の通り lv_base の分割元である vg_critical から分割できる領域は既にほぼ使い切った状態になっています。
# df -h /srv/base/
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_base  976M  882M   28M  97% /srv/base
# vgdisplay -C vg_critical
  VG          #PV #LV #SN Attr   VSize VFree   
  vg_critical   2   2   0 wz--n- 7.99g 1016.00m
でもご安心ください。LVM を使っていれば新しい PV を既存の VG を構成する PV の 1 つとして追加することが可能です。たとえば、今までは LVM の外で管理されていた sdb1 パーティションには、lv_backups に移動しても問題のないアーカイブだけが含まれていた点に気が付いたとしましょう。このため、sdb1 パーティションを vg_critical を構成する PV の 1 つとして再利用することが可能です。こうすることで、vg_critical から lv_base に分割される領域のサイズを増やすことが可能です。これが vgextend コマンドの目的です。もちろん、事前に sdb1 パーティションを PV として準備しなければいけません。vg_critical を拡張したら、先と同様のコマンドを使って先に lv_base のサイズを増加させ、その後に lv_base 上のファイルシステムのサイズを増加させます。
# pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created.
# vgextend vg_critical /dev/sdb1
  Volume group "vg_critical" successfully extended
# vgdisplay -C vg_critical
  VG          #PV #LV #SN Attr   VSize  VFree 
  vg_critical   3   2   0 wz--n- <9.99g <1.99g
# [...]
[...]
# df -h /srv/base/
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_base  2.0G  882M  994M  48% /srv/base

12.1.3. RAID それとも LVM?

1 番目の利用形態は用途が時間的に変化しない 1 台のハードディスクを備えたデスクトップコンピュータのような単純な利用形態です。この場合 RAID と LVM はどちらも疑う余地のない利点をもたらします。しかしながら、RAID と LVM は目標を分岐させて別々の道を歩んでいます。どちらを使うべきか悩むのは間違っていることではありません。最も適切な答えはもちろん現在の要求と将来に予測される要求に依存します。
いくつかの状況では、疑問の余地がないくらい簡単に答えを出すことが可能です。2 番目の利用形態はハードウェア障害からデータを保護することが求められる利用形態です。この場合、ディスクの冗長性アレイ上に RAID をセットアップするのは明らかです。なぜなら LVM はこの種の問題への対応策を全く用意していないからです。逆に、柔軟なストレージ計画が必要でディスクの物理的な配置に依存せずにボリュームを構成したい場合、RAID はあまり役に立たず LVM を選ぶのが自然です。
3 番目に注目すべき利用形態は単に 2 つのディスクを 1 つのボリュームにまとめるような利用形態です。性能が欲しかったり、利用できるディスクのどれよりも大きな単一のファイルシステムにしたい場合にこの利用形態が採用されます。この場合、RAID-0 (またはリニア RAID) か LVM ボリュームを使って対処できます。この状況では、追加的な制約事項 (たとえば、他のコンピュータが RAID だけを使っている場合に RAID を使わなければいけないなどの制約事項) がなければ、通常 LVM を選択すると良いでしょう。LVM の最初のセットアップは RAID に比べて複雑ですが、LVM は複雑度を少し増加させるだけで要求が変った場合や新しいディスクを追加する必要ができた場合に対処可能な追加的な柔軟性を大きく上昇させます。
そしてもちろん、最後の本当に興味深い利用形態はストレージシステムにハードウェア障害に対する耐性を持たせさらにボリューム分割に対する柔軟性を持たせる必要がある場合の利用形態です。RAID と LVM のどちらも片方だけで両方の要求を満足させることは不可能です。しかし心配ありません。この要求を満足させるには RAID と LVM の両方を同時に使用する方針、正確に言えば一方の上に他方を構成する方針を採用すれば良いでのです。RAID と LVM の高い成熟度のおかげでほぼ標準になりつつある方針に従うならば、最初にディスクを少数の大きな RAID アレイにグループ分けすることでデータの冗長性を確保します。さらにそれらの RAID アレイを LVM の PV として使います。そして、ファイルシステム用の VG から分割された LV を論理パーティションとして使います。この標準的な方針の優れた点は、ディスク障害が起きた場合に再構築しなければいけない RAID アレイの数が少ない点です。このため、管理者は復旧に必要な時間を減らすことが可能です。
ここで具体例を見てみましょう。たとえば Falcot Corp の広報課は動画編集用にワークステーションを必要としていますが、広報課の予算の都合上、最初から高性能のハードウェアに投資することは不可能です。このため、グラフィック性能を担うハードウェア (モニタとビデオカード) に大きな予算を割き、ストレージ用には一般的なハードウェアを使うことが決定されました。しかしながら、広く知られている通りデジタルビデオ用のストレージはある種の条件を必要とします。すなわち、保存されるデータのサイズが大きく、このデータを読み込みおよび書き込みする際の処理速度がシステム全体の性能にとって重要 (たとえば、平均的なアクセス時間よりも重要) という条件です。この条件を一般的なハードウェアを使って満足させる必要があります。今回の場合 2 台の SATA ハードディスクドライブを使います。さらに、システムデータと一部のユーザデータはハードウェア障害に対する耐性を持たせる必要があります。編集済みのビデオクリップを保護する必要はありますが、編集前のビデオ素材をそれほど気にする必要はありません。なぜなら、編集前のビデオ素材はまだビデオテープに残されているからです。
前述の条件を満足させるために RAID-1 と LVM を組み合わせます。ディスクの並行アクセスを最適化し、そして障害が同時に発生する危険性を減らすために、各ディスクは 2 つの異なる SATA コントローラに接続されています。このため、各ディスクは sdasdc として現れます。どちらのディスクも以下に示したパーティショニング方針に従ってパーティショニングされます。
# fdisk -l /dev/sda

Disk /dev/sda: 300 GB, 300090728448 bytes, 586114704 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00039a9f

Device    Boot     Start       End   Sectors Size Id Type
/dev/sda1 *         2048   1992060   1990012 1.0G fd Linux raid autodetect
/dev/sda2        1992061   3984120   1992059 1.0G 82 Linux swap / Solaris
/dev/sda3        4000185 586099395 582099210 298G 5  Extended
/dev/sda5        4000185 203977305 199977120 102G fd Linux raid autodetect
/dev/sda6      203977306 403970490 199993184 102G fd Linux raid autodetect
/dev/sda7      403970491 586099395 182128904  93G 8e Linux LVM
  • sda1sdc1 パーティション (約 1 GB) から RAID-1 ボリューム md0 を構成します。md0 はルートファイルシステムを保存するために直接的に使われます。
  • sda2sdc2 パーティションから swap パーティションを作成します。スワップ領域のサイズは合計で 2 GB になります。RAM のサイズ 1 GB と合わせれば、ワークステーションで利用できるメモリサイズは十分な量と言えます。
  • sda5sdc5 パーティションおよび sda6sdc6 パーティションからそれぞれ約 100 GB の 2 つの新しい RAID-1 ボリューム md1md2 を構成します。md1md2 は LVM の PV として初期化され、これらの PV から vg_raid VG を構成します。vg_raid は約 200 GB の安全な領域になります。
  • 残りのパーティションである sda7sdc7 はそのまま LVM の PV として初期化され、これらの PV から vg_bulk VG を構成します。vg_bulk はおよそ 200 GB の領域になります。
VG を作成したら、VG をとても柔軟な方法で LV に分割することが可能です。vg_raid から分割された LV は 1 台のディスク障害に対して耐性を持ちますが、vg_bulk から分割された LV はディスク障害に対する耐性を持たない点を忘れないでください。逆に、vg_bulk は両方のディスクにわたって割り当てられるので、vg_bulk から分割された LV に保存された巨大なファイルの読み書き速度は高速化されるでしょう。
We will therefore create the lv_var and lv_home LVs on vg_raid, to host the matching filesystems; another large LV, lv_movies, will be used to host the definitive versions of movies after editing. The other VG will be split into a large lv_rushes, for data straight out of the digital video cameras, and a lv_tmp for temporary files. The location of the work area is a less straightforward choice to make: while good performance is needed for that volume, is it worth risking losing work if a disk fails during an editing session? Depending on the answer to that question, the relevant LV will be created on one VG or the other.
We now have both some redundancy for important data and much flexibility in how the available space is split across the applications.