DUICUO

Crossplane と VCluster を使用して Kubernetes 上に新しいクラスターを迅速に構築する

Crossplaneは、Kubernetes APIを拡張することでクラウドリソースのプロビジョニングに対応するオープンソースのKubernetesプラグインです。Crossplaneを使用すると、コードを一切記述することなく、アプリケーションが正しく動作するために必要なクラウドリソースを宣言的に定義できます。これらのクラウドリソースは、関連するCRDオブジェクトを作成することで直接定義されるため、実質的にTerraformのクラウドネイティブ版と言えます。

VClusterは、軽量な仮想Kubernetesクラスターを通じて柔軟性とコスト削減を実現するツールです。VClusterを使用すると、Kubernetesクラスター内に独立した仮想Kubernetesクラスターを作成できます。これにより、Kubernetesクラスターのコントロールプレーンの作成と保守の複雑さが大幅に軽減されます。

次の表は、名前空間、vcluster、Kubernetes クラスターの使用時の分離レベルと管理の複雑さを比較したものです。

では、Crossplane と VCluster を組み合わせると何が起こるでしょうか? 例を挙げて説明しましょう。

この例では、次の機能を実現したいと考えています。

  • クラスターを作成すると、新しいクラスター環境を開始する要求を受け取ることができます。
  • これらの環境では、Helm を使用してアプリケーションをインストールできるようになります。
  • 新しい環境を要求するチームはクラスターがどこに作成されるかを気にしないため、VCluster を使用するか、クラウド プロバイダーで Kubernetes クラスターを作成すると、エンド ユーザーに同様のエクスペリエンスが提供されるはずです。

ここでは、デモのためにローカル環境でKinDを使用しています。関連リソースのリストは、https://github.com/salaboy/from-monolith-to-k8s/tree/main/platform/crossplane-vcluster で確認できます(事前にkubectl、helm、kindをインストールしておく必要があります)。

上の図に示すように、KinD クラスター(またはその他の Kubernetes クラスター)を作成し、そのクラスターに Crossplane と Crossplane Helm Provider をインストールするだけです。ここではクラウドリソースを作成しないため、他の Crossplane Provider(GCP、AWS、Azure など)を設定する必要はありません。

クロスプレーンをインストールする

次に、KinD を使用して Kubernetes クラスターを作成します。

 $ kind クラスターを作成
クラスター「kind」 を作成しています...
ノードイメージの確保( kindest / node : v1 .23 .4 ) 🖼
ノードを準備中📦
設定の記述📜
制御起動します🕹️
CNI のインストール🔌
StorageClass のインストール💾
kubectl コンテキスト「kind-kind」 設定する
これで、 クラスターをのように使用できるようになりました
kubectl クラスター- 情報-- コンテキストの種類- 種類
ご質問 バグ報告機能リクエストなどございましたら ぜひお知らせください https://kind.sigs.k8s.io/#community 🙂
$ kubectl ノードを取得
名前ステータス役割年齢バージョン
kind - control - plane Ready control - plane , master 56 s v1 .23 .4

クラスターの準備ができたら、次に示すように、Crossplane と Crossplane Helm Provider を KinD クラスターにインストールできます。

 $ kubectl create ns クロスプレーン- システム
名前空間/ クロスプレーン- 作成されたシステム
$ helm install crossplane --namespace crossplane - system crossplane - stable / crossplane
名前クロスプレーン
最終展開: 2022年8月9日() 15:20:22
名前空間: クロスプレーン- システム
ステータス: 展開済み
改訂1
テストスイート: なし
注記:
リリースクロスプレーン
チャート: クロスプレーン
チャート説明: Crossplane プラットフォームチームが複数のベンダーインフラストラクチャを組み立て アプリケーションチーム使用できるレベルセルフサービスAPI を公開できるようにするオープンソースKubernetes アドオンです
チャートバージョン: 1.9.0
チャートアプリケーションバージョン: 1.9.0
Kube バージョン: v1.23.4

インストール後、次の 2 つの Pod が crossplane-system 名前空間で実行されます。

 $ kubectl get pods - n クロスプレーン- システム
名前準備完了ステータス再起動年齢
クロスプレーン- c9b9fc9f9 - 4 hn47 1 / 1 ランニング0 11 m
クロスプレーン- rbac - マネージャー- 56 c8ff5b65 - 8l grp 1 / 1 実行中0 11 m

次に、Crossplane Helm Provider をインストールする必要があります。これは、crossplane kubectl プラグインを使用して直接実行できます。

 $ kubectl crossplane プロバイダーをインストールcrossplane / provider - helm : v0 .10 .0
