DUICUO

一般的に使用されているKubernetesマルチクラスタソリューションの予備調査

クラスター フェデレーションの一般的なアプリケーション シナリオ:

  • 高可用性: 複数のクラスターにアプリケーションを展開すると、クラスター障害の影響を最小限に抑えることができます。
  • ベンダー ロックインを回避: アプリケーションのワークロードは複数のベンダーのクラスターに分散され、必要に応じて他のベンダーに直接移行できます。
  • 障害の分離: 複数の小さなクラスターを持つ方が、単一の大きなクラスターを持つよりも障害を分離しやすくなります。

フェデレーション v1

最も初期のマルチクラスター プロジェクトは、Kubernetes コミュニティによって提案され、維持されていました。

Federation v1はKubernetes v1.3をベースに設計され、その後のバージョンでは関連コンポーネントとコマンドラインツール(kubefed)がリリースされ、ユーザーが迅速にフェデレーションクラスタを構築できるようにしました。v1.6でベータ版に移行しましたが、その後は開発が進められませんでした。柔軟性とAPIの成熟度に関する問題から、Kubernetes v1.11頃に正式に廃止されました。

v1 の基本アーキテクチャは上の図に示されており、主に次の 3 つのコンポーネントで構成されています。

  • フェデレーション API サーバー: Kubernetes API サーバーと同様に、統合されたリソース管理ポータルを提供しますが、サポートされている Kubernetes リソースを拡張するにはアダプターの使用のみを許可します。
  • コントローラー マネージャー: kube-controller-manager と同様に、複数のクラスター間のリソースのスケジュールと状態の同期を提供します。
  • Etcd: フェデレーションを保存するためのリソース

バージョンv1では、フェデレーションリソースを作成するための一般的な手順は次のとおりです。すべてのフェデレーション構成情報は、リソースオブジェクトのアノテーションに書き込まれます。作成プロセス全体はKubernetesと同様です。リソースはFederation APIサーバー上に作成され、その後、Federation Controller Managerがアノテーションの設定に従って各サブクラスターにリソースを作成します。以下はReplicaSetの例です。

このアーキテクチャには、主に 2 つの問題があります。

  • 柔軟性が十分ではありません。新しいリソースが作成されるたびに、新しいアダプタを追加する必要があり (コードのコミットとリリース)、オブジェクトには多くの Federation 固有の注釈が付けられます。
  • 独立した API オブジェクトのバージョン管理が不足しています。たとえば、デプロイメントは Kubernetes では GA ですが、Federation v1 ではベータ版のみです。

フェデレーション v2

バージョン v1 から得た経験と教訓に基づいて、コミュニティは新しいクラスター フェデレーション アーキテクチャである Federation v2 を提案しました。Federation プロジェクトの進化については、Kubernetes Federation Evolution の記事でも参照できます。

バージョン 2 では、CRD を使用して全体的な機能を実装し、さまざまなカスタム リソース (CR) を定義することでバージョン 1 にあった API サーバーの必要性を排除します。バージョン 2 は、次の 2 つのコンポーネントで構成されます。

  • admission-webhookは入場制御を提供します
  • コントローラー マネージャーはカスタム リソースを処理し、異なるクラスター間の状態を調整します。

バージョン 2 でフェデレーション リソースを作成する一般的なプロセスは次のとおりです。

フェデレーテッドリソースはホストクラスターのAPIサーバーに作成されます。その後、コントローラーマネージャーが介入し、対応するリソースを異なるクラスターに分散させます。分散ルールはすべてこのフェデレーテッドリソースオブジェクトに記述されます。

論理的には、Federation v2 は構成と伝播という 2 つの主要部分に分かれており、構成には主にクラスター構成とタイプ構成という 2 つの構成が含まれます。

クラスタ構成

これは、フェデレーションクラスタのAPI認証情報を保存するために使用されます。クラスタへの参加または削除は、 ​kubefedctl join/unjoin​コマンドを使用して行うことができます。参加に成功すると、APIエンドポイント、CAバンドル、トークンなどのクラスタ関連情報を格納するための​KubeFedCluster​ CRが作成されます。コントローラマネージャは、この情報を使用して、異なるKubernetesクラスタにアクセスします。

 APIバージョン: core.kubefed.io/v1beta1
