手当たり次第に書くんだ

飽きっぽいのは本能

Kubernetes を前提とした仮想化アーキテクチャ – VM とコンテナをどう重ねるか

Kubernetes が一般化したことで、インフラ設計では「仮想マシンを使うのか、コンテナを使うのか」という話になりがちです。

しかし、実際の基盤設計では、VM と Kubernetes は単純な競合関係ではありません。むしろ多くの環境では、物理サーバー、仮想化基盤、仮想マシン、Kubernetes、コンテナ、アプリケーションが階層として重なります。

重要なのは、どちらを選ぶかではなく、どの層にどの責務を持たせるかです。

仮想化は抽象化である

仮想化とは、単に仮想マシンを動かすことではありません。複雑な物理構造や運用対象を、扱いやすい単位に置き換える抽象化です。

VLAN は物理ネットワークを論理的に分けます。LVM は物理ディスクを論理ボリュームとして扱います。KVM は物理サーバーを複数の仮想マシンに分けます。Kubernetes は複数ノード上のコンテナを、宣言的なリソースとして扱います。

つまり、現代のインフラは抽象化の積み重ねです。抽象化が増えるほど柔軟になりますが、同時に、どの層で何が起きているのかを見失いやすくなります。

VM と Kubernetes は役割が違う

仮想マシンは、OS 単位の分離を作る技術です。カーネル、ネットワーク設定、ディスク、セキュリティ境界、障害範囲を VM 単位で分けられます。

Kubernetes は、アプリケーションの配置、再起動、スケール、Service、ConfigMap、Secret、Ingress、Pod 間通信などを扱うための基盤です。つまり、OS より上のアプリケーション運用を標準化する層です。

このため、VM と Kubernetes は同じ問題を解いているわけではありません。VM はノードや境界を作り、Kubernetes はその上でアプリケーションを運用する、と考える方が自然です。

層ごとに責務を分ける

Kubernetes を前提にした仮想化アーキテクチャでは、責務を層ごとに分けて考える必要があります。

主な責務
物理レイヤ電源、筐体、CPU、メモリ、ディスク、NIC、配線、冷却を扱う。
仮想化レイヤKVM、VMware、OpenStack などで VM の配置、リソース、仮想ネットワークを扱う。
OS レイヤ各ノードのカーネル、パッケージ、時刻同期、名前解決、証明書、ログを扱う。
Kubernetes レイヤPod、Service、Ingress、CNI、CSI、Secret、Deployment などを扱う。
アプリケーションレイヤ実際のサービス、データ、設定、リリース、監視観点を扱う。

この分離が曖昧になると、Kubernetes で解くべきではない問題を Kubernetes に押し込んだり、VM 側で解くべき問題をアプリケーション側に漏らしたりします。

Kubernetes ノードを VM にする意味

Kubernetes ノードを物理サーバーに直接構築することもできます。しかし、VM 上に Kubernetes ノードを作る構成にはいくつかの利点があります。

  • ノード単位の作成、削除、再作成がしやすい
  • コントロールプレーン、ワーカー、検証用ノードを分けやすい
  • VM テンプレートや IaC によって再現性を高めやすい
  • 障害検証や構成変更を VM 単位で試しやすい
  • 物理ホストと Kubernetes ノードの責務を分離しやすい

一方で、VM の上に Kubernetes を載せると、ネットワーク、ストレージ、性能の見通しは複雑になります。Pod の通信が、CNI、VM の仮想 NIC、仮想スイッチ、物理 NIC を経由するため、どの層で問題が起きているかを切り分ける力が必要になります。

ネットワークは特に多層化しやすい

Kubernetes を前提にした仮想化アーキテクチャで難しくなりやすいのはネットワークです。物理ネットワーク、仮想スイッチ、VM の NIC、Linux bridge、OVS、OVN、Kubernetes CNI、Service、Ingress が重なります。

ここで大事なのは、すべてを Kubernetes の中だけで理解しようとしないことです。Pod 間通信の問題に見えても、実際には VM の仮想 NIC、MTU、ルーティング、DNS、ファイアウォール、ロードバランサー相当の設計が原因になることがあります。

Kubernetes は強力ですが、下位レイヤの問題を消すわけではありません。むしろ、下位レイヤを正しく設計した上で、その上にアプリケーション運用の抽象化を重ねる技術です。

ストレージも責任境界を決める必要がある

ストレージも同じです。Kubernetes では PV、PVC、StorageClass、CSI といった抽象化がありますが、その背後にはローカルディスク、NFS、Ceph、外部ストレージ、バックアップ設計があります。

アプリケーションから見ると PVC は単なる永続ボリュームに見えます。しかし、実際にはどのストレージに保存され、どの障害に耐え、どのようにバックアップされ、どこまで復元できるのかを設計しておく必要があります。

Kubernetes の抽象化を使うほど、下位レイヤの責任を意識的に言語化しないと、障害時にどこまで戻せるのかが曖昧になります。

OpenStack、VMware、KVM との関係

VMware は、仮想マシンを安定して運用するための完成された仮想化基盤です。OpenStack は、API を中心にクラウド基盤を作るための部品群です。KVM と libvirt は、Linux 上で仮想化基盤を構成するための土台になります。

Kubernetes を前提にする場合でも、これらの仮想化基盤は不要になるわけではありません。むしろ、Kubernetes ノードをどこに置くか、どのように作るか、障害時にどう再作成するかという点で重要になります。

OpenShift Virtualization のように、Kubernetes 側から VM を管理する考え方もあります。ただし、それも VM とコンテナの境界が消えるというより、VM を Kubernetes の運用モデルに寄せる設計と見る方が自然です。

自宅マイクロデータセンターでは自然なテーマになる

自宅のマイクロデータセンターのような環境では、KVM の上に Kubernetes ノードを作り、その上でアプリケーションを動かす構成はかなり自然です。

物理ホストを直接アプリケーション基盤にするのではなく、VM でノードを分け、Kubernetes でアプリケーションを運用する。さらに構成管理は Ansible で管理し、ネットワークやストレージも明示的に設計する。

これは一般的な家庭内サーバーとしては少し過剰ですが、インフラの責務分離を学び、実際に運用するには非常に良い題材になります。

参考
書籍
参考書籍

Kubernetes 完全ガイド 第 2 版

Kubernetes のリソース、ネットワーク、ストレージ、運用観点を体系的に確認したい場合の参考書籍です。VM と Kubernetes の役割分担を考える前提として役立ちます。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

関連記事

まとめ

Kubernetes を前提にした仮想化アーキテクチャでは、VM とコンテナを対立させて考える必要はありません。VM は OS とノードの境界を作り、Kubernetes はアプリケーション運用を抽象化します。

重要なのは、物理、仮想化、OS、Kubernetes、アプリケーションの責務を分けることです。抽象化を重ねるほど便利になりますが、同時に責任境界を明確にしなければ、障害時にどこを見るべきかが分からなくなります。

Kubernetes は下位レイヤの設計を不要にする技術ではありません。むしろ、下位レイヤを正しく設計した上で、その上にアプリケーション運用の標準化を重ねるための技術です。

Kubernetes を前提とした仮想化アーキテクチャ – VM とコンテナをどう重ねるか

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る