0Pricing
DevOps Bootcamp · レッスン

ディスク、ファイルシステム、マウントの自動化

ブロックデバイスを調査し、fstabエントリを管理して、LVMやマウント操作を安全にスクリプト化します。

「ディスク、ファイルシステム、マウントの自動化」はCoddyKit上の無料DevOps Bootcampレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはDevOps Bootcamp学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 DevOps Bootcampコースには全4レッスンが含まれています。

lsblkとfdiskでブロックデバイスを理解する

ディスク操作を自動化する前に、システム上にどのブロックデバイスが存在するかを確認できなければなりません。必須のツールはlsblkとfdisk -lです。

  • lsblk — デバイス名、サイズ、マウントポイント、種類(disk、part、lvm)を示すブロックデバイスの一覧をツリー形式で表示します
  • fdisk -l — パーティションテーブルとセクターの詳細を表示します(root権限が必要です)
  • blkid — 各ブロックデバイスのUUIDとファイルシステムの種類を表示します

スクリプトでは、この出力を解析して利用可能なディスクを検出したり、パーティションがフォーマット済みか確認したり、マウント前にUUIDを特定したりすることがよくあります。

#!/usr/bin/env bash
# Inspect all block devices and their UUIDs
set -euo pipefail

echo '=== Block Device Tree ==='
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,UUID

echo ''
echo '=== Partition Table Details ==='
sudo fdisk -l 2>/dev/null | grep -E '^Disk |^/dev/'

echo ''
echo '=== UUID Lookup via blkid ==='
sudo blkid | awk -F: '{print $1}' | while read -r dev; do
  uuid=$(sudo blkid -s UUID -o value "$dev" 2>/dev/null || echo 'N/A')
  fstype=$(sudo blkid -s TYPE -o value "$dev" 2>/dev/null || echo 'unknown')
  printf '%-20s UUID=%-38s TYPE=%s\n' "$dev" "$uuid" "$fstype"
done

dfとduでディスク容量を確認する

dfとduは、ファイルシステムとディレクトリの使用量を報告するための基本ツールです。システム管理スクリプトでは、アラートの発生、クォータの適用、追加領域をプロビジョニングするタイミングの判断などに使用します。

  • df -h — マウントされているすべてのファイルシステムの使用量を、人間が読みやすい形式で表示します
  • df -BG — 一貫した数値解析ができるよう、ギガバイト単位で出力します
  • du -sh /path — 特定のディレクトリのサイズを集計して表示します
  • du -d 1 /var — 1階層分の内訳を表示します(どのサブディレクトリが大きいかを調べるのに便利です)

dfの使用率列は、監視スクリプトでディスクフルアラートを発生させるためによく解析されます。

#!/usr/bin/env bash
# Alert if any mounted filesystem exceeds a usage threshold
set -euo pipefail

THRESHOLD=80   # percent

echo 'Checking filesystem usage...'
df -h --output=source,pcent,target | tail -n +2 | while IFS= read -r line; do
  device=$(awk '{print $1}' <<< "$line")
  pct=$(awk '{print $2}' <<< "$line" | tr -d '%')
  mount=$(awk '{print $3}' <<< "$line")

  # Skip pseudo filesystems
  [[ "$device" == tmpfs* || "$device" == devtmpfs* ]] && continue

  if (( pct >= THRESHOLD )); then
    echo "WARNING: $device mounted at $mount is ${pct}% full" >&2
  else
    echo "OK: $device at $mount is ${pct}% used"
  fi
done

/etc/fstabを読み取り解析する

/etc/fstabは静的ファイルシステムテーブルです。起動時にどのデバイスを、どのパスへ、どのオプションでマウントするかを定義します。各行には6つのフィールドがあります。

  • Device — UUID=...、LABEL=...、または/dev/sdX
  • Mount point — ディレクトリパス
  • Filesystem type — ext4、xfs、nfs、tmpfsなど
  • Options — defaults、ro、noexec、nofailなど
  • Dump — 0または1(バックアップフラグ)
  • Pass — 0、1、または2(fsckの実行順序)

