TT Lab
はじめる
学ぶ 学習パス コース

LFCS — Linux Foundation認定システム管理者

拡張は二つの層で別々に起きる — LVM・fstab・swap・NFS・autofs

TT Labで続きを見る

一言でいうと

ストレージは層です。ブロックデバイスの上にLVMが、その上にファイルシステムが、その上にマウントがあり、各層は自分の下の層だけを知っています。そのため、LVを拡張してもファイルシステムは知らず、fstabを変更してもカーネルは知らず、/etc/exportsを変更してもNFSサーバーは知りません。このモジュールのラボは、その「知らない」を、1つずつ手で教える練習です。

なぜ必要なのか

前のモジュール(lfcs-storage)はPodで動いていました。そこにはmountもpvcreateもなく、読み物自身が「仮想マシンやループバックデバイスを使える環境で、別に練習することをお勧めする」と書いていました。LFCSのStorageドメインは20%なのに、その全部が概念の説明にとどまっていました。

このモジュールはUbuntu 24.04のVMで動きます。rootで、systemdがPID 1なので、すべて本物として動作します。ただし、空きディスクはありません。プラットフォームが付けてくれるスクラッチディスクは、cloud-initがすでにext4でフォーマットしてバインドしているからです。そのため、最初のステップがlosetupです。losetup(8)は、通常のファイルをブロックデバイスのように見せるループデバイスを扱うツールで、ディスクなしでLVM・RAID・ファイルシステムを試すときに、実務でもまさにこのように使います。Ubuntuのクラウドイメージは、snapが/dev/loop0からいくつかをすでに使っているので、番号を固定すると「デバイスがビジー状態です」に出会います。losetup -f --showで空いているものを受け取り、あとでlosetup -j <파일>で見つけ直します(プレースホルダーはファイルです)。

どう動くのか

LVMは3つの層です。lvm(8)の用語で、PV(physical volume)はLVMラベルを書いたブロックデバイス、VG(volume group)はPVを集めたプール、LV(logical volume)はそのプールから切り出したブロックデバイスです。VGは、エクステント(デフォルトは4MiB)単位で領域を管理するので、lvcreate -L 600Mは、エクステントを150個確保します。ディスクをさらに追加することは、pvcreateのあとvgextendでVGに入れることで、LVはそのあとで拡張します。パーティションを切り直さなくてよいことが、LVMを使う理由です。

層 作成するコマンド 拡張するコマンド 確認するコマンド
PV pvcreate — pvs
VG vgcreate vgextend vgs
LV lvcreate lvextend lvs
ファイルシステム mkfs.ext4 resize2fs df

ここで試験が最もよく突いてくるのが、最後の2行です。lvextend(8)は、LVというブロックデバイスを大きくするだけで、その上のext4は、自分が900MiBのデバイスの上に乗っていることを知りません。lvsは900Mなのに、dfはそのままという状態が、それです。resize2fs(8)がファイルシステムの層を合わせ、ext4はマウントしたまま(オンラインで)拡張できます。lvextend -rは、この2つの層を一度に処理するオプションです。

fstabには、デバイス名ではなくUUIDで書きます。fstab(5)の最初のフィールドはデバイスですが、/dev/sdb1や/dev/loop3のような名前は、起動の順序によって変わることがあります。ファイルシステムに刻まれたUUIDは変わりません。blkidで読み取ってUUID=…として書き、6つのフィールド(デバイス・マウントポイント・タイプ・オプション・dump・pass)を空白で区切ります。変更したあとは、さらに2つのことをする必要があります。systemdはfstabを.mountユニットに変換するのでsystemctl daemon-reload、そしてmount -aで、その行が実際に動作するかを今確認します。findmnt --verifyが[E]を1つでも出したら、次の起動でemergencyシェルに出会います。

スワップファイルは、権限が600である必要があります。mkswap(8)は、権限が広いファイルに「insecure permissions」の警告を出します。スワップにはメモリのコピーが入るので、他のユーザーが読めてはいけません。作成・chmod 600・mkswap・swaponの順序で、fstabのマウントポイントの位置はnone、タイプはswapです。

NFSサーバーは、ファイルを変更したことを知りません。exports(5)の形式は디렉터리 클라이언트(옵션)で、クライアントと開き括弧の間に空白を入れると、そのオプションがクライアントではなく全員に適用されます。manページが明示的に警告している落とし穴です(プレースホルダーは順に、ディレクトリ、クライアント、オプションです)。ファイルを変更したあと、exportfs(8)の-raでサーバーに知らせ、exportfs -vで実際にエクスポートされているかを見ます。NFSv4は2049だけで動作するので、このラボのように、同じVMの中で127.0.0.1:/srv/shareをマウントできます。

autofsは、アクセスしたときに取り付けます。auto.master(5)のマスターマップが「どのディレクトリの下を、どのマップで」を決め、autofs(5)のマップファイルが「キー オプション ソース」を決めます。Ubuntuの/etc/auto.masterは、末尾に+dir:/etc/auto.master.dがあり、そのディレクトリの*.autofsファイルがマスターマップとして読まれます。マップを書いたあと、デーモンを再起動する必要があり、ls /nfs/shareが、そのままマウントのトリガーです。1つ驚く点: サーバーが自分自身の場合、autofsはNFSの代わりにbindマウントで取り付けます。auto.master(5)は、nobindオプションを「local NFS filesystemsのbind mountingを防ぐ」と説明していて、その文がデフォルトの動作を教えてくれます。

現場での姿

「ディスクを拡張したのに、なぜ容量がそのままなのか」という質問は、クラウドでも毎週出ます。ボリュームを拡張すること(クラウドコンソール)、パーティションまたはLVを拡張すること、ファイルシステムを拡張することは、3つの層の仕事で、コンソールでサイズを変えた人は、最初の層だけを行ったことになります。ノードに入って、lsblkでデバイスが大きくなったか、lvsでLVが大きくなったか、dfでファイルシステムが大きくなったかを、上から下へたどりながら見れば、どの層で止まったかが、一度にわかります。

KubernetesのReadWriteManyボリュームは、たいていNFSです。Podがmount.nfs: access denied by serverで止まったら、サーバー側の/etc/exportsのクライアント範囲がノードのIPを含んでいるか、そして、exportfs -vに本当にそのエントリがあるかを見ます。ファイルにはあるのにexportfs -raを実行していない場合が、思ったより多いです。

ディスクの性能問題は、iostat(1)とvmstat(8)で切り分けます。どちらも最初のサンプルは起動後の累積平均なので捨てる必要があり、iostat -xの%utilとawaitがディスクがビジーかを、vmstatのsi/soの列がスワップを叩いているかを、教えてくれます。

次のラボですること

ループデバイス2つ → PV → VGvg_lfcs → LVlv_data(ext4) → /srv/dataのマウントとUUIDのfstabの行 → オンライン拡張 → 256MiBのスワップファイル → /srv/shareを127.0.0.1にだけNFSでエクスポートしてマウント → 同じ共有をautofsで → iostat・vmstatの指標と要約ファイル。採点ツールは、ファイルだけを見るのではなく、vgs・lvs・findmnt・swapon --show・exportfs -vで、今のシステムを見ます。ですから、「ファイルを変更した」で止まらずに、「デーモンが知ったか」まで進んでください。