provider . pkg . crossplane . io / crossplane - provider - helm が作成されました

さらに、Crossplane Helm プロバイダーをインストールするときは、プロバイダーが Helm Charts をインストールできるように、プロバイダーが新しい ClusterRoleBinding を作成するための適切な ServiceAccount を提供する必要があることに注意することが重要です。

 $ SA = $ ( kubectl -n crossplane - system get sa -o name | grep provider - helm | sed - e ' s|serviceaccount\/|crossplane-system:|g' )
$ エコー$SA
クロスプレーン- システム: クロスプレーン- プロバイダー- helm - 3 d2f09bcd965
$ kubectl create clusterrolebinding provider - helm - admin - binding --clusterrole cluster - admin -- serviceaccount = " ${SA}"
clusterrolebinding . rbac . authorization . k8s . io / provider - helm - admin - binding が作成されました

次に、以下に示すように ProviderConfig オブジェクトを作成し、Helm プロバイダーのインストールを宣言します。

 # helm - プロバイダー- config.yaml
apiVersion : ヘルムクロスプレーンio / v1ベータ1
種類: プロバイダー構成
メタデータ
名前: デフォルト
仕様:
資格
ソース: InjectedIdentity
---
# SA = $ ( kubectl -n crossplane - system get sa -o name | grep provider - helm | sed - e ' s|serviceaccount\/|crossplane-system:|g' )
# kubectl create clusterrolebinding provider - helm - admin - binding --clusterrole cluster - admin -- serviceaccount = "$ { SA}"

上記のリソース リストを適用するだけです。

 $ kubectl apply -f helm -provider -config .yaml   
providerconfig . helm . crossplane . io / default が作成されました

Crossplane のインストールはこれで完了です。最後に、Kubernetes クラスターに接続するための vcluster コマンドラインツールのインストールもお勧めします。インストール手順については、https://www.vcluster.com/docs/getting-started/setup のドキュメントをご覧ください。

クロスプレーンコンポジションを使用した VCluster の作成

CrossplaneとCrossplane Helm Providerが準備完了しました。次はCrossplane Compositionを見てみましょう。Crossplaneは、管理対象リソースをコンポジションするためのメカニズムを提供し、ユーザーは宣言的に独自の抽象化を作成できます。

  • 複合リソース(XR):複合リソースは、管理対象リソースから構成されるカスタムリソースであり、インフラストラクチャの詳細を抽象化できます。CompositeResourceDefinition(XRD)は、新しいタイプの複合リソースを定義します。XRDはクラスター全体で有効であり、名前空間固有のXRを作成するには、対応するXRDで複合リソース宣言(XRC)を提供できます。
  • コンポジション:コンポジションは、XR を構成するリソース、つまり XR を作成したときに何が起こるかを指定します。XR は複数のコンポジションを持つことができます。例えば、CompositeDatabase XR の場合、1 つのコンポジションを使用して AWS RDS インスタンス、セキュリティグループ、および MySQL データベースを作成できます。別のコンポジションでは、GCP CloudSQL インスタンスと PostgreSQL データベースを定義できます。
  • 構成: 構成は XRD であり、Crossplane CLI を使用して OCI イメージ レジストリに公開でき、宣言型構成リソースを作成して Crossplane クラスターにインストールできる要素のパッケージです。

ここでのCrossplane Composition(XR)は、新しい環境リソースを作成する際に実行する必要がある操作を定義します。このオブジェクトは以下の操作を実行します。

  • Helm Provider のインストール時に設定した Helm Provider Config を使用して、VCluster Helm Chart をインストールします。この Chart をインストールすると、新しい VCluster を作成できます。とても簡単ですね。
  • VCluster をインストールすると、VCluster APIServer に接続するためのトークンを含む Kubernetes Secret オブジェクトが作成されます。この Secret を使用して 2 つ目の Helm Provider Config を設定し、新しく作成したクラスターに Helm Chart をインストールできます。
  • 2 番目の Helm プロバイダー Config を使用して、作成された VCluster にアプリケーションをインストールできます。

次に、これがどのように実現されるかを見てみましょう。まず、新しい環境リソースを作成できるように、Crossplane CompositionとEnvironment CRDをクラスターに適用する必要があります。

まず、環境の複合リソースを定義します。対応するリソースリストは以下のとおりです。このオブジェクトは、Kubernetes クラスターの CRD に相当します。

 # 環境- リソース- 定義.yaml
