AIでLinuxをインストールする: 4部構成シリーズ
第1部: ディストリビューションの選択 → 第2部: ストレージと暗号化 → 第3部: 手動インストール → 第4部: サービスとGPU
深夜3時にルートパーティションが満杯になり、システムが停止するのを目の当たりにしたことがあるなら、もう分かっているはずだ。デフォルトのパーティション設定は罠だと。しかし、6つの異なるワークロードを3台の物理ディスクに分散させた、適切な暗号化LVMレイアウトを設計するとなると、それは丸一日かかる作業だ。ドキュメントを参照し、サイズを計算し、ひとりで悩み続けることになる。
ここでは、AIにストレージ設計の重労働を任せる方法を紹介する。manページに一日中埋もれることなく、ワークロードの要件を入力すれば、根拠のある完全なアーキテクチャが返ってくる。構築するすべての層を理解した状態で作業を進められる。
第1部では、ディストリビューションを選択してハードウェアをマッピングした。次は、多くの人がデフォルト設定を受け入れるか、完全に諦めてしまう部分だ。ストレージ設計である。
パーティションサイズではなく、ワークロードから始める
第1部でハードウェアをマッピングした。たとえば、NVMeドライブ、SSD、HDDを搭載した古めのThinkPadだ。スペックは何が可能かを教えてくれる。しかし、ワークロードが何が必要かを教えてくれる。
やり方はこうだ。AIにパーティションテーブルを求めてはいけない。サイズを指定してもいけない。「/homeを独立したパーティションに」などと言ってもいけない。代わりに、動作と要件を説明し、アーキテクチャを導き出させる。たとえば次のように:
「このマシンはDockerコンテナ、TimescaleDB付きのPostgreSQL、Redis、ローカルAIモデル用のOllamaを実行し、ハニーポットネットワークからの攻撃アーティファクトを保存します。また、OSとは分離した暗号化された解析ワークスペースと、長期的な証拠保管のための暗号化アーカイブストレージが必要です。見つかった3台のディスクに最適なパーティションと暗号化戦略を設計してください。」
違いが分かるだろうか。制約と目標を渡しているのであって、解決策を細かく指示しているわけではない。返ってきた根拠が妥当であれば、設計も妥当なものになる。そして、ある選択が意味をなさなければ、マシンが実際に何をする必要があるかを理解しているので、それに気づくことができる。
ディスクの動作でワークロードを分類する
最初に整理すべきは、IOパターンによるワークロードの分離だ。サイズや重要度ではなく、各ワークロードが実際にどのようにディスクにアクセスするかによって分類する。
3つのレーン
- 高IOPS、低レイテンシ = NVMe。OS、Docker、データベース、AIモデルはここに置く。これらのワークロードは小さなランダムな読み書きを大量に行う。利用可能な最速のストレージが必要だ。
- 高速なスクラッチスペース、独立性 = SSD。解析ワークスペースはここに置く。キャプチャの処理やツールの実行にはそれなりの速度が必要だが、それ以上に重要なのは、OSディスクから分離されていることだ。解析作業でファイルシステムが破損したりディスクが満杯になっても、OSは動き続ける。
- 大容量、シーケンシャル書き込み = HDD。pcap、証拠のエクスポート、バックアップの長期アーカイブストレージ。シーケンシャル書き込み性能で十分だ。速度よりも容量が重要になる。
この分離だけで、最も一般的な障害モードを防ぐことができる。あるワークロードが別のワークロードのディスクIOやスペースを奪ってしまう問題だ。
すべてのサービスが独自の論理ボリュームを持つ理由
3台のディスクで止まってはいけない。NVMe上では、スペースを特定の目的ごとに6つの独立した論理ボリュームに分割する:
- /var/lib/docker は分離する。Dockerはディスクを予測不能な形で消費するからだ。暴走したコンテナのビルドや忘れられたイメージキャッシュがルートを埋め尽くしてはいけない。
- /var/lib/postgresql は分離する。独立したサイズ調整、バックアップスナップショット、将来のパフォーマンスチューニングのためだ。データベースには専用スペースの恩恵を受けるユニークなIOパターンがある。
- /var/lib/ollama は分離する。AIモデルは巨大で、独立して成長するからだ。単一のLLMは8GB以上になることもある。モデルのダウンロードがOSのスペースと競合してほしくない。
- /home は分離する。ユーザーデータ、dotファイル、個人設定がOSの再構築後も残るようにするためだ。
- swap は独自の論理ボリュームとして、必要に応じてハイバネーションをサポートするサイズにする。
- root (/) は固定サイズに制限する。指定されたパス以外のものがそれを埋め尽くせないようにするためだ。ルートが満杯になるとシステムは機能しなくなる。制限することは防御的な設計だ。
暗号化は任意ではない
ここでは暗号化は任意ではなく、その理由は明快だ。これはラップトップ形式で動作するセキュリティワークステーションであり、機密データを保存している。ハニーポットのキャプチャ、攻撃アーティファクト、ネットワーク解析結果などだ。マシンが盗まれたり、紛失したり、廃棄されたりした場合、すべてのディスクはパスフレーズなしでは読み取れない状態でなければならない。
このユースケースでは、LUKSによるフルディスク暗号化がベースラインだ。以上。
ボリュームグループに余裕を残す
この細部が、優れたLVM設計と素人の設計を分ける。ボリュームグループの約5〜10%を未割り当てのままにしておく。無駄にするのではなく、予約しておくのだ。理由はこうだ:
LVMを使えば、再起動なしにオンザフライで論理ボリュームを拡張できる。6ヶ月後にDockerがより多くのスペースを必要とするなら、LVを拡張してファイルシステムを数秒でリサイズできる。すべてを最初に割り当ててしまうと、一方のボリュームを縮小して他方を拡張する必要が生じる。縮小は遅く、リスクがあり、特定のファイルシステムでは不可能な場合もある。
意図的な余裕は無駄ではなく、機能だ。
ストレージ層のメンタルモデル
このメンタルモデルは、この章全体から持ち帰るべき最も価値あるものだ。パーティションサイズでも、マウントポイントでもない。Linuxのストレージが実際にどのように機能するかを上から下まで説明する、この8層スタックだ。
8層ストレージスタック
ストレージのすべてのデータは、上から下へこれらの層を通過する:
- 生パーティション:
fdiskやgdiskが物理ディスク上に作成するもの - 暗号化 (LUKS): 生パーティションを暗号化されたコンテナでラップする
- マッパーデバイス: アンロック後に現れるもの:
/dev/mapper/cryptnvme - LVM物理ボリューム (PV): LVMのストレージとして登録されたマッパーデバイス
- ボリュームグループ (VG): 1つ以上のPVをプールにまとめたもの
- 論理ボリューム (LV): 特定の目的のためにサイ���設定されたVGのスライス
- ファイルシステム: LV上にフォーマットされたext4またはswap
- マウントポイント: ファイルシステムがディレクトリツリーに現れる場所
何かが壊れたとき、修正はほぼ常に特定の1つの層で行われる。どの層かを特定できなければ、間違った箇所のトラブルシューティングに何時間も費やすことになる。
実際のインストール中に遭遇するほとんどの障害、特に第3部のfstabとcrypttabに関するものは、これらの層を混同することから生じる。層6が期待される場所に層2のUUIDを書いてしまう。層1が必要な設定に層3のデバイスパスを参照してしまう。すべてのストレージエラーは層の不一致に起因する。
このスタックをブックマークしておこう。前腕にタトゥーを入れてもいい。この8つの層を内面化すれば、Linuxのストレージは謎ではなくなる。それぞれが1つの仕事をこなす8つのものが、順番につながっているだけだ。
NVMeの最終レイアウト
プライマリNVMeドライブの完全な設計を示す:
プライマリNVMe (nvme0n1)
| パーティション | サイズ | タイプ | 目的 |
|---|---|---|---|
| nvme0n1p1 | 1 GB | EFIシステム (FAT32) | ブートファームウェア |
| nvme0n1p2 | 2 GB | /boot (ext4) | カーネルとinitramfs |
| nvme0n1p3 | 残り全部 | LUKS2暗号化 | その他すべて |
nvme0n1p3のLUKSコンテナ内:
nvme0n1p3 → cryptnvme (LUKS2) → LVM PV → vgkali (ボリュームグループ)
| 論理ボリューム | サイズ | ファイルシステム | マウントポイント |
|---|---|---|---|
| root | 120 GB | ext4 | / |
| swap | 24 GB | swap | [swap] |
| docker | 220 GB | ext4 | /var/lib/docker |
| ollama | 180 GB | ext4 | /var/lib/ollama |
| postgres | 120 GB | ext4 | /var/lib/postgresql |
| home | 200 GB | ext4 | /home |
| (空き) | 約65 GB | なし | なし |
セカンダリディスク
SSD (sdb): sdb1 → cryptanalysis (LUKS2) → ext4 → /srv/analysis
HDD (sda): sda1 → cryptarchive (LUKS2) → ext4 → /srv/archive
3台の暗号化ディスク。プライマリに6つの論理ボリューム。各ワークロードが独自のレーンに。何も共有すべきでないものとスペースを共有しない。
デザインをビルドスクリプトに変換する
設計が確定したら、次のプロンプトはシンプルだ:
「このストレージレイアウト全体を、ライブKali環境から構築するための正確なコマンドを教えてください。3つのディスクはすべて消去可能とします。」
完全なシェルスクリプトを要求しよう。既存のシグネチャの消去、GPTパーティションテーブルの作成、sgdiskによるパーティションの切り出し、強力なデフォルト設定でのLUKS2コンテナの作成、コンテナのオープン、LVM物理ボリュームの初期化、ボリュームグループの作成、6つの論理ボリュームすべての割り当て、フォーマット、そしてSSDとHDDへのLUKSセットアップの繰り返しまでを含む内容だ。
おおよそ80行程度になるはずだ。すべてのコマンドは監査可能でなければならない。スクリプトの中で意味が分からない部分があれば、実行する前にAIにその行を説明させること。
うまくいかないこと(設計の問題ではない)
正直に言っておこう。設計は堅牢だ。問題が起きるのは実行の段階だ。注意すべき落とし穴を挙げる:
Windowsの改行コード。 Windowsマシンでスクリプトを書いてUSB経由でライブ環境に転送すると、各行の末尾が\nではなく\r\nになる。Bashはすべてのコマンドで詰まり、エラーメッセージも意味不明だ。実行前にsed -i 's/\r$//' script.shで修正すること。
シバン行の破損。 改行コードの問題と関連している。#!/bin/bashの行に不可視のキャリッジリターンが付くため、カーネルがインタープリタを見つけられない。スクリプトが明らかに存在しているのに、存在しないかのようなエラーが出る。
パスの混乱。 USBはあるパスにマウントされているが、別の作業ディレクトリからスクリプトを参照している。ライブ環境では複数のマウントポイントを扱うため、タブ補完や相対パスは信頼できない。絶対パスを使うこと。
実行構文の誤り。 スクリプト名の前に./を忘れる、または実行権限を先に設定しないといったミスだ。ストレージ設計とは無関係な、筋肉記憶の問題だ。
「AIはスクリプトを書けるが、貼り付けた内容を理解するのはあなた自身だ。意味が分からないコマンドがあれば、立ち止まって質問すること。」
改行コードと実行の問題が解決すれば、ストレージ���構築は2分以内に完了する。すべてのLUKSコンテナが開く。すべてのLVM構造がきれいに作成される。すべてのファイルシステムがフォーマットされる。設計は機能する。
貼り付けて確認するパターンですべてを検証する
成功を前提にしてはいけない。スクリプトが完了したら、ターミナルの出力をAIに貼り付けて結果を監査させよう:
「
lsblkとlvsの出力です。すべて正しく構築されましたか?」
生のターミナル出力を貼り付け、AIに一行ずつ確認させる。確認すべき内容は:cryptnvmeがアクティブであること、vgkaliが正しいサイズの6つの論理ボリュームとともに存在すること、各ボリュームに正しいファイルシステムが設定されていること、セカンダリディスクが暗号化されフォーマットされていること。
この貼り付けて検証するパターンは、AIを使ったシステム管理において最も有用なテクニックの一つだ。コマンドを実行し、出力を貼り付け、現実が計画と一致しているか確認する。作業に近すぎて見落としがちな問題を発見できる:
- 論理ボリュームが誤ったファイルシステムタイプでフォーマットされている
- ギガバイトのつもりがメガバイト単位でサイズが設定されている
- スクリプトが静かにスキップしたパーティションが欠けている
- 実際には開いていないLUKSコンテナ
これはほぼあらゆるシステム状態で使える:lsblk、lvs、pvs、vgs、blkid、fdisk -l、cryptsetup status。貼り付けて、AIに監査させる。自分ですべてを確認するより速く、より徹底的だ。
まとめ:デフォルトではなくワークロードから設計する
ここで紹介したストレージレイアウトは、テンプレートから選んだものでも、フォーラムの投稿からコピーしたものでもない。実際のワークロード要件から導き出したものだ。Dockerにはスペースの分離が必要だ。データベースには専用のIOが必要だ。AIモデルには成長できる余地が必要だ。セキュリティアーティファクトには保存時の暗号化が必要だ。アーカイブには速度よりも容量が必要だ。
すべての決定は実際の要件に基づいている。それが、6ヶ月後も機能するストレージレイアウトと、予期しない事態が起きた途端に崩壊するレイアウトの違いだ。
このアプローチはセキュリティワークステーションに限らず、あらゆる構築に使える。AIにそのマシンが何をするかを伝えよう。サービス、データパターン、成長の見込み、乗り越えたい障害シナリオを説明する。そしてディスクの整理方法はAIに考えさせる。AIが示す推論は最終的なパーティションテーブルよりも価値がある。各選択がなぜ行われたのか、そしていつ変更が必要になるかを理解できるからだ。
ディスクはパーティション分割され、暗号化され、論理ボリュームに切り出された。アーキテクチャは完成した。次は実際に人々を苦しめる部分だ:グラフィカルインストーラーの助けなしに、この上にOSをインストールすること。
**パート3:手動インストール**では、暗号化ボリュームをマウントし、Kaliをゼロからブートストラップし、起動時にすべてがアンロックされるようfstabとcrypttabを設定し、動作するブートローダー設定を構築する。ここで8層モデルが本当の意味でストレステストされ、UUIDを一つ間違えるだけでGRUBレスキュープロンプトを見つめることになる。コーヒー���用意しておこう。