はじめに
KubeVirtはQEMUをPod内で実行するが、だからといって制約なくホストリソースにアクセスさせるわけではない。むしろKubeVirtを深く読むと、コントローラよりもセキュリティ境界のほうが複雑なコードが多い。`/dev/kvm`、TAP、VFIO、マイグレーションソケット、マウントnamespaceのようなセンシティブなパスを扱う必要があるからである。
本記事ではKubeVirtがどのようにセキュリティ境界を設けているかを見る。核心は三つである。
- SELinuxコンテキストを合わせる。
- seccompでsyscall許可範囲を管理する。
- cgroupとデバイスプラグインレイヤーでデバイスアクセスを絞る。
1. なぜKubeVirtのセキュリティモデルはより厳しいのか
通常のPodはネットワークとストレージを使う程度で十分な場合が多い。一方KubeVirtは次をやる必要がある。
- ハードウェア仮想化デバイスにアクセスする。
- TAPデバイスを作る。
- マイグレーション時にノード間でメモリとデバイス状態を移す。
- ゲストディスク、cloud-init、ソケット、QEMUプロセスを一緒に管理する。
つまりVM一つを立ち上げるとはホストカーネル機能に深く触れるということである。そのためKubeVirtは単に「privileged Pod一つ」で済ませず、セキュリティ境界を複数の層に分割する。
2. SELinux:同じPodでも正しいラベルが合わなければならない
KubeVirtがSELinuxを重視していることはAPI型だけ見ても明らかである。`VirtualMachineInstanceStatus`と`MigrationState`には実際の`selinuxContext`が記録される。これはSELinuxが単なる環境情報ではなく、マイグレーションとホスト側ヘルパーが再現しなければならない実行条件であることを意味する。
`pkg/virt-controller/watch/migration/migration.go`を見ると、ターゲットマイグレーションPodを作る際にソース側のSELinuxコンテキストを読み取ってターゲットPodに適用できる。デフォルト動作はソースと同じレベルを合わせる方向である。この設計は「ターゲットPodも同じファイルとソケットにアクセス可能でなければならない」という運用現実を反映している。
特にRWXボリュームや共有状態が絡むと、SELinuxレベルの不一致は単なる警告ではなくマイグレーション失敗原因になる。
3. SELinuxはネットワークヘルパー実行にも影響する
SELinuxがマイグレーションPodにのみ使われるわけではない。`pkg/network/driver/virtchroot/tap.go`を見ると、TAPデバイス作成時に`AddTapDeviceWithSELinuxLabel`パスがある。ここではlauncher PIDのSELinuxラベルを基準にヘルパーコマンドを実行する。
この動作の実際の核心は`pkg/virt-handler/selinux/context_executor.go`にある。
- 対象PIDの現在のラベルを読む。
- 現在のプロセスの元のラベルも保管する。
- ヘルパー実行直前にdesiredラベルに切り替える。
- 実行が終わったら元のラベルに戻す。
つまりKubeVirtは「ホストヘルパーが代わりに作業する」で止まらない。**そのヘルパーがどのSELinux文脈で実行されるべきかまで復元**する。
これが重要な理由は単純である。TAP作成やnamespace内部作業が成功するには、単純なroot権限だけでは不十分で、正しいラベル文脈が合う必要がある場合があるからである。
4. seccomp:syscallもそのまま全開にしない
`pkg/virt-handler/seccomp/seccomp.go`はkubeletルート配下にKubeVirt用seccompプロファイルをインストールする。インストール場所を見るとホストのkubelet管理ディレクトリ配下に`seccomp/kubevirt/kubevirt.json`を作る。
ここで特に目を引くsyscallが`userfaultfd`である。ベースプロファイルをベースにしつつ、KubeVirtはこのsyscallを明示的に許可している。コメントにも理由が書かれている。post-copyマイグレーションに必要だからである。
このポイントは重要である。
- 普段はsyscallを可能な限りベースプロファイルに合わせる。
- しかしライブマイグレーションの特定段階には追加syscallがどうしても必要。
- そのためKubeVirtは「機能のためにセキュリティを放棄」するのではなく、必要なsyscallだけを精密に開ける。
つまりseccompはKubeVirtにおいて単なるコンプライアンス設定ではなく、**ライブマイグレーション機能要件とセキュリティ要件を同時に満たす調整レイヤー**である。
5. cgroupデバイスアクセス:QEMUがデバイスを使える範囲を制限する
VM実行がQEMUプロセスであるという事実はセキュリティ面でも重要である。結局デバイスアクセス制御はプロセス基準で行う必要がある。
`pkg/virt-handler/vm.go`を見るとKubeVirtはデバイスコントローラとcgroupマネージャーを一緒に扱う。また`cmd/virt-chroot/cgroup.go`はホストcgroupパスに入ってruncのcgroupマネージャーを通じて実際のリソースを設定する。v1とv2の両方をサポートしているのも目を引く。
このレイヤーがやることは大体次の通り。
- VMに必要なデバイスだけ許可リストに反映する。
- cgroup v1、v2の違いに合わせて実際のカーネル制約をかける。
- CPUとメモリだけでなくデバイスアクセスルールまでホスト側に反映する。
つまりKubeVirtはPod specのリソースリクエストだけを信頼せず、**実際のVMプロセスがホストで出会うcgroup境界を別途調整**する。
6. デバイスプラグインとpermanent host device
`pkg/virt-handler/vm.go`の初期化コードを見ると、KubeVirtはハイパーバイザーデバイスに対してpermanent host device pluginの概念を置いている。`/dev/kvm`のようなデバイスをノードレベルで管理可能なリソースとして扱うための構造である。
この構造のおかげでKubeVirtは単にprivilegedコンテナがホストデバイスを直接探す方式ではなく:
- ノードにどのデバイスがあるか公開し
- スケジューラがそのリソースを考慮するようにし
- 実際のlauncherが該当デバイスを使うよう接続する
という流れを作れる。
この観点から見るとデバイスプラグインはパフォーマンス機能ではなくセキュリティ機能でもある。どのVMがどのホストデバイスを受け取るかを明示的に管理できるからである。
7. VFIOとホストデバイスパススルーがなぜセンシティブか
SR-IOVとPCIホストデバイスパススルーは`virtwrap/device/hostdevice`系とVFIOモデルを通じてゲストにデバイスを渡す。このとき通常の仮想NICよりはるかに強いホスト依存性が生じる。
そのためこのような設定はマイグレーション可能性にも直接影響する。API型にはそもそも`HostDeviceNotLiveMigratable`、`SEVNotLiveMigratable`、`SecureExecutionNotLiveMigratable`のようなreasonが定義されている。
これはKubeVirtがセキュリティまたはハードウェア特殊機能を有効にした瞬間、その代償として一部の柔軟性を放棄すべきことをAPIレベルで示しているということである。
8. privileged helperがあっても「制限付きprivileged」を目指す
KubeVirtコードを見ると`virt-handler`、`virt-launcher`、`virt-chroot`が役割を分担している。
- クラスタ側の宣言と調整はcontrollerが担当。
- node-localのprivileged作業は`virt-handler`とヘルパーが担当。
- 実際のVM実行は`virt-launcher`とlibvirt、QEMUが担当。
つまりすべての作業を一つのコンテナが行う構造ではない。役割を分離し、必要な瞬間にのみhost-levelヘルパーを呼び出す。
この設計は完璧な最小権限ではないにせよ、**権限を機能境界に合わせて分散する方向**である。
9. ライブマイグレーションとセキュリティ境界はつながっている
多くのユーザーがライブマイグレーションをパフォーマンスと可用性機能としてのみ見る。しかし実際にはセキュリティ文脈の再現問題でもある。
- ターゲットPodがソースと同じSELinuxレベルを持てるか
- post-copyに必要なsyscallが許可されているか
- マイグレーションソケットとstateファイルにアクセス可能か
- デバイスとボリュームがターゲットでも同じように準備されているか
これらの一つでもずれればマイグレーションは壊れる。つまりKubeVirtにおいてセキュリティ設定は付加機能ではなくマイグレーションの前提条件である。
運用者が覚えるべき要点
- `/dev/kvm`アクセスができるだけでVMプラットフォームが完成するわけではない。
- SELinuxコンテキストはマイグレーション成功の可否と直結する。
- seccompはpost-copyのような高度な機能と衝突しうるためプロファイルレベルで理解する必要がある。
- cgroupデバイスルールとデバイスプラグインはセキュリティとスケジューリングを同時に扱う。
まとめ
KubeVirtはPod内でQEMUを実行するが、その内部は全く単純ではない。SELinuxはヘルパーとマイグレーションターゲットの実行文脈を合わせ、seccompは必要なsyscallだけを許可し、cgroupとデバイスプラグインはデバイスアクセス範囲を管理する。結局KubeVirtのセキュリティモデルは「VMも結局Linuxプロセス」という事実を正面から受け止め、そのプロセスがカーネルと出会う地点を精密に調整する方式である。
次の記事では、このような内部状態が運用者にどう見えるか、つまりVMI status、ゲストエージェント、domain stats、メトリクス、デバッグパスをたどっていく。
현재 단락 (1/64)
KubeVirtはQEMUをPod内で実行するが、だからといって制約なくホストリソースにアクセスさせるわけではない。むしろKubeVirtを深く読むと、コントローラよりもセキュリティ境界のほうが複雑な...