Kubernetes クラスターの自動プロビジョナー
Cockpit の Kubernetes クラスター自動プロビジョナーは、仮想化されたコンピューティングリソースおよびネットワークリソース上に Kubernetes クラスターをデプロイ、スケール、および維持するためのネイティブかつ合理化されたメカニズムを提供します。マルチ VM アーキテクチャ、軽量な k3s ディストリビューション、および自動化されたオーケストレーションを活用することで、Cockpit はクラスターの構築(ブートストラップ)の複雑さを抽象化しながら、ネットワーキング、ストレージ、およびスケジューリングに関するエンタープライズグレードのカスタマイズを提供します。
1. アーキテクチャの概要
Cockpit の自動プロビジョナーは、構造化されたバックグラウンドパイプラインを使用して、物理ハイパーバイザー上の VM を調整します。システムは、あらかじめ構成された OS ゴールデンイメージを使用してコントロールプレーンとワーカーノードをデプロイし、起動時に cloud-init を介してカスタマイズし、起動後は QEMU Guest Agent を使用して管理します。
flowchart TD
subgraph Cockpit Management Plane
UI[Cockpit UI ダッシュボード] -->|REST API / WebSockets| API[Cockpit API エンジン]
API -->|タスクランナー| Tasks[バックグラウンドプロビジョニングタスク]
DB[(PostgreSQL DB - GORM)] <-->|クラスターとノードのステータス| API
end
subgraph データストアとストレージ
DS_Shared[共有データストア - NFS] -->|即時の VM クローニング| Hypervisors
DS_Local[ローカルデータストア] -->|フォールバックテンプレートキャッシュ| Hypervisors
end
subgraph ハイパーバイザーと VM
Hypervisors -->|クローンしてデプロイ| VM_CP[コントロールプレーン VM]
Hypervisors -->|クローンしてデプロイ| VM_W1[ワーカーノード 1 VM]
Hypervisors -->|クローンしてデプロイ| VM_W2[ワーカーノード 2 VM]
end
subgraph Kubernetes クラスター
VM_CP -->|k3s サーバーの起動| K8S_CP[コントロールプレーンノード]
VM_W1 -->|トークンでクラスターに参加| K8S_CP
VM_W2 -->|トークンでクラスターに参加| K8S_CP
endCockpit バックエンドは、ハイパーバイザーとのすべてのやり取りを管理し、VM のステータスを監視し、QEMU Guest Agent を介して VM から構成状態を読み取り、クラスターのブートストラップを実行します。
2. インフラの前提条件
自動プロビジョナーを使用する前に、管理者は仮想化環境とベーステンプレートが以下の要件を満たしていることを確認する必要があります。
2.1 OS ゴールデンイメージテンプレート
迅速な VM クローニングをサポートするために、標準化された「ゴールデンイメージ」が必要です。
- ベースオペレーティングシステム: Ubuntu 24.04 LTS(
qcow2形式)。 - QEMU Guest Agent: プリインストールされ(
apt-get install -y qemu-guest-agent)、起動時に有効になるよう設定されている必要があります。エージェントにより、Cockpit は以下を実行できます:- DHCP を介して割り当てられた VM の IP アドレスを動的に検出します。
- k3s 参加トークンなどの認証トークンを安全に取得します。
- SSH キーを公開したり、ネットワークトンネルを設定したりすることなく、生成された
kubeconfigを取得します。
- Cloud-Init: 有効化され、libvirt ハイパーバイザーから渡されるメタデータを読み取るように構成されている必要があります。
- ルートパーティションの自動拡張: ルートパーティションは、最初の起動時に割り当てられたディスクサイズに合わせて自動的に拡張するように構成されている必要があります(
growpartまたは同様の cloud-init ユーティリティを使用)。
2.2 データストアストレージプール
テンプレートは以下のいずれかのデータストアに保存されている必要があります:
- 共有ストレージプール(推奨): ゴールデンイメージテンプレートを共有データストア(NFS やクラスター化された OCFS2 など)に保存すると、Cockpit クラスター内のすべての物理ハイパーバイザーが、コントロールプレーン/ワーカー VM を即座にクローンして起動できます。
- ローカルストレージプール(フォールバックキャッシュ): ノードがローカルハイパーバイザーのストレージプールにプロビジョニングされる場合、Cockpit バックエンドはターゲットホストのストレージプールにゴールデンイメージファイルがローカルに存在するかどうかを確認します。存在しない場合、Cockpit は VM のクローン操作を開始する前に、プライマリ Cockpit ストアからそのホストのローカルストレージプールにテンプレートファイルを自動的にキャッシュ(コピー)します。
3. プロビジョニングウィザードの手順
管理者は Cockpit UI から直接プロビジョニングフローを起動できます:
- 左側のインベントリツリーで Cluster ノードを右クリックします。
- コンテキストメニューで Kubernetes -> New Cluster を選択します。
- Kubernetes プロビジョニングウィザードが開き、以下の5つの手順に沿って構成を進めます。
| 手順 | セクション名 | 構成項目 | 主なアーキテクチャの規則 / アクション |
|---|---|---|---|
| 1 | ID とバージョン | • クラスター名 • 説明 • 対象ネットワーク • K3s バージョン (例: v1.29.2+k3s1)• CNI ネットワークプラグイン | • CNI オプションには、Flannel(デフォルト)、Calico、および Cilium eBPF があります。 • 対象ネットワークは、VM を仮想ネットワークブリッジに割り当てます。 |
| 2 | コントロールプレーン構成 | • CPU vCore 数 • メモリ (GB) • ストレージプール • ディスクサイズ (GB) • ノード数 (1 または 3) • 配置戦略 | • ノード数のオプション: シングルコントロールプレーン(1 ノード)または高可用性 (HA)(3 ノード)。 • 配置オプション: 1. 自動分散: Cockpit の DRS エンジンを使用して非アフィニティルールを適用し、3台の HA マスター VM が3台の異なる物理ホストにスケジュールされるようにします。 2. 手動オーバーライド: 各ノードに特定のハイパーバイザーを明示的に割り当てるためのドロップダウンが表示されます。 |
| 3 | ワーカーノードプール | • ワーカー数(デフォルト: 3)• ワーカーごとの CPU vCore 数 • メモリ (GB) • ストレージプール • ディスクサイズ (GB) • 配置戦略 | • 配置オプション: 1. 自動分散: CPU/メモリの使用率のバランスを取るために、ワーカー VM を物理ホスト全体に自動的に分散します。 2. 手動オーバーライド: ワーカー VM を特定のホストに明示的に割り当てます(GPU などのホスト固有のハードウェアを利用する場合に便利です)。 |
| 4 | 資格情報と CSI 階層 | • SSH 公開鍵 (テキストエリア) • CSI ストレージ階層オプション | • SSH 鍵: トラブルシューティングのために VM ノードへの root/admin アクセスを許可します。 • CSI ストレージ階層(詳細はセクション5を参照): - 階層 1: ホストパス ( local-path-provisioner) [デフォルトで有効]。- 階層 2: NFS 共有ストレージ [デフォルトで無効]。 - 階層 3: レプリケーションブロックストレージ (Longhorn) [デフォルトで無効]。 |
| 5 | 確認とプロビジョニング | • サマリーダッシュボード | • 構成、リソースフットプリント、および物理ホストのマッピングを表示します。 • Provision をクリックすると、Cockpit に実行時間の長いタスクが登録され、ウィザードが閉じます。 |
4. Container Network Interface (CNI) の構成
CNI の選択によって、ポッドネットワークのルーティング、セキュリティポリシー、およびパフォーマンス特性が決まります。
| CNI プラグイン | デフォルト | ルーティング技術 | セキュリティ / ネットワークポリシー | 主なユースケース |
|---|---|---|---|---|
| Flannel | はい | VXLAN / Host-gw カプセル化 | なし | 軽量、ローカル開発、単一ノードまたは低オーバーヘッド環境。 |
| Calico | いいえ | IP-in-IP / BGP ルーティング | 完全な Kubernetes NetworkPolicies | 安全な分離ポリシーを必要とするマルチテナント環境。 |
| Cilium | いいえ | Linux eBPF (直接ルーティング) | 高度な L3-L7 ポリシー適用と Hubble テレメトリ | 高スループットが必要な高性能プロダクション環境。 |
CNI ブートストラッププロセス
- Flannel(デフォルト): Cockpit は、標準の k3s インストールフラグを使用してコントロールプレーン VM を構成します:bash
curl -sfL https://get.k3s.io | sh -s - server --disable traefik --write-kubeconfig-mode 644 - Calico & Cilium(カスタム CNI):
- ルーティングルールの競合を防ぐため、Cockpit は組み込みの Flannel およびネットワークポリシーコンポーネントを無効にするフラグを使用してコントロールプレーン VM を起動します:bash
curl -sfL https://get.k3s.io | sh -s - server --disable traefik --flannel-backend=none --disable-network-policy --write-kubeconfig-mode 644 - クラスターは最初に「ネットワーク利用不可 (Network Unavailable)」状態で起動します。API サーバーが到達可能になると、Cockpit バックエンドはカスタムの Calico または Cilium マニフェスト(Helm チャートデプロイまたは YAML リソース)を直接適用し、ワーカー VM が登録を試みる前にポッドネットワークをブートストラップします。
- ルーティングルールの競合を防ぐため、Cockpit は組み込みの Flannel およびネットワークポリシーコンポーネントを無効にするフラグを使用してコントロールプレーン VM を起動します:
5. Container Storage Interface (CSI) のオプション
Cockpit は、永続ボリューム(PV)を物理ハイパーバイザーのストレージプールまたは共有インフラにマッピングできるマルチ階層 CSI 選択インターフェースを実装しています。
┌────────────────────────────────────────┐
│ CSI ストレージオプション │
└───────────────────┬────────────────────┘
│
┌────────────────────────────┼────────────────────────────┐
▼ ▼ ▼
[階層 1: ホストパス] [階層 2: NFS 共有] [階層 3: Longhorn ブロック]
• 組み込みの local-path • NFS CSI ドライバー • Longhorn がローカル
• ポッドデータを VM の • NFS データストアに接続 VM ディスクを統合
ルートディスクに保存 • ReadWriteMany をサポート • レプリケーション、高可用性5.1 階層 1: ホストパス(デフォルトで有効)
- エンジン: k3s 組み込みの
local-path-provisionerを使用します。 - データフロー: PV データは、ワーカー VM のルートディスク上の指定されたローカルパス(
/opt/local-path-provisioner)に書き込まれます。VM のディスク(.qcow2ファイル)は Cockpit の物理ホストストレージプール上に存在するため、ストレージは最終的にホストの物理ディスクによってバッキングされます。 - メリット/デメリット: 高いパフォーマンス、セットアップ不要。ただし、ボリュームは移動不可です。ポッドが別のワーカー VM に再スケジュールされた場合、データにアクセスできなくなります。
5.2 階層 2: NFS 共有ストレージ(オプション)
- エンジン: Kubernetes NFS CSI ドライバーをデプロイします。
- 構成オプション:
- 既存の NFS データストアを使用する: Cockpit ですでに構成されている NFS ストレージプールから選択します。サーバー IP とエクスポートパスの詳細は、Cockpit のデータベースから自動的に取得されます。
- 外部の NFS サーバーを使用する: NFS サーバーの IP/ホスト名、マウントパス、および資格情報を手動で指定します。
- バックエンドの事前チェック: プロビジョニングが開始される前に、Cockpit タスクランナーは、選択された仮想ネットワークブリッジから指定された NFS サーバー IP へのポート
2049(NFS ポート)での TCP 接続を試行します。接続できない場合、タスクは停止し、管理者に警告します。 - メリット/デメリット:
ReadWriteMany(RWX)PV をサポートします。ポッドは、同じボリュームへのアクセスを維持したまま、ワーカーノードや物理ハイパーバイザー間を動的に移行できます。
5.3 階層 3: レプリケーションストレージ - Longhorn(オプション)
- エンジン: クラスター内に Longhorn 分散ブロックストレージオペレーターをデプロイします。
- 構成: 管理者は、ワーカー VM のディスクファイルを格納する対象の Cockpit ホストデータストア(例:
fast-ssd-pool)を選択します。 - データフロー: Longhorn は、すべてのワーカー VM のローカルディスクスペース(選択された高速ホストデータストア上に物理的に存在する)を統合し、レプリケーションされたブロックストレージを提供します。
- メリット/デメリット: 完全な冗長性を備えた高可用性ストレージ(
ReadWriteOnce)。重要なステートフルアプリケーション(データベース)に最適です。物理ホストまたはワーカー VM がダウンした場合でも、ボリュームは他のノードから引き続きアクセス可能です。
6. クラスターへのアクセス: Kubeconfig のセットアップ
クラスターのステータスが active に移行すると、管理用の kubeconfig がダウンロード可能になります。
6.1 エンドポイントの動的書き換え
ユーザーが GET /api/v1/kubernetes/clusters/:id/kubeconfig を介して kubeconfig をリクエストすると、Cockpit バックエンドは以下の後処理パイプラインを実行します:
- QEMU Guest Agent を使用して、コントロールプレーン VM 上の
/etc/rancher/k3s/k3s.yamlから生成された未加工ファイルを読み取ります。 - デフォルトのファイルはローカルループバックアドレス(
server: https://127.0.0.1:6443)を指しています。 - Cockpit は、
127.0.0.1(またはlocalhost)をコントロールプレーン VM の外部物理 DHCP IP アドレス(例:server: https://192.168.122.155:6443)に動的に書き換えます。 - ペイロードをダウンロード可能な添付ファイルとして返します:
- Content-Type:
application/x-yaml - Filename:
kubeconfig-{cluster_name}.yaml
- Content-Type:
6.2 接続手順
ローカルシステムから kubectl CLI を使用して新しいクラスターに接続するには:
Kubeconfig のダウンロード: Cockpit UI のクラスター詳細ページから Download Kubeconfig をクリックします。
ファイルの移動と権限の制限: ダウンロードしたファイルをローカルマシンの構成フォルダーに移動し、アクセス権限を制限します(kubectl に必要):
bashmkdir -p ~/.kube mv ~/Downloads/kubeconfig-k8s-prod.yaml ~/.kube/config-k8s-prod chmod 600 ~/.kube/config-k8s-prodKUBECONFIG 環境変数の設定: アクティブなターミナルを新しくダウンロードした構成に指定します:
bashexport KUBECONFIG=~/.kube/config-k8s-prodTIP
この設定を永続化するには、シェルプロファイルファイル(例:
~/.bashrcまたは~/.zshrc)にエクスポートステートメントを追加します。接続の確認: API サーバーに問い合わせ、ノードの可用性を確認して接続をテストします:
bashkubectl cluster-info kubectl get nodes -o wide
7. ワーカープールの動的スケーリング
Cockpit を使用すると、ユーザーはクラスターやコントロールプレーンを再構築することなく、ワーカーノードプールを動的にスケールアップまたはスケールダウンできます。
プールスケーリングリクエスト受信
│
▼
ノードの増減を計算
│
┌──────────────────┴──────────────────┐
▼ (増加) ▼ (減少)
[スケールアップ] [スケールダウン]
│ │
QEMU Guest Agent 経由で │
コントロールプレーン VM から │
参加トークンを取得 │
│ │
OS ゴールデンテンプレートから │
新しいワーカー VM をクローン │
│ │
コントロールプレーン IP と │
参加トークンを使用して │
Cloud-Init 参加コマンドを注入 │
│ │
VM を起動し DHCP ノードを安全にドレイン
IP 検出を待機 (kubectl drain)
│ │
Kubernetes ノードのステータスが ワーカー VM を削除
"Ready" になるのを待機 │
│ │
GORM DB にノード情報を保存 DB レコードを更新
│ │
└──────────────────┬──────────────────┘
▼
タスク完了7.1 スケールアップ
- 増減の計算: バックエンドは、リクエストされた数と
K8sNodePoolデータベースに構成されている現在のdesired_countを比較します。 - トークンの取得: Cockpit は、QEMU Guest Agent を使用してコントロールプレーン VM の
/var/lib/rancher/k3s/server/node-tokenを読み取り、現在のクラスター参加用シークレットを取得します。 - VM のクローン: タスクランナーは、OS テンプレートから追加のワーカー VM インスタンスをクローンします。
- Cloud-Init の設定: 新しい VM のユーザーデータに以下の参加構成を設定します:yaml
#cloud-config runcmd: - systemctl enable --now qemu-guest-agent - curl -sfL https://get.k3s.io | K3S_URL=https://<CONTROL_PLANE_IP>:6443 K3S_TOKEN=<JOIN_TOKEN> sh - - 起動と登録: 起動後、VM は DHCP IP を取得し、それが QEMU Guest Agent 経由で検出されます。Cockpit は、新しいノードが表示され
Readyを報告するまで Kubernetes クラスター API を監視します。
7.2 スケールダウン
- ノードの選択: Cockpit は、余剰のワーカー VM(アップタイムが最も短いノード、またはインデックスが最も高いノードを優先)を選択します。
- 安全なドレイン: Cockpit は、コントロールプレーンを介してクラスタードレインコマンド(
kubectl drain <node-name> --delete-emptydir-data --ignore-daemonsets --forceに相当)を実行し、ワークロードを退避させます。 - 削除と回収: ドレインが完了すると、Cockpit は対象の仮想マシンを停止および削除してハイパーバイザーのリソースを解放し、
K8sNodeデータベーステーブルから対応するレコードを削除します。
8. 動的なバージョン選択とアップグレード
Cockpit は、Rancher の System Upgrade Controller オペレーターを使用して、Kubernetes クラスターの無停止(ゼロダウンタイム)アップグレードを実行します。
8.1 バージョンの動的取得
Cockpit UI は、ハードコードされたバージョンリストに依存せず、バックエンドエンドポイント GET /api/v1/kubernetes/k3s-versions に動的に問い合わせます。
- 動的取得: バックエンドは GitHub Releases API に問い合わせて、アクティブで安定した k3s タグを取得します。
- フォールバックリスト: ネットワークが隔離されている(エアギャップ)環境や GitHub API のレート制限が発生した場合、Cockpit は
v1.36.1+k3s1からv1.31.0+k3s1までの事前定義された内蔵 K3s リリースリストを使用します。
8.2 System Upgrade Controller のセットアップ
初期のクラスターブートストラップ中に、Cockpit はクラスター内に system-upgrade-controller をデプロイします。このコントローラーは、アップグレードを実行するためのカスタム Plan リソースを監視します。
8.3 アップグレードパイプライン
管理者が UI で新しい k3s バージョンを選択した場合(例: v1.28.7+k3s1 から v1.29.2+k3s1 へのアップグレード):
- アップグレードのトリガー: Cockpit は
POST /api/v1/kubernetes/clusters/:id/upgradeリクエストを送信します。 - プランの適用: Cockpit バックエンドは、新しいバージョンを対象とするカスタム
Planマニフェストをクラスターに適用します。yamlapiVersion: upgrade.cattle.io/v1 kind: Plan metadata: name: k3s-server namespace: system-upgrade spec: concurrency: 1 version: v1.29.2+k3s1 nodeSelector: matchExpressions: - key: node-role.kubernetes.io/master operator: In values: - "true" serviceAccountName: system-upgrade upgrade: image: rancher/k3s-upgrade - 順次実行:
- System Upgrade Controller は、一度に1つのノードを選択して処理します(最初にコントロールプレーンノード、次にワーカーノード)。
- 対象ノード上のワークロードをドレインします。
- VM 内部の k3s バイナリと構成ファイルを更新します。
- サービスを再起動し、ヘルスチェックステータスを監視して、ノードのスケジューリング不可状態を解除 (uncordon) します。
- ノードが
Ready状態に戻ると、コントローラーはシーケンス内の次のノードの処理に進みます。
- 監視: Cockpit バックエンドは、カスタムリソース
Planのステータスを照会し、タスクパネルに進行状況を示す進捗バーを表示します。
9. トラブルシューティングと一般的な問題
9.1 VM が「作成中 (Creating)」または「起動中 (Booting)」状態のまま進まない
- 想定される原因: ターゲットホストのローカルデータストアに OS ゴールデンイメージテンプレートが存在しないか、ネットワーク経由のコピー速度が遅いため処理が遅延しています。
- 解決策: Cockpit のタスクログでイメージコピーイベントの成否を確認してください。コピーに失敗している場合は、ホスト間レプリケーションのアクセス権限とネットワークブリッジが有効であることを確認してください。
9.2 ノードは起動したがクラスターに参加できない(CNI が利用不可)
- 想定される原因: カスタム CNI(Calico/Cilium)のインストールマニフェストがコントロールプレーンに正常に適用されず、ネットワーク初期化が失敗しています。
- 解決策: コントロールプレーン VM のコンソールまたはターミナルにアクセスし、API サーバーが正常に起動しているか確認してください。外部レジストリからカスタム CNI イメージを取得するため、VM がインターネットに接続できていることを確認してください。
9.3 QEMU Guest Agent に接続できない
- 想定される原因: ゴールデンイメージで QEMU Guest Agent デーモンが自動起動するよう設定されていないか、デーモンが起動時にクラッシュしています。
- 解決策: Cockpit の
noVNCパネルから VM コンソールを開いてログインし、エージェントサービスが稼働しているかステータスを確認してください:bashインストールされていない場合は、手動でインストールして自動起動を有効にし、再起動してください:systemctl status qemu-guest-agentbashsudo apt-get install -y qemu-guest-agent && sudo systemctl enable --now qemu-guest-agent