種類: KubeFedCluster
メタデータ:
作成タイムスタンプ: "2019-10-24T08:05:38Z"
世代: 1
名前: クラスター1
名前空間: kube-federation-system
リソースバージョン: "647452"
selfLink: /apis/core.kubefed.io/v1beta1/namespaces/kube-federation-system/kubefedclusters/cluster1
uid: 4c5eb57f-5ed4-4cec-89f3-cfc062492ae0
仕様:
apiエンドポイント: https://172.16.200.1:6443
caBundle: LS... .Qo =
シークレットRef:
名前: cluster1-shb2x
状態:
条件:
-最終プローブ時間: "2019-10-28T06:25:58Z"
最終遷移時間: "2019-10-28T05:13:47Z"
メッセージ: /healthz が OK と応答しました
理由: ClusterReady
ステータス: "True"
タイプ: 準備完了
地域: ""

タイプ構成

これは、フェデレーション管理に使用するKubernetes APIリソースを定義します。例えば、フェデレーションメカニズムを介して異なるクラスターに​ConfigMap​リソースを作成する場合、まずCRDを使用してホストクラスターに新しいリソース​FederatedConfigMap​を作成し、次に​configmaps​​FederatedTypeConfig​ 」)という名前のType設定リソースを作成し、最後に​ConfigMap​ ​FederatedConfigMap​で管理するように記述する必要があります。これにより、Kubefedコントローラーマネージャーはフェデレーションリソースの作成方法を認識できます。例を以下に示します。

 APIバージョン: core.kubefed.k8s.io/v1beta1
種類: FederatedTypeConfig
メタデータ:
名前: configmaps
名前空間: kube-federation-system
仕様:
フェデレーションタイプ:
グループ: types.kubefed.k8s.io
種類: FederatedConfigMap
複数形名: federatedconfigmaps
スコープ: 名前空間
バージョン: v1beta1
伝播: 有効
ターゲットタイプ:
種類: ConfigMap
複数形名: configmaps
スコープ: 名前空間
バージョン: v1

フェデレーテッドリソースCRD

もう一つ重要なポイントがあります。
CRD: フェデレーションリソース。フェデレーションが必要な新しいリソースを追加する場合は、新しい FederatedXX を作成する必要があります。
CRD(企業リソースレジストリ)は、対応するリソース(どのクラスターに分散させる必要があるか)の構造と分散戦略を記述します。フェデレーションリソースCRDは主に3つの部分で構成されます。

  • テンプレートは、統合されたリソースを記述するために使用されます。
  • 「配置」フィールドには、デプロイ先のクラスターを指定します。設定されていない場合、アプリケーションはどのクラスターにも配布されません。
  • オーバーライドを使用すると、クラスターの一部にある特定のリソースを上書きできます。

次に例を示します。

 APIバージョン: types.kubefed.k8s.io/v1beta1
種類: フェデレーテッドデプロイメント
メタデータ:
名前: テストデプロイメント
名前空間: テスト名前空間
仕様:
template: # デプロイメントのすべてのコンテンツを定義します。これは、デプロイメントとポッドの関係として理解できます。
メタデータ:
ラベル:
アプリ: nginx
仕様:
...
配置:
クラスター:
-名前: クラスター2
-名前: クラスター1
上書き:
-クラスター名: クラスター2
クラスターオーバーライド:
-パス: spec.replicas
値: 5

これらの FederatedXX CRD は​kubefedctl enable <target kubernetes API type>​を使用して作成できます。また、対応する CRD を自分で生成/記述してから作成することもできます。

上記で紹介したクラスター構成、タイプ構成、およびフェデレーテッド リソース CRD を組み合わせると、バージョン v2 の全体的なアーキテクチャと関連する概念がより明確になります。

スケジュール

Kubefedは現在、手動で指定するシンプルなクラスタ間スケジューリングのみをサポートしています。手動スケジューリングの方法は主に2つの部分から構成されます。1つはリソース内でターゲットクラスタを直接指定する方法、もう1つは​ReplicaSchedulingPreference​を介して比例配分する方法です。

リソース内でクラスタを直接指定するには、 ​clusters​を使用して​cluster​のリストを指定するか、 ​clusterSelector​を使用してクラスタタグに基づいてクラスタを選択します。ただし、注意すべき点が2点あります。

  • ​clusters​フィールドが指定されている場合、 ​clusterSelector​無視されます。
  • 選択されたクラスターは平等に扱われ、リソースは選択された各クラスターに単一の区別のないレプリカとしてデプロイされます。
仕様:
配置:
クラスター:
-名前: クラスター2
-名前: クラスター1
クラスターセレクター:
一致ラベル:
foo: バー

複数のクラスター間で差別化されたスケジュールを実行する必要がある場合は、比例してスケジュールするために​ReplicaSchedulingPreference​を導入する必要があります。

 apiバージョン: scheduling.kubefed.io/v1alpha1
