運用しやすさを考えてLXDコンテナでまとめる

Dockerで複数サービスを運用すると管理が煩雑になるため、LXDコンテナ上でDockerを動かして「軽量VM」的に管理する選択肢があります。ここでは「LXD内でDockerを動かす」場合と「ベアメタルでDockerを動かす」場合の比較、ストレージ選定、運用上の注意点、そしてLXD上での実際のストレージ準備・マウント手順を整理して記します。

LXD内Docker vs ベアメタルDocker

まずは、LXD内でDockerを動かす場合と、マシン上で直接Dockerを動かす場合について。

パフォーマンス

  • CPU / メモリ:ほぼ同等(通常差は1〜5%)。LXDはホストカーネルを共有するためオーバーヘッドは小さい。
  • ディスクI/O:影響を受けやすく、構成次第で5〜20%低下することがある。特に ZFS + overlay2 の組合せは遅くなる場合あり。bind mount や btrfs プールで改善可能。
  • ネットワーク:ブリッジやNAT経由だと数%〜10%程度の遅延/スループット低下。–net=host 相当や macvlan で回避可能。
  • 実測目安:軽負荷で 1〜3% 差、I/O/ネットワーク重視なら 5〜15%(最悪 20% 前後)。最高性能が必須ならベアメタル推奨。

管理性

  • ベアメタル(メリット):最大性能、構成がシンプル、トラブルシュートが直感的。
    デメリット:ホストが「汚れる」、複数環境の分離が面倒、ホスト障害で全サービスに影響。
  • LXD内Docker(メリット):強い隔離(スナップショット・バックアップ・マイグレーションが容易)、リソース制限・複製が簡単、ホストをクリーンに保てる。
    デメリット:設定項目が増える(例:security.nesting 等)、ストレージ相性問題、二層デバッグ、AppArmor/SELinux の落とし穴。

ディスク容量目安

Ubuntu 24.04 ベース・LXDコンテナ1つあたりの例です。

  • Dockerインストールのみ(最小):1.2〜2.5 GB(目安:約1.5 GB)
  • 軽いテストイメージを数個:2〜4 GB
  • 実運用開始後:プロジェクトごとに 5〜20+ GB が普通
  • 複数コンテナ(例:3つ)のクリーンスタート:合計 5〜8 GB
  • 容量節約策:minimal イメージ、docker system prune、ボリュームをホストに bind mount、LXD の quota 設定

選択の目安

  • ベアメタル推奨:最高性能が必要、環境が少数でシンプル、ホストを専用化できる場合。
  • LXD内Docker推奨:複数の独立環境を運用したい、スナップショットや移行を多用する、ホストを汚したくない、小〜中規模運用。

容量に心配がなければ、LXD内で運用するほうがシンプルになりそうです。
なお、LXDで運用するにしても、ストレージに何を使用するかは注意が必要そうです。


ストレージバックエンドの違い

LXDのストレージドライバで容量効率がかなり変わります。特にDockerネスト時はここがネックになります。

  • btrfs(推奨、Dockerとの相性良好)
    • Copy-on-Write が効き、overlay2 と相性が良い。初期オーバーヘッドが小さく実使用量に近い。
    • 推奨運用:LXDで別プールを作り Docker 用コンテナを配置する(例: lxc storage create dockerpool btrfs source=/mnt/…)。
  • ZFS(LXDデフォルト)
    • 安定性・堅牢性が高いが、overlay2 との相性で非効率になることがある。スナップショットやコピーで容量増になる報告あり。Docker 側の storage driver を zfs にする運用も検討可。
  • dir(シンプルだが非推奨)
    • スナップショットが遅く、容量効率も悪いためテスト用途向け。

ZFS と Btrfs の使い分け

簡単に言えば、それぞれ次のようになりそうですね。個人用途であれば、即時スナップショット、コンテナ別クォータ、透過圧縮などの高度機能が使えるなど、Btrfsのメリットが多そうです。ただ、Btrfsを利用する場合も、注意が必要そうです。

  • Btrfs が向く場面:単一SSDノート/小型サーバー、既存 EXT4 環境への導入、容量のオンライン拡張/縮小、軽量運用、Docker と LXD を同一FSで扱いたい場合。
  • ZFS が向く場面:高信頼性優先の本番、RAID5/6 を使う大容量運用、高い IOPS 安定性が必要な場合。
  • 注意:Btrfs は RAID5/6 の安定性や CoW による断片化に注意。可能ならホスト上の実パーティションで運用する。

