Skip to content

Kubernetes クラスターの自動プロビジョナー

Cockpit の Kubernetes クラスター自動プロビジョナーは、仮想化されたコンピューティングリソースおよびネットワークリソース上に Kubernetes クラスターをデプロイ、スケール、および維持するためのネイティブかつ合理化されたメカニズムを提供します。マルチ VM アーキテクチャ、軽量な k3s ディストリビューション、および自動化されたオーケストレーションを活用することで、Cockpit はクラスターの構築(ブートストラップ)の複雑さを抽象化しながら、ネットワーキング、ストレージ、およびスケジューリングに関するエンタープライズグレードのカスタマイズを提供します。


1. アーキテクチャの概要

Cockpit の自動プロビジョナーは、構造化されたバックグラウンドパイプラインを使用して、物理ハイパーバイザー上の VM を調整します。システムは、あらかじめ構成された OS ゴールデンイメージを使用してコントロールプレーンとワーカーノードをデプロイし、起動時に cloud-init を介してカスタマイズし、起動後は QEMU Guest Agent を使用して管理します。

mermaid
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
    end

Cockpit バックエンドは、ハイパーバイザーとのすべてのやり取りを管理し、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 データストアストレージプール

テンプレートは以下のいずれかのデータストアに保存されている必要があります:

  1. 共有ストレージプール(推奨): ゴールデンイメージテンプレートを共有データストア(NFS やクラスター化された OCFS2 など)に保存すると、Cockpit クラスター内のすべての物理ハイパーバイザーが、コントロールプレーン/ワーカー VM を即座にクローンして起動できます。
  2. ローカルストレージプール(フォールバックキャッシュ): ノードがローカルハイパーバイザーのストレージプールにプロビジョニングされる場合、Cockpit バックエンドはターゲットホストのストレージプールにゴールデンイメージファイルがローカルに存在するかどうかを確認します。存在しない場合、Cockpit は VM のクローン操作を開始する前に、プライマリ Cockpit ストアからそのホストのローカルストレージプールにテンプレートファイルを自動的にキャッシュ(コピー)します。

3. プロビジョニングウィザードの手順

管理者は Cockpit UI から直接プロビジョニングフローを起動できます:

  1. 左側のインベントリツリーで Cluster ノードを右クリックします。
  2. コンテキストメニューで Kubernetes -> New Cluster を選択します。
  3. Kubernetes プロビジョニングウィザードが開き、以下の5つの手順に沿って構成を進めます。
手順セクション名構成項目主なアーキテクチャの規則 / アクション
1ID とバージョン• クラスター名
• 説明
• 対象ネットワーク
• 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 ブートストラッププロセス

  1. Flannel(デフォルト): Cockpit は、標準の k3s インストールフラグを使用してコントロールプレーン VM を構成します:
    bash
    curl -sfL https://get.k3s.io | sh -s - server --disable traefik --write-kubeconfig-mode 644
  2. 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 が登録を試みる前にポッドネットワークをブートストラップします。

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 バックエンドは以下の後処理パイプラインを実行します:

  1. QEMU Guest Agent を使用して、コントロールプレーン VM 上の /etc/rancher/k3s/k3s.yaml から生成された未加工ファイルを読み取ります。
  2. デフォルトのファイルはローカルループバックアドレス(server: https://127.0.0.1:6443)を指しています。
  3. Cockpit は、127.0.0.1(または localhost)をコントロールプレーン VM の外部物理 DHCP IP アドレス(例: server: https://192.168.122.155:6443)に動的に書き換えます。
  4. ペイロードをダウンロード可能な添付ファイルとして返します:
    • Content-Type: application/x-yaml
    • Filename: kubeconfig-{cluster_name}.yaml

6.2 接続手順

ローカルシステムから kubectl CLI を使用して新しいクラスターに接続するには:

  1. Kubeconfig のダウンロード: Cockpit UI のクラスター詳細ページから Download Kubeconfig をクリックします。

  2. ファイルの移動と権限の制限: ダウンロードしたファイルをローカルマシンの構成フォルダーに移動し、アクセス権限を制限します(kubectl に必要):

    bash
    mkdir -p ~/.kube
    mv ~/Downloads/kubeconfig-k8s-prod.yaml ~/.kube/config-k8s-prod
    chmod 600 ~/.kube/config-k8s-prod
  3. KUBECONFIG 環境変数の設定: アクティブなターミナルを新しくダウンロードした構成に指定します:

    bash
    export KUBECONFIG=~/.kube/config-k8s-prod

    TIP

    この設定を永続化するには、シェルプロファイルファイル(例: ~/.bashrc または ~/.zshrc)にエクスポートステートメントを追加します。

  4. 接続の確認: API サーバーに問い合わせ、ノードの可用性を確認して接続をテストします:

    bash
    kubectl 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 スケールアップ

  1. 増減の計算: バックエンドは、リクエストされた数と K8sNodePool データベースに構成されている現在の desired_count を比較します。
  2. トークンの取得: Cockpit は、QEMU Guest Agent を使用してコントロールプレーン VM の /var/lib/rancher/k3s/server/node-token を読み取り、現在のクラスター参加用シークレットを取得します。
  3. VM のクローン: タスクランナーは、OS テンプレートから追加のワーカー VM インスタンスをクローンします。
  4. 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 -
  5. 起動と登録: 起動後、VM は DHCP IP を取得し、それが QEMU Guest Agent 経由で検出されます。Cockpit は、新しいノードが表示され Ready を報告するまで Kubernetes クラスター API を監視します。

7.2 スケールダウン

  1. ノードの選択: Cockpit は、余剰のワーカー VM(アップタイムが最も短いノード、またはインデックスが最も高いノードを優先)を選択します。
  2. 安全なドレイン: Cockpit は、コントロールプレーンを介してクラスタードレインコマンド(kubectl drain <node-name> --delete-emptydir-data --ignore-daemonsets --force に相当)を実行し、ワークロードを退避させます。
  3. 削除と回収: ドレインが完了すると、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 へのアップグレード):

  1. アップグレードのトリガー: Cockpit は POST /api/v1/kubernetes/clusters/:id/upgrade リクエストを送信します。
  2. プランの適用: Cockpit バックエンドは、新しいバージョンを対象とするカスタム Plan マニフェストをクラスターに適用します。
    yaml
    apiVersion: 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
  3. 順次実行:
    • System Upgrade Controller は、一度に1つのノードを選択して処理します(最初にコントロールプレーンノード、次にワーカーノード)。
    • 対象ノード上のワークロードをドレインします。
    • VM 内部の k3s バイナリと構成ファイルを更新します。
    • サービスを再起動し、ヘルスチェックステータスを監視して、ノードのスケジューリング不可状態を解除 (uncordon) します。
    • ノードが Ready 状態に戻ると、コントローラーはシーケンス内の次のノードの処理に進みます。
  4. 監視: 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-agent
    インストールされていない場合は、手動でインストールして自動起動を有効にし、再起動してください:
    bash
    sudo apt-get install -y qemu-guest-agent && sudo systemctl enable --now qemu-guest-agent