種類: レプリカスケジュール設定
メタデータ:
名前: テストデプロイメント
名前空間: test-ns
仕様:
ターゲット種類: フェデレーテッドデプロイメント
合計レプリカ数: 9
クラスター:
答え:
最小レプリカ数: 4
最大レプリカ数: 6
重量: 1
バ:
最小レプリカ数: 4
最大レプリカ数: 8
重量: 2

​totalReplicas​レプリカの合計数を定義し、 ​clusters​さまざまなクラスターの最大/最小レプリカと重みを記述します。

現在、ReplicaSchedulingPreference はデプロイメントとレプリカセットの 2 種類のリソースのみをサポートしています。

カルマダ

Karmadaは、Huaweiによるオープンソースのマルチクラウドコンテナオーケストレーションプロジェクトです。このプロジェクトはKubernetes Federation v1およびv2の継続であり、いくつかの基本概念はこれら2つのバージョンから継承されています。

Karmada には 3 つの主要コンポーネントがあります。

  • Karmada API サーバー: 基本的には、フェデレーションされるリソースを保存するための別の etcd インスタンスがバンドルされた通常の Kubernetes API サーバーです。
  • Karmada コントローラー マネージャー: Karmada API サーバー内のオブジェクトをリッスンし、メンバー クラスター API サーバーと通信する複数のコントローラーのコレクション。
  • Karmadaスケジューラ: 高度なマルチクラスタスケジューリング戦略を提供します

Federation v1と同様に、リソースを配布する際には、Karmada独自のAPIサーバーへの書き込みも必要です。以前は、コントローラーマネージャーが特定のポリシーに基づいてリソースを複数のクラスターに配布していました。しかし、このAPIサーバーはKubernetesネイティブであるため、あらゆるリソースをサポートし、以前のFederation v1バージョンで発生していた問題は発生しません。さらに、フェデレーション管理対象リソースの配布戦略も別のCRDによって制御されるため、v2ではFederated Resource CRDとType Configureを設定する必要はありません。

Karmada の基本的な概念:

  • リソース テンプレート: Karmada はネイティブ Kubernetes API 定義をリソース テンプレートとして使用し、Kubernetes エコシステム ツールチェーンとの迅速な統合を促進します。
  • 配布ポリシー: Karmada は、リソース配布ポリシーを構成するための個別のポリシー API を提供します。
  • オーバーライド ポリシー: Karmada は、異なるクラスターに異なるイメージを構成するなど、クラスター固有のオーバーライドを構成するための個別のオーバーライド API を提供します。

クラスタ

クラスター リソース レコードには、管理対象クラスターにアクセスするために必要な情報 (API エンドポイント、CA バンドル、アクセス トークン) を含む、Federation v2 と同様の情報が含まれています。

仕様:
apiエンドポイント: https://172.31.165.66:55428
シークレットRef:
名前: メンバー1
名前空間: karmada-cluster
同期モード: プッシュ

ただし、Karmadaの​Cluster​リソースには​Push​​Pull​ 2つの同期モードがあるという重要な違いがあります。 ​Push​は最も一般的で標準的な方法で、ホストクラスタのKarmadaコンポーネントがこのタイプのクラスタの状態の同期と更新を担当します。 ​Pull​では、 ​karmada-agent​コンポーネントがメンバークラスタ上で実行されます。このコンポーネントは、自身の状態を収集し、ホストクラスタの対応する​Cluster​リソースの状態を更新します。

伝播ポリシー

Karmadaでメンバークラスターにリソースを分配するには、この別の​PropagationPolicy​ CRを設定する必要があります。以下のnginxアプリケーションを例に挙げると、最初の部分は標準的なKubernetes ​Deployment​であるリソーステンプレートです。

 apiバージョン: apps/v1
種類: デプロイメント
メタデータ:
名前: nginx
ラベル:
アプリ: nginx
仕様:
レプリカ: 2
セレクタ:
一致ラベル:
アプリ: nginx
テンプレート:
メタデータ:
ラベル:
アプリ: nginx
仕様:
コンテナ:
-画像: nginx
名前: nginx

次に、この nginx ​Deployment​リソースの分散戦略を制御するための​PropagationPolicy​を設定します。以下の例では、nginx アプリケーションは 1:1 の重み比で member1 と member2 のクラスターに分散されます。

 apiバージョン: policy.karmada.io/v1alpha1