api バージョン: apiextensions.crossplane.io/v1
種類: 複合リソース定義
メタデータ
名前: 環境.fmtok8s.salaboy.com
仕様:
グループ: fmtok8s.salaboy.com
名前:
種類: 環境
複数形環境
クレーム名:
種類: クラスター
複数形クラスター
バージョン:
- 名前: v1alpha1
提供true
参照可能: true
スキーマ:
openAPIV3スキーマ:
タイプ: オブジェクト
プロパティ
仕様:
タイプ: オブジェクト
プロパティ: {}

XRDコンポジションリソースを宣言したら、次はコンポジションオブジェクトを定義します。リソースマニフェストファイルの内容を以下に示します。このコンポジションオブジェクトは複数のリソースを定義し、それらは上記のXRDオブジェクトで宣言されたEnvironmentオブジェクトに関連付けられます。

 # 構成.yaml
api バージョン: apiextensions.crossplane.io/v1
種類: 作曲
メタデータ
名前: 環境.fmtok8s.salaboy.com
仕様:
writeConnectionSecretsToNamespace : クロスプレーン- システム
複合型参照:
apiバージョン: fmtok8s.salaboy.com/v1alpha1
種類: 環境
リソース
- 名前: vcluster - helm - リリース
ベース:
apiVersion : ヘルムクロスプレーンio / v1ベータ1
種類: リリース
メタデータ
注釈:
クロスプレーン.io / 外部: # パッチ適用済み
仕様:
ロールバック制限: 3
プロバイダー:
名前空間: # パッチ適用済み
チャート
名前: vcluster
リポジトリ: https://charts.loft.sh
バージョン: "0.10.2"

シンカー:
extraArgs : [] # パッチ適用済み
# - --out - kube - config - server = https : //cluster-1.cluster-1.svc
プロバイダー構成参照:
名前: デフォルト
パッチ:
- fromFieldPath : メタデータ. 名前
toFieldPath : spec.forProvider.namespace
ポリシー
fromFieldPath : 必須
- fromFieldPath : メタデータ. 名前
toFieldPath : メタデータ. アノテーション[ クロスプレーン.io / 外部]
ポリシー
fromFieldPath : 必須
- fromFieldPath : メタデータ. 名前
toFieldPath : メタデータ名
変換:
- : 文字列

fmt : "%s-vcluster"
- タイプ: CombineFromComposite
組み合わせる
変数:
- fromFieldPath : メタデータ. 名前
戦略文字列

fmt : "--out-kube-config-secret=%s-secret"
toFieldPath : 仕様forProvider価値観シンクロ追加引数[ 0 ]
- タイプ: CombineFromComposite
組み合わせる
変数:
- fromFieldPath : メタデータ. 名前
- fromFieldPath : メタデータ. 名前
戦略文字列

fmt : "--out-kube-config-server=https://%s.%s.svc"
toFieldPath : 仕様forProvider価値観シンクロ追加引数[ 1 ]
- タイプ: CombineFromComposite
組み合わせる
変数:
- fromFieldPath : メタデータ. 名前
- fromFieldPath : メタデータ. 名前
戦略文字列

fmt : "--tls-san=%s.%s.svc"
toFieldPath : 仕様forProvider価値観シンクロextraArgs [ 2 ]
- 名前: helm - providerconfig
ベース:
api バージョン: helm.crossplane.io/v1alpha1
種類: プロバイダー構成
仕様:
資格
出典シークレット
シークレットRef :
名前: # パッチ適用済み
名前空間: # パッチ適用済み
キー: config
パッチ:
- fromFieldPath : メタデータ. 名前
toFieldPath : spec.credentials.secretRef.name
変換:
- : 文字列

fmt : vc -% s
- fromFieldPath : メタデータ. 名前
toFieldPath : spec.credentials.secretRef.namespace
- fromFieldPath : メタデータ.uid
toFieldPath : メタデータ名
- 名前: helm - プロバイダー- vcluster
ベース:
apiVersion : ヘルムクロスプレーンio / v1ベータ1
種類: プロバイダー構成
仕様:
資格
出典シークレット
シークレットRef :
名前空間: #patched
キー: config
パッチ:
- fromFieldPath : メタデータ. 名前
toFieldPath : メタデータ名
- fromFieldPath : メタデータ. 名前
toFieldPath : spec.credentials.secretRef.namespace
ポリシー
fromFieldPath : 必須
# このProviderConfig 上記VCluster の接続シークレットを
# 資格情報は秘密です
- fromFieldPath : "metadata.name"
toFieldPath : spec.credentials.secretRef.name
変換:
- : 文字列

