この記事は1年以上前のものです。古い記事には古い内容が含まれている可能性があります。公開時から情報が古くなっていないかご確認ください。
Kubernetesの中でKubernetesを実行するという最も興味深いフェーズに近づいています。 この記事では、KamajiやCluster APIなどのテクノロジーとそれらのKubeVirtとの統合について説明します。
以前の議論では、ベアメタル上でのKubernetesの準備と、Kubernetesを仮想マシン管理システムに変える方法について説明しました。 この記事では、上記のすべてを使用して、本格的な管理対象のKubernetesを構築し、ワンクリックで仮想Kubernetesクラスターを実行する方法を説明して、シリーズを締めくくります。
まず、Cluster APIについて詳しく見ていきましょう。
Cluster APIは、Kubernetesの拡張機能で、別のKubernetesクラスター内でカスタムリソースとしてKubernetesクラスターを管理できるようにするものです。
Cluster APIの主な目的は、Kubernetesクラスターの基本的なエンティティを記述し、そのライフサイクルを管理するための統一されたインターフェースを提供することです。 これにより、クラスターの作成、更新、削除のプロセスを自動化し、スケーリングとインフラストラクチャの管理を簡素化できます。
Cluster APIのコンテキストでは、管理クラスターとテナントクラスターの2つの用語があります。
テナントクラスターは、物理的に管理クラスターと同じインフラストラクチャ上で実行する必要は必ずしもないことを理解することが重要です。 むしろ多くの場合、それらは別の場所で実行されています。
Cluster APIを使用した管理KubernetesクラスターとテナントKubernetesクラスターの相互作用を示す図
Cluster APIは、その動作のために プロバイダー の概念を利用します。 プロバイダーは、作成されるクラスターの特定のコンポーネントを担当する個別のコントローラーです。 Cluster API内にはいくつかの種類のプロバイダーがあります。 主なものは次のとおりです。
始めるには、Cluster API自体と各種プロバイダーを1つずつインストールする必要があります。 サポートされているプロバイダーの完全なリストはプロジェクトのドキュメントで確認できます。
インストールにはclusterctlユーティリティや、より宣言的な方法としてCluster API Operatorを使用できます。
KubeVirtを使用してKubernetesクラスターを実行するにはKubeVirt Infrastructure Providerをインストールする必要があります。 これにより、Cluster APIが動作する管理クラスターと同じ場所で、ワーカーノード用の仮想マシンをデプロイできるようになります。
Kamajiプロジェクトは、管理クラスター内のコンテナとしてテナントクラスターのKubernetesコントロールプレーンを実行するためのソリューションを提供しています。 このアプローチには、いくつかの重要な利点があります。
Kubeadmをブートストラッププロバイダーとして使用します。 これは、Cluster APIでクラスターを準備するための標準的な方法です。 このプロバイダーは、Cluster API自体の一部として開発されています。kubeletとkubeadmがインストールされた準備済みのシステムイメージのみが必要で、cloud-initとignitionの形式でコンフィグを生成できます。
Talos LinuxもCluster API経由でのプロビジョニングをサポートしており、そのためのプロバイダーが用意されていることは注目に値します。 前回の記事では、ベアメタルノードで管理クラスターをセットアップするためにTalos Linuxを使用する方法について説明しましたが、テナントクラスターをプロビジョニングするには、Kamaji+Kubeadmのアプローチの方が優れています。 コンテナへのKubernetesコントロールプレーンのデプロイを容易にするため、コントロールプレーンインスタンス用に個別の仮想マシンを用意する必要無くなります。 これにより、管理が簡素化され、コストが削減されます。
Cluster APIの主要なオブジェクトはClusterリソースで、他のすべてのリソースの親となります。 通常、このリソースは他の2つのリソースを参照します。 コントロールプレーンを記述するリソースとインフラストラクチャを記述するリソースです。 それぞれが個別のプロバイダーによって管理されます。
Clusterとは異なり、これら2つのリソースは標準化されておらず、そのリソースの種類は使用している特定のプロバイダーに依存します。
Cluster APIにおけるClusterリソースとそれがリンクするリソースの関係を示す図
Cluster APIには、MachineDeploymentという名前のリソースもあります。 これは物理サーバーか仮想マシンかにかかわらずノードのグループを記述するものです。 このリソースは、Deployment、ReplicaSet、Podなどの標準のKubernetesリソースと同様に機能し、ノードのグループを宣言的に記述し、自動的にスケーリングするためのメカニズムを提供します。
つまり、MachineDeploymentリソースを使用すると、クラスターのノードを宣言的に記述でき、指定されたパラメーターと要求されたレプリカ数に応じて、ノードの作成、削除、更新を自動化できます。
Cluster APIにおけるMachineDeploymentリソースとその子リソースの関係を示す図
マシンを作成するために、MachineDeploymentは、マシン自体を生成するためのテンプレートと、そのcloud-init設定を生成するためのテンプレートを参照します。
Cluster APIにおけるMachineDeploymentリソースとそれがリンクするリソースの関係を示す図
Cluster APIを使用して新しいKubernetesクラスターをデプロイするには、以下のリソースのセットを準備する必要があります。
ほとんどの場合これで十分ですが、使用するプロバイダーによっては、他のリソースも必要になる場合があります。 プロバイダーの種類ごとに作成されるリソースの例は、Kamajiプロジェクトのドキュメントで確認できます。
この段階ですでに使用可能なテナントKubernetesクラスターができていますが、これまでのところ、APIワーカーとあらゆるKubernetesクラスターのインストールに標準で含まれるいくつかのコアプラグイン(kube-proxyとCoreDNS)しか含まれていません。 完全に統合するには、さらにいくつかのコンポーネントをインストールする必要があります。
追加のコンポーネントをインストールするには、個別のCluster API Add-on Provider for Helmや、前の記事で説明したFluxCDを使用できます。
FluxCDでリソースを作成する際、Cluster APIによって生成されたkubeconfigを参照することでターゲットクラスターを指定できます。 そうするとインストールは直接そのクラスターに対して実行されます。 このように、FluxCDは管理クラスターとユーザーテナントクラスターの両方でリソースを管理するための汎用ツールになります。
管理クラスターとテナントKubernetesクラスターの両方にコンポーネントをインストールできるfluxcdの相互作用スキームを示す図
ここで議論されているコンポーネントとは何でしょうか?一般的に、そのセットには以下が含まれます。
テナントKubernetesクラスター内のPod間の通信を確保するには、CNIプラグインをデプロイする必要があります。 このプラグインは、Pod同士が相互に通信できるようにする仮想ネットワークを作成し、従来はクラスターのワーカーノード上にDaemonsetとしてデプロイされます。 適切だと思うCNIプラグインを選んでインストールできます。
ネストされたKubernetesクラスターのスキームにおいて、テナントKubernetesクラスター内にインストールされたCNIプラグインを示す図
この一部レスポンスについては、以下のようにMarkdown記法を修正するのが良いと思います。
クラウドコントローラーマネージャー(CCM)の主な役割は、Kubernetes をクラウドインフラストラクチャプロバイダーの環境(この場合は、テナントKubernetesのすべてのワーカーがプロビジョニングされている管理Kubernetesクラスター)と統合することです。 CCMが実行するタスクは次のとおりです。
node.cloudprovider.kubernetes.io/uninitialized) を付けてクラスターに追加されます。これにより、必要に応じて追加のビジネスロジックを処理できます。初期化が正常に完了すると、この taint がノードから削除されます。クラウドプロバイダーによっては、CCM がテナントクラスターの内部と外部の両方で動作する場合があります。
KubeVirt Cloud Providerは、外部の親管理クラスターにインストールするように設計されています。 したがって、テナントクラスターでLoadBalancerタイプのサービスを作成すると親クラスターでLoadBalancerサービスの作成が開始され、トラフィックがテナントクラスターに誘導されます。
ネストされたKubernetesクラスターのスキームにおいて、テナントKubernetesクラスターの外部にインストールされたCloud Controller Managerと、それが管理する親から子へのKubernetesクラスター間のサービスのマッピングを示す図
Container Storage Interface(CSI)は、Kubernetesでストレージを操作するために、2つの主要な部分に分かれています。
KubeVirt CSI Driverを使用するコンテキストでは、ユニークな機会が生まれます。 KubeVirtの仮想マシンは管理KubernetesクラスターでKubernetesのフル機能のAPIが利用できる環境で実行されるため、ユーザーのテナントクラスターの外部でcsi-controllerを実行する道が開かれます。 このアプローチはKubeVirtコミュニティで人気があり、いくつかの重要な利点があります。
ただし、csi-nodeは、各ノードのkubeletと直接やり取りするため、必然的にテナントクラスター内で実行する必要があります。 このコンポーネントは、Podへのボリュームのマウントとマウント解除を担当し、クラスターノードで直接発生するプロセスとの緊密な統合が必要です。
KubeVirt CSIドライバーは、ボリュームの要求のためのプロキシとして機能します。 テナントクラスター内でPVCが作成されると、管理クラスターにPVCが作成され、作成されたPVが仮想マシンに接続されます。
ネストされたKubernetesクラスターのスキームにおいて、テナントKubernetesクラスターの内部と外部の両方にインストールされたCSIプラグインのコンポーネントと、それが管理する親から子へのKubernetesクラスター間の永続ボリュームのマッピングを示す図
クラスターオートスケーラーは、さまざまなクラウドAPIと連携できる汎用的なコンポーネントであり、Cluster APIとの統合は利用可能な機能の1つに過ぎません。 適切に設定するには、2つのクラスターへのアクセスが必要です。 テナントクラスターではPodを追跡し、新しいノードを追加する必要性を判断し、管理するKubernetesクラスター(管理Kubernetesクラスター)ではMachineDeploymentリソースと対話し、レプリカ数を調整します。
Cluster Autoscalerは通常テナントKubernetesクラスター内で実行されますが、今回のケースでは、前述と同じ理由からクラスター外にインストールすることをお勧めします。 このアプローチは、テナントクラスターのユーザーが管理クラスターの管理APIにアクセスできないようにするため、メンテナンスがより簡単で、より安全です。
ネストされたKubernetesクラスターのスキームにおいて、テナントKubernetesクラスターの外部にインストールされたCluster Autoscalerを示す図
もう1つ追加のコンポーネントについて言及したいと思います。 Konnectivityです。 後でテナントKubernetesクラスターでwebhookとAPIアグリゲーションレイヤーを動作させるために、おそらくこれが必要になるでしょう。 このトピックについては、私の以前の記事で詳しく説明しています。
上記のコンポーネントとは異なり、Kamajiでは、Konnectivityを簡単に有効にし、kube-proxyやCoreDNSと並んで、テナントクラスターのコアコンポーネントの1つとして管理できます。
これで、動的スケーリング、ボリュームの自動プロビジョニング、ロードバランサーの機能を備えた、完全に機能するKubernetesクラスターができました。
今後は、テナントクラスターからのメトリクスやログの収集を検討するとよいでしょうが、それはこの記事の範囲を超えています。
もちろん、Kubernetesクラスターをデプロイするために必要なコンポーネントはすべて、1つのHelmチャートにパッケージ化し、統一されたアプリケーションとしてデプロイできます。 これは、オープンなPaaSプラットフォームであるCozystackで、ボタンをクリックするだけで管理対象のKubernetesクラスターのデプロイを整理する方法そのものです。 Cozystackでは、記事で説明したすべてのテクノロジーを無料で試すことができます。