ループバックファイル vs 専用パーティション

  • ループバック(利点):追加ディスク不要、手早く導入・削除可能 → テスト向け。
    欠点:ホストFS越しのI/Oで性能低下、断片化、サイズ縮小が難しい。
  • 専用パーティション(利点):性能・信頼性が高い → 本番向け。
  • 推奨:本番/長期運用や高負荷なら専用パーティション。短期テストやディスクが無い場合はループバック可。

LXDでbtrfsを使う場合の注意点

  • ホストが btrfs でない場合、ループバックでの運用になり性能低下する可能性がある。
  • 既存プールの source(デバイス)は UI から後で変更できないなどの制約がある。
  • Dockerネスト時は overlay2 等のストレージドライバとの相性を事前に確認する。

ファイルシステムを何にするにしても、専用パーティションにしたほうが良さそうですね。


実践:専用Btrfsパーティションを作成してLXDに登録する手順

注意:ルートパーティションの縮小をライブで行う場合はライブUSBから作業してください。以降のコマンドは例であり、環境に応じてデバイス名やパスを置き換えてください。

1) パーティション操作(例: gparted)

  • 既存パーティションを縮小して空き領域を作る。
  • 空き領域に新規パーティションを作成、ファイルシステムは btrfs、ラベル例: lxd-btrfs。
  • 変更を適用。

2) マウントポイントを作成

自動マウントではなく、システム起動時に必ず同じ場所にマウントされるようにします。ここではnvme0n1p3デバイスの例。

# マウントポイントを作成
sudo mkdir -p /mnt/lxd-storage

# いったんアンマウントして、固定場所にマウントし直す
sudo umount /run/media/user/btrfs
sudo mount /dev/nvme0n1p3 /mnt/lxd-storage

3) サブボリューム作成(btrfs-progs が必要)

LXDコンテナ内にマウントするポイントとして、単なるフォルダ(mkdir)ではなく、Btrfsの機能(スナップショット等)を個別に使える「サブボリューム」として作成します。まず、btrfs-progsをインストールします。

sudo apt update
sudo apt install -y btrfs-progs

# LXDのプール用(コンテナのOS等)
sudo btrfs subvolume create /mnt/lxd-storage/lxd-pool

# LXD内Dockerなどのデータ用(ホストからも見える場所)
sudo btrfs subvolume create /mnt/lxd-storage/lxd-data

4) LXDへデフォルトプールとして登録

LXDのストレージプールとして、作成したサブボリュームを指定します。

デフォルトプールに指定しておけば、今後も自動でこのプールが使われるので良いでしょう。

5) データ用ディレクトリもマウント

データ用ディレクトリも追加します。こちらもデフォルトプロファイルに登録しておくと、今後コンテナを作成するたびに作業しなくて済むので楽です。
「Mount host path」を選択し、それぞれ次のように指定します。

/mnt/lxd-storage/lxd-data
/opt/lxd-data

コンテナ(インスタンス)を作成します。作成したBtrfsが利用されているのを確認しましょう。
コンテナが起動したら、マウントするディレクトリを作成します。

ちなみに、Dockerを利用するならNestingをAllowにします。

6) コンテナを作成して起動

コンテナを作成して起動します。コンテナが起動したら、コンソールで作業しても良いですが、コンテナ内に入って作業するほうが楽でしょう。

 lxc exec コンテナ名 -- bash

マウントしてディレクトリが見えているか確認してみましょう。

cd /opt
ls

ただ、現時点ではlxd-data内へ書き込みしようとするとエラーになります。

7) パーミッションと ID マッピング

コンテナ内のDocker(root)が書き込めるように、ホスト側のディレクトリの所有権を設定します。

これにはいくつか方法がありますが、手軽で安全なのは、コンテナの設定でIDマッピングを許可することです。通常、非特権 LXD コンテナでは、

  • コンテナ内 uid=0(root) → ホスト uid=100000
  • コンテナ内 uid=1000 → ホスト uid=101000

というように 10 万番台へ変換されて動きます。
このため、ホストの /opt/lxd-data の owner を 1000:1000 にしても、
コンテナ内のユーザー(uid=1000) は 101000 として扱われるので書き込みエラーが発生します。

書き込みを許可するには raw.idmap を使ってホストとコンテナの UID/GID を直接対応させます。

例(コンテナ内 uid=1000 をホストの uid=1000 にマップ)

lxc config set <コンテナ名> raw.idmap "both 1000 1000"
lxc restart <コンテナ名>
sudo chown 1000:1000 /mnt/lxd-storage/lxd-data

「both 1000 1000」は、コンテナ→ホスト、ホスト→コンテナの両方向で UID/GID 1000 を対応させるという意味で、これによりコンテナ内からもエラーなく書き込めるはずです。


タイトルとURLをコピーしました