fmt : "%s-secret"
準備チェック:
- タイプ: なし
- 名前: 会議- チャート- vcluster
ベース:
apiVersion : ヘルムクロスプレーンio / v1ベータ1
種類: リリース
メタデータ
注釈:
クロスプレーン.io / 外部: 会議
仕様:
プロバイダー:
チャート
名前: fmtok8s - カンファレンス- チャート
リポジトリ: https://salaboy.github.io/helm/
バージョン: "v0.1.1"
名前空間: 会議
プロバイダー構成参照:
名前: #パッチ済み
パッチ:
- fromFieldPath : メタデータ. 名前
toFieldPath : spec.providerConfigRef.name

Crossplane で使用する VCluster Chart パッケージに 3 つのパラメータを設定します。

  • 53 行目では、`fmt: "--out-kube-config-secret=%s-secret"` を設定します。これは、VCluster で Secret オブジェクトを作成し、その中に kubeconfig をホストして、それを取得して新しく作成された APIServer に接続する必要があるためです。
  • 62行目のfmt: "--out-kube-config-server=https://%s.%s.svc" は、kubeconfig がクラスター内から新しい APIServer URL を参照する必要があるため、設定されています。デフォルトでは、生成された kubeconfig は https://localhost:8443 を参照します。
  • 71 行目の構成「fmt: "--tls-san=%s.%s.svc"」は、APIServer が接続を受け入れるホストのリストに新しいサービス アドレスを追加する必要があることを示しています。

次に、上記の 2 つのオブジェクトを直接適用できます。

 $ kubectl apply -f コンポジション.yaml
composition.apiextensions.crossplane.io/environment.fmtok8s.salaboy.com 作成
$ kubectl apply -f 環境- リソース- 定義.yaml
compositeresourcedefinition.apiextensions.crossplane.io/environments.fmtok8s.salaboy.com 作成まし

クラスターの複合要素と CRD が利用可能になると、新しい環境リソースの作成を開始し、実行前に現在どの VCluster が利用可能かを確認できます。

 $ vcluster リスト
名前名前空間ステータス接続済み作成日年齢
エントリが見つかりません

まだVClustersは存在しないはずです。これで新しい環境を作成できます。例えば、`dev`環境を定義するには、以下のように`Environment`オブジェクトを宣言するだけです。

 # 環境- resource.yaml
apiバージョン: fmtok8s.salaboy.com/v1alpha1
種類: 環境
メタデータ
名前: 開発環境
仕様: {}

オブジェクトを直接適用します。

 $ kubectl apply -f 環境- リソース.yaml 
環境.fmtok8s.salaboy.com / dev - 環境作成されまし
$ kubectl 環境を取得する
名前準備構成年齢
dev - 環境偽の環境. fmtok8s . salaboy . com 57
$ kubectl 環境を記述しますdev - 環境
名前: 開発環境
名前空間:
ラベル: crossplane . io / composite = dev - environment
注釈: <なし>
API バージョン: fmtok8sサラボーイcom / v1alpha1
種類: 環境
……
イベント:
タイプ理由年齢送信元 メッセージ
---- ------ ---- ---- -------
通常のPublishConnectionSecret 76 s が定義されました/ compositeresourcedefinition . apiextensions . crossplane . io 接続の詳細が正常に公開されました
通常のSelectComposition 19 76 以上でx7 定義済み/compositeresourcedefinition.apiextensions.crossplane.io 構成正常選択されまし
通常のComposeResources 18 ( x7 、 76 以上) defined / compositeresourcedefinition . apiextensions . crossplane . io リソース正常に構成されました

これで、作成した環境を他のKubernetesリソースと同じように扱えるようになりました。`kubectl get environments` を使って直接リストを表示したり、description を使って詳細情報を確認したりすることも可能です。

ここで VCluster を再度確認して正常であれば、新しいリソースが見つかります。

 $ vcluster リスト
名前名前空間ステータス接続済み作成日年齢
開発環境開発環境実行2022-08-09 17:44:07 + 0800 CST 56 38

VClusterは、APIServer(デフォルトでK3sを使用)、CoreDNSインスタンス、Syncerを新しい名前空間dev-environmentにインストールします。これにより、ユーザーはkubectl経由でVCluster API Serverとやり取りできるようになります。通常のクラスターと同様に、VClusterはこれらのリソースをワークロードのスケジューリングを担当するホストクラスターと同期し、名前空間をKubernetesクラスターとして機能させます。

Crossplane と Crossplane Helm Provider を設定したら、新しい Helm Release を作成し、Helm Chart をインストールすることで、新しい VCluster を簡単に作成できます。