fstabのエントリを追加または検証するスクリプトでは、コメント(#で始まる行)や空行を適切に処理する必要があります。再起動時にデバイスの順序が変わっても問題が起きないよう、デバイス名よりUUIDを常に優先してください。

#!/usr/bin/env bash
# Parse /etc/fstab and display non-comment entries in a readable table
set -euo pipefail

FSTAB=/etc/fstab

printf '%-40s %-20s %-10s %s\n' 'DEVICE' 'MOUNTPOINT' 'FSTYPE' 'OPTIONS'
printf '%s\n' '-------------------------------------------------------------------------------------'

while IFS= read -r line; do
  # Skip blank lines and comments
  [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue

  read -r device mountpt fstype options _dump _pass <<< "$line"
  printf '%-40s %-20s %-10s %s\n' "$device" "$mountpt" "$fstype" "$options"
done < "$FSTAB"

fstabエントリを安全に追加する

/etc/fstabを手動で編集すると、ミスが起こりやすくなります。誤ったエントリがあると、システムが起動できなくなる可能性があります。安全な自動化スクリプトでは、次の点を実施する必要があります。

  • 追加する前にエントリがすでに存在するか確認する(冪等性)
  • 変更を加える前に元のファイルをバックアップする
  • デバイスパスではなくUUIDを使用する
  • マウントオプションにnofailを追加し、ディスクが見つからなくても起動を停止させない
  • 再起動する前に、mount -aをドライランまたはテストマウントとして実行し、検証する

エントリを書き込んだ後は、必ずfindmnt --verify(最新のsystemdディストリビューションで利用可能)で検証し、構文エラーをすぐに検出してください。

#!/usr/bin/env bash
# Safely append a new entry to /etc/fstab (idempotent)
set -euo pipefail

DEVICE_PATH='/dev/sdb1'
MOUNTPOINT='/mnt/data'
FSTYPE='ext4'
OPTIONS='defaults,nofail'
FSTAB='/etc/fstab'

# Resolve UUID for stable identification
UUID=$(sudo blkid -s UUID -o value "$DEVICE_PATH")
if [[ -z "$UUID" ]]; then
  echo "ERROR: Could not resolve UUID for $DEVICE_PATH" >&2
  exit 1
fi

ENTRY="UUID=$UUID  $MOUNTPOINT  $FSTYPE  $OPTIONS  0  2"

# Idempotency: skip if UUID already referenced in fstab
if grep -qsF "UUID=$UUID" "$FSTAB"; then
  echo "INFO: fstab already contains UUID=$UUID — skipping."
  exit 0
fi

# Backup
cp -p "$FSTAB" "${FSTAB}.bak.$(date +%Y%m%d%H%M%S)"

# Create mountpoint if needed
sudo mkdir -p "$MOUNTPOINT"

# Append entry
echo "$ENTRY" | sudo tee -a "$FSTAB" > /dev/null
echo "INFO: Added: $ENTRY"

# Validate
sudo findmnt --verify --verbose || echo 'WARNING: findmnt verify reported issues'

スクリプトでファイルシステムをマウントおよびアンマウントする

mountコマンドとumountコマンドは単純ですが、スクリプトではエッジケースに対処する必要があります。

  • デバイスがすでにマウントされている場合、再度マウントすると失敗します。findmntまたはmountpointで確認してください
  • マウントポイントが使用中(開いているファイルがある)の場合、umountは失敗します。lsof +D /mnt/targetで原因となっているプロセスを確認してください
  • アンマウントせずに読み取り専用へ切り替えるには、mount -o remount,ro /mnt/dataを使用します
  • 最後の手段としてumount -l /mnt/data(lazy)を使用できます。名前空間から切り離しますが、参照が閉じられるまで待機します

自動化では、必ずmountの終了コードを確認し、loggerを使って失敗をsyslogに記録してください。

#!/usr/bin/env bash
# Mount a device only if not already mounted; log outcome
set -euo pipefail

DEVICE='/dev/sdb1'
MOUNTPOINT='/mnt/data'

log() { logger -t disk-mount "$*"; echo "[$(date '+%F %T')] $*"; }

# Check if already mounted
if mountpoint -q "$MOUNTPOINT"; then
  log "INFO: $MOUNTPOINT is already mounted — nothing to do."
  exit 0
fi

# Ensure mountpoint directory exists
sudo mkdir -p "$MOUNTPOINT"

# Attempt mount
if sudo mount "$DEVICE" "$MOUNTPOINT"; then
  log "OK: Mounted $DEVICE at $MOUNTPOINT"
else
  log "ERROR: Failed to mount $DEVICE at $MOUNTPOINT"
  exit 1
fi

# Show what is now mounted there
df -h "$MOUNTPOINT"

LVM入門:Physical Volume、Volume Group、Logical Volume

LVM(Logical Volume Manager)は、未加工のブロックデバイスとファイルシステムの間に柔軟な抽象化レイヤーを追加します。3層構造は次のとおりです。

  • Physical Volume(PV) — pvcreateで初期化した未加工のディスクまたはパーティション
  • Volume Group(VG) — vgcreateで1つ以上のPVをまとめたプール
  • Logical Volume(LV) — lvcreateでVGから切り出した仮想パーティション。ここをフォーマットしてマウントします

主な利点は、アンマウントせずにLVをオンラインで拡張できることと、再フォーマットせずに新しいディスクをVGへ追加できることです。そのため、LVMは本番環境のストレージ自動化に不可欠です。

確認用コマンドには、pvs、vgs、lvsと、それぞれの詳細表示版であるpvdisplay、vgdisplay、lvdisplayがあります。

LVMボリュームの作成をスクリプトで自動化する

LVMセットアップの自動化は、厳密な順序pvcreate → vgcreate → lvcreate → mkfs → mountに従います。次のステップへ進む前に各ステップが成功している必要があるため、set -euo pipefailを使用し、各コマンドの出力を検証してください。

  • pvcreateを実行する前に、対象ディスクに既存のパーティションテーブルがないことを必ず確認します
  • 対話形式でないスクリプトでは、対話プロンプトを抑制するために-yフラグを使用します
  • 固定サイズには-Lを、残りの空き領域をすべて使うには-l 100%FREEを指定します
  • mkfsの後は、LVのデバイスパス/dev/<vgname>/<lvname>を使用します
#!/usr/bin/env bash
# Automate LVM setup: PV -> VG -> LV -> mkfs -> mount
set -euo pipefail

DISK='/dev/sdc'          # raw disk, no existing partitions
VG_NAME='vg_appdata'
LV_NAME='lv_appdata'
LV_SIZE='10G'
MOUNTPOINT='/mnt/appdata'
FSTYPE='xfs'

echo "[1/6] Initializing Physical Volume on $DISK"
sudo pvcreate -y "$DISK"

echo "[2/6] Creating Volume Group: $VG_NAME"
sudo vgcreate "$VG_NAME" "$DISK"

echo "[3/6] Creating Logical Volume: $LV_NAME (${LV_SIZE})"
sudo lvcreate -y -L "$LV_SIZE" -n "$LV_NAME" "$VG_NAME"

echo "[4/6] Formatting as $FSTYPE"
sudo mkfs."$FSTYPE" "/dev/$VG_NAME/$LV_NAME"

echo "[5/6] Mounting at $MOUNTPOINT"
sudo mkdir -p "$MOUNTPOINT"
sudo mount "/dev/$VG_NAME/$LV_NAME" "$MOUNTPOINT"

echo "[6/6] Done. Disk usage:"
df -h "$MOUNTPOINT"

# Show LVM summary
vgs && lvs

Logical Volumeをオンラインで拡張する

LVMの強力な機能の1つがオンラインリサイズです。これは、マウントして使用中の状態を保ったまま、論理ボリュームとそのファイルシステムを拡張する機能です。手順は次のとおりです。

  1. lvextendでLVを拡張します(-rフラグを指定すると、同じ手順でファイルシステムもリサイズされます)
  2. -rを使用しない場合は、ファイルシステムを別途リサイズします。ext4にはresize2fs、xfsにはxfs_growfsを使用します

重要な制約:

  • xfsは拡張のみ可能で、縮小はできません。容量を慎重に計画してください
  • ext4は縮小できますが、アンマウントした状態でのみ可能です
  • 拡張する前に、vgdisplay -sでVGに空き領域があることを必ず確認してください
#!/usr/bin/env bash
# Extend an LV and its xfs filesystem online
set -euo pipefail

VG_NAME='vg_appdata'
LV_NAME='lv_appdata'
EXTEND_BY='5G'
LV_DEV="/dev/$VG_NAME/$LV_NAME"

# Confirm VG has enough free space
FREE_GB=$(vgs --noheadings --units g -o vg_free "$VG_NAME" | tr -d ' g')
echo "VG free space: ${FREE_GB}G"
if (( $(echo "$FREE_GB < 5" | bc -l) )); then
  echo 'ERROR: Not enough free space in VG' >&2
  exit 1
fi

echo "Extending LV by $EXTEND_BY..."
sudo lvextend -L "+${EXTEND_BY}" "$LV_DEV"

echo 'Growing xfs filesystem online...'
sudo xfs_growfs "$LV_DEV"

echo 'New size:'
df -h "$LV_DEV"
lvs "$LV_DEV"

ファイルシステムの作成とフォーマット

パーティション分割またはLVMのセットアップ後は、ブロックデバイスをファイルシステムでフォーマットする必要があります。Linux管理でよく使われる選択肢は次のとおりです。

  • ext4 — 成熟したジャーナリングファイルシステムで、縮小をサポートします。多くのディストリビューションでデフォルトです(mkfs.ext4)
  • xfs — 高性能で、大きなファイルや並列I/Oに適しています。RHEL/CentOSのデフォルトです(mkfs.xfs)
  • btrfs — Copy-on-Write方式で、スナップショットを標準搭載しています(mkfs.btrfs)
  • tmpfs — RAM上に作成され、mkfsなしでfstabに指定します

意味のあるファイルシステムラベル(-Lフラグ)を必ず設定してください。これにより、UUIDの代替手段としてfstabでLABEL=を使ってデバイスを参照できます。

#!/usr/bin/env bash
# Format a partition and assign a label; print resulting UUID
set -euo pipefail

PARTITION='/dev/sdb1'
FSTYPE='ext4'
LABEL='appdata'

# Safety check: refuse to format a currently mounted device
if findmnt --source "$PARTITION" > /dev/null 2>&1; then
  echo "ERROR: $PARTITION is currently mounted. Unmount first." >&2
  exit 1
fi

echo "Formatting $PARTITION as $FSTYPE with label '$LABEL'..."
sudo mkfs."$FSTYPE" -L "$LABEL" -F "$PARTITION"

# Retrieve and display the new UUID
NEW_UUID=$(sudo blkid -s UUID -o value "$PARTITION")
echo "Formatted successfully."
echo "Label : $LABEL"
echo "UUID  : $NEW_UUID"
echo "Use this in fstab: UUID=$NEW_UUID  /mnt/$LABEL  $FSTYPE  defaults,nofail  0  2"

autofsでNFSマウントを自動化する

ネットワークファイルシステムでは、NFSサーバーに一時的に接続できない場合、fstabによる起動時のマウントが遅延したり失敗したりすることがあります。autofsは、必要になったときにマウントし、タイムアウト後にアンマウントすることで、この問題を解決します。

  • マスターマップ:/etc/auto.master — マウントポイントのディレクトリとそのマップファイルを定義します
  • ダイレクトマップ:/etc/auto.nfs — サブディレクトリごとのオプションとNFSサーバーのパスを指定します
  • 変更後はsystemctl reload autofsで再読み込みします
  • 設定したディレクトリにアクセスすると、マウントが自動的に表示されます

スクリプトでは、NFS共有の一覧からマップファイルを動的に生成し、autofsを再読み込みできます。これは、多数のホストに共有ストレージをプロビジョニングする場合に便利です。

#!/usr/bin/env bash
# Generate an autofs NFS map file from a share list and reload autofs
set -euo pipefail

NFS_SERVER='192.168.1.50'
AUTO_MAP='/etc/auto.nfs'
AUTO_MASTER='/etc/auto.master'
MOUNT_BASE='/nfs'

# Define shares: localname:remote_path
declare -A SHARES=(
  [homes]='/export/homes'
  [media]='/export/media'
  [backups]='/export/backups'
)

# Write map file
{
  echo '# Generated by disk-automation script'
  for localname in "${!SHARES[@]}"; do
    remote="${SHARES[$localname]}"
    echo "$localname  -rw,soft,timeo=30  ${NFS_SERVER}:${remote}"
  done
} | sudo tee "$AUTO_MAP" > /dev/null

echo "Wrote $AUTO_MAP"

# Ensure master map references this file
if ! grep -qF "$AUTO_MAP" "$AUTO_MASTER"; then
  echo "$MOUNT_BASE  $AUTO_MAP" | sudo tee -a "$AUTO_MASTER" > /dev/null
  echo "Updated $AUTO_MASTER"
fi

sudo systemctl reload autofs && echo 'autofs reloaded'

安全なバックアップのためのLVMスナップショット

LVMのスナップショットは、論理ボリュームの特定時点のコピーを提供します。これにより、マウントしたままのライブファイルシステムをアンマウントせずに、一貫性のあるバックアップを作成できます。スナップショットはCopy-on-Writeを使用して、作成時点の状態を取得します。

  • 作成:lvcreate -s -n lv_snap -L 2G /dev/vg_data/lv_data
  • バックアップのためにスナップショットを読み取り専用でマウントします:mount -o ro /dev/vg_data/lv_snap /mnt/snap
  • スナップショットのマウントポイントに対してrsyncまたはtarを実行します
  • バックアップ後にスナップショットを削除します:umount /mnt/snap && lvremove -f /dev/vg_data/lv_snap

スナップショットのサイズは元のLVの10~20%にしてください。スナップショットがいっぱいになると無効になるため、lvs -o lv_name,snap_percentで監視します。

#!/usr/bin/env bash
# Create an LVM snapshot, back up via tar, then remove snapshot
set -euo pipefail

VG='vg_appdata'
ORIGIN_LV='lv_appdata'
SNAP_LV='lv_appdata_snap'
SNAP_SIZE='2G'
SNAP_MOUNT='/mnt/snap_backup'
BACKUP_DEST='/var/backups/appdata'
DATESTAMP=$(date +%Y%m%d_%H%M%S)

trap 'sudo umount "$SNAP_MOUNT" 2>/dev/null; sudo lvremove -f "/dev/$VG/$SNAP_LV" 2>/dev/null' ERR EXIT

echo '[1] Creating snapshot...'
sudo lvcreate -s -n "$SNAP_LV" -L "$SNAP_SIZE" "/dev/$VG/$ORIGIN_LV"

echo '[2] Mounting snapshot read-only...'
sudo mkdir -p "$SNAP_MOUNT"
sudo mount -o ro "/dev/$VG/$SNAP_LV" "$SNAP_MOUNT"

echo '[3] Archiving to backup destination...'
sudo mkdir -p "$BACKUP_DEST"
sudo tar -czf "$BACKUP_DEST/appdata_${DATESTAMP}.tar.gz" -C "$SNAP_MOUNT" .

echo '[4] Cleaning up snapshot...'
sudo umount "$SNAP_MOUNT"
sudo lvremove -f "/dev/$VG/$SNAP_LV"

echo "Backup complete: $BACKUP_DEST/appdata_${DATESTAMP}.tar.gz"

理解度チェック:安全なfstabとマウントの自動化

このレッスンで学んだ、安全なディスク、ファイルシステム、マウントの自動化手法について理解度を確認しましょう。

レッスンのまとめ:ディスク、ファイルシステム、マウントの自動化

このレッスンでは、Linuxシステムで安全かつスクリプト化可能なディスクおよびストレージ管理を行うためのツールセットを構築しました。重要なポイントは次のとおりです。

  • まず調査する:lsblk、blkid、df、duで、変更前に必要な情報を取得します。
  • fstabの原則:常にUUIDを使用し、必ずnofailを含め、編集前に必ずバックアップし、findmnt --verifyで検証します。
  • マウントの安全性:マウント前にmountpoint -qで確認し、loggerで記録し、デバイスが使用中の場合のエラーにはlsofで対処します。
  • LVMの力:PV → VG → LVの流れにより、停止時間なしでオンライン拡張やスナップショットベースのバックアップが可能になります。
  • ファイルシステムの選択は重要:xfsは高性能ですが拡張のみ、ext4は柔軟でオフラインなら縮小可能、btrfsはスナップショットを標準で備えたワークロードに適しています。
  • NFSをオンデマンドで利用する:autofsは、ネットワーク共有をアクセス時のみマウントすることで、起動時の遅延を避けます。
  • スナップショットバックアップ:LVMスナップショットにより、一貫性のあるライブバックアップを作成できます。ただし、必ずsnap_percentを監視し、バックアップ後は速やかにスナップショットを削除してください。

これらのパターンを組み合わせることで、検出、プロビジョニング、マウント、リサイズ、バックアップというストレージのライフサイクル全体を確実に自動化できます。

よくある質問

「ディスク、ファイルシステム、マウントの自動化」レッスンは無料ですか?

はい。「ディスク、ファイルシステム、マウントの自動化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、DevOps Bootcampコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 DevOps Bootcampコースには全4レッスンが含まれています。

「ディスク、ファイルシステム、マウントの自動化」で何を学びますか?

ブロックデバイスを調査し、fstabエントリを管理して、LVMやマウント操作を安全にスクリプト化します。 ブラウザで直接実行するハンズオンコードでDevOps Bootcampを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

DevOps Bootcampを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのDevOps Bootcampは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「ディスク、ファイルシステム、マウントの自動化」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このDevOps Bootcampレッスンでコードを書いて実行できますか?

はい。すべてのDevOps Bootcampレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ユーザーとグループのプロビジョニング自動化
  2. systemdサービスの制御とユニットファイルの作成
  3. ディスク、ファイルシステム、マウントの自動化
  4. システムヘルスチェックとアラートスクリプトの構築
← DevOps Bootcampに戻る