種類: 伝播ポリシー
メタデータ:
名前: nginx-propagation
仕様:
リソースセレクター:
- apiバージョン: apps/v1
種類: デプロイメント
名前: nginx
配置:
クラスターアフィニティ:
クラスター名:
-メンバー1
-メンバー2
レプリカスケジュール:
レプリカ分割優先度: 重み付け
レプリカスケジュールタイプ: 分割
重量の好み:
静的重量リスト:
-ターゲットクラスター:
クラスター名:
-メンバー1
重量: 1
-ターゲットクラスター:
クラスター名:
-メンバー2
重量: 1

Karmada API サーバーでこれら 2 つのリソースを作成した後、Karmada API サーバーを通じてリソースのステータスを照会できます。

 $ kubectl デプロイを取得
名前 準備完了 最新 利用可能 年齢
nginx 2/2 2 2 51秒

ただし、これはアプリケーションがKarmada APIサーバーと同じクラスターで実行されていることを意味するわけではないことに注意してください。実際には、このクラスターにはワークロードはなく、これらのリソーステンプレートが格納されているだけです。実際のワークロードは、 ​PropagationPolicy​が設定されたmember1クラスターとmember2クラスターで実行されます。member1/member2クラスターに切り替えると、これを確認できます。

 $ kubectlデプロイを取得
名前 準備完了 最新 利用可能 年齢
nginx 1 /1 1 1 6分26秒

$ kubectlポッドを取得する
名前 準備完了 ステータス 再起動 年齢
nginx-6799fc88d8-7cgfz 1 /1 実行中0 6分29秒

分散戦略では、クラスター名の指定に加えて、 ​LabelSelector​​FieldSelector​​ExcludeClusters​もサポートされています。これらのフィルターをすべて設定すると、すべての条件を満たすクラスターのみが選択されます。クラスターアフィニティに加えて、 ​SpreadConstraints​もサポートしています。これは、 ​region​​zone​​provider​などに基づいてクラスターを動的にグループ化することで、アプリケーションを特定のタイプのクラスターにのみ分散できるようにするものです。

​replicas​を持つリソース(ネイティブの​Deployment​​StatefulSet​など)の場合、異なるクラスタにリソースを分散する際に、必要に応じてレプリカ数を更新できます。例えば、member1クラスタのnginxアプリケーションにレプリカを2つ設定し、member2クラスタではレプリカを1つだけ設定したいとします。この設定には複数の方法があり、その1つが​ReplicaSchedulingType​です。これには2つのオプション値があります。

  • ​Duplicated​ : 各候補メンバー クラスターには、元のリソースからコピーされた同じ数のレプリカがあり、 ​ReplicaSchedulingStrategy​設定していない場合と同じ効果が得られます。
  • ​Divided​ :有効な候補メンバークラスターの数に基づいて、レプリカは複数の部分に分割されます。各クラスターのレプリカ数は、 ​ReplicaDivisionPreference​

この​ReplicaDivisionPreference​には 2 つのオプション値があります。

  • ​Aggregated​ :クラスター内の利用可能なリソースを考慮して、これらのレプリカは可能な限り少ないクラスターにスケジュールされます。1つのクラスターにすべてのレプリカを収容できる場合、そのクラスターにのみレプリカがスケジュールされます。他のクラスターにも対応するリソースはありますが、レプリカの数は0になります。
  • ​Weighted​ :レプリカの数は​WeightPreference​に基づいて割り当てられます。WeightPreference ​WeightPreference​非常にシンプルで、各クラスターの重みを直接指定します。

完全かつ詳細な構造については、 ​Placement​ API の定義を参照してください。

上書きポリシー

オーバーライドポリシーは非常にシンプルです。`OverridePolicy` CR ​OverridePolicy​追加することで、クラスタごとに異なる設定を行うことができます。例を見てみましょう。

 apiバージョン: policy.karmada.io/v1alpha1
種類: OverridePolicy
メタデータ:
名前: 例のオーバーライド
名前空間: デフォルト
仕様:
リソースセレクター:
- apiバージョン: apps/v1
種類: デプロイメント
名前: nginx
ターゲットクラスター:
クラスター名:
-メンバー1
ラベルセレクター:
一致ラベル:
失敗ドメイン.kubernetes.io/リージョン: dc1
オーバーライド:
平文:
-パス: /spec/template/spec/containers/0/image
演算子: 置換
値: 'dc-1.registry.io/nginx:1.17.0-alpine'
-パス: /metadata/annotations
演算子: 追加
価値:
foo: バー

参考リンク

  • https://blog.ihypo.net/15716465002689.html
  • https://blog.ihypo.net/15718231244282.html
  • https://jimmysong.io/kubernetes-handbook/practice/federation.html
  • https://support.huaweicloud.com/productdesc-mcp/mcp_productdesc_0001.html