シークレット内に作成された正しいkubeconfigを使用してVClusterを作成したら、新しく作成されたVClusterにアプリケーションをインストールするための2つ目のHelmプロバイダーを設定できます。上記のコンポジションオブジェクトの95行目に定義されているhelm-provider-vclusterが、このプロバイダーの説明です。

次に、コンポジション内で、会議アプリケーション用の Helm Chart パッケージの使用を構成しました。

すべての設定を完了し、新しい環境を作成したら、VCluster に接続してアプリケーションがインストールされているかどうかを確認します。

 $ vcluster connect dev - 環境-- サーバーhttps : //localhost:8443 -- bash
デフォルト対話型シェルzsh になりまし
zsh を使用するようにアカウント更新するには`chsh - s / bin / zsh` を実行してください
詳細についてhttps://support.apple.com/kb/HT208050 をご覧ください
bash - 3.2 $ kubectl get ns
名前ステータス年齢
デフォルトアクティブ32m
kube - システムアクティブ32 m
kube - パブリックアクティブ32 か月
kube - ノード- リースアクティブ32 か
会議アクティブ23
bash - 3.2 $ kubectl get pods - n カンファレンス
名前準備完了ステータス再起動年齢
会議- fmtok8s - フロントエンド- 7 cd5db8669 - pv944 1 / 1 実行中0 23
会議- fmtok8s - メール- サービス- 768 bc88cbb - sklrg 1 / 1 実行中0 23
会議- postgresql - 0 1 / 1 実行中0 23
会議- fmtok8s - c4p - サービス- 7f 56 d7bd9d - 2 vjtx 1 / 1 実行中2 ( 19 ) 23
会議- redis - マスター- 0 1 / 1 実行中0 23
会議- Redis - レプリカ- 0 1 / 1 実行中0 23
会議- fmtok8s - 議題- サービス- 7 db66c9568 - xsh5m 1 / 1 実行中2 ( 16 ) 23

ご覧のとおり、アプリケーションはこのクラスターに正常にインストールされており、これらのアプリケーションは実際には元の KinD クラスターの dev-environment 名前空間の下にデプロイされています。

 $ kubectl get pods - n dev - 環境
名前準備完了ステータス再起動年齢
会議- fmtok8s - 議題- サービス- 7 db66c9568 - xsh5m - x - 08f 9332627 1 / 1 実行中2 ( 18 ) 25
会議- fmtok8s - c4p - サービス- 7f 56 d7bd9d - 2 vjtx - x - co - fc2c58eaec 1 / 1 実行中2 ( 21 ) 25
会議- fmtok8s - メール- サービス- 768 bc88cbb - sklrg - x -- c5d9594434 1 / 1 実行中0 25 m
会議- fmtok8s - フロントエンド- 7 cd5db8669 - pv944 - x - confe - 2832 ac1bef 1 / 1 実行中0 25
会議- postgresql - 0 - x - 会議- x - 開発- 環境1 / 1 実行中0 25
会議- redis - マスター- 0 - x - 会議- x - 開発- 環境1 / 1 実行中0 25
会議- redis - レプリカ- 0 - x - 会議- x - 開発- 環境1 / 1 実行中0 25
coredns - 76 dd5485df - 6 cbl7 - x - kube - system - x - dev - environment 1 / 1 実行中0 34
開発- 環境- 0 2 / 2 実行中0 63

VCluster は単純に名前空間を分離し、その使用エクスペリエンスは Kubernetes クラスターと基本的に同じになります。

要約

これは、CrossplaneとVClusterを併用してKubernetesクラスタ環境を迅速に構成し、そこにアプリケーションをインストールすることで開発者の生産性を向上させる方法を示す簡単な例です。もちろん、最適化の余地は数多くあります。例えば、以下のような点です。

  • VClusterにArgoCDをインストールし、環境パラメータとして提供されるGitHub URLを使用すると、GitOpsが有効になり、VCluster上でkubectlを使用する必要がなくなります。コンポジションを使用すると、ArgoCDリソースを作成し、ユーザーの介入なしにリポジトリとクラスターを構成できます。
  • 開発者が Knative Functions、Knative Serving、Eventing 機能を利用してアプリケーションを設計できるように、VCluster に Knative をインストールします。
  • VCluster が使用するクラウド リソース (GCP、AKS、EKS など) の選択は、環境パラメータによって決まります。
  • 同様に、Crossplane もローカル KinD クラスターでテスト・使用されています。GCP、AWS、Azure などの実際のクラウドリソースにも接続できます。