すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Go 用 SDK を使用したマルチクラスタリソースへのアクセス

最終更新日:Feb 26, 2025

分散クラウドコンテナプラットフォーム Kubernetes 版 (ACK One) Fleet インスタンスをプラットフォームに統合して各クラスタのリソースにアクセスする場合、Go 用 SDK を使用できます。このトピックでは、Go 用 SDK を使用して、Fleet インスタンスの kubeconfig ファイルを使用して複数のクラスタの Kubernetes リソースを管理する方法について説明します。

マルチクラスタリソースアクセスの原則

ACK One は、オープンソースコミュニティの Cluster Gateway を使用して、Fleet インスタンスの kubeconfig ファイルを使用した複数のクラスタの Kubernetes リソースへの一元的なアクセスを実現しています。また、ACK One は ユーザー偽装 を使用して、クラスタのロールベースアクセス制御 (RBAC) 権限へのユーザーアクセスを管理します。

  1. Alibaba Cloud アカウントまたは RAM ユーザーを使用して Fleet にログオンします。次に、kubeconfig ファイルを取得します。

    事前にクラスタの RBAC 権限を RAM ユーザーに付与できます。

  2. Fleet 内の Open Cluster Management (OCM) ManagedCluster リソースを取得します。Cluster Gateway は、ManagedCluster の名前を使用してクラスタを変更し、クラスタの Kubernetes リソースにアクセスします。

ユーザー偽装

Cluster Gateway では、ユーザー偽装を使用して、クラスタ内の Kubernetes リソースへのアクセスを管理できます。次のセクションでは、詳細な手順について説明します。

  1. Alibaba Cloud アカウントを使用して、ACK コンソール にログオンします。左側のナビゲーションウィンドウで、[fleet] > [権限] を選択します。 [関連付けられたクラスタ] タブをクリックし、各クラスタの RBAC 権限を RAM ユーザーに付与します。

  2. ACK One コンソール にログオンします。左側のナビゲーションウィンドウで、[fleet 情報] を選択します。 [fleet に接続] タブをクリックして、kubeconfig ファイルを取得します。

  3. kubeconfig ファイルを使用して、Cluster Gateway を使用して各クラスタの Kubernetes リソースにアクセスします。詳細については、「サンプルコード」をご参照ください。

    リソースに対する操作を実行する権限がない場合、Cluster Gateway は次のような内容のエラーメッセージを報告します。

    stream error: stream ID 3; INTERNAL_ERROR; received from peer

サンプルコード

次のサンプルコードは、OCM v0.14.0 に基づいています。このサンプルは、Fleet インスタンスの kubeconfig ファイルを使用してマルチクラスタ Kubernetes リソースにアクセスし、すべてのクラスタの kube-system 名前空間 UID を出力する方法の例を示しています。次の手順を実行します。

  1. kubeconfig ファイルを使用して、関連付けられたクラスタに対応する OCM ManagedCluster リソースを取得します。

  2. Cluster Gateway を使用して、各クラスタの kubeClient パラメータを構成できます。

  3. すべてのクラスタの kube-system 名前空間の UID を出力します。

package main

import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/errors"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	ocmcluster "open-cluster-management.io/api/client/cluster/clientset/versioned"
)

// クラスタの kube-system 名前空間の UID を出力します。
func main() {
	fleetKubeconfigPath := "<your fleet kubeconifg path>"
	memberClients, err := GenerateMemberClusterKubeClients(fleetKubeconfigPath)
	if err != nil {
		panic(err.Error())
	}

	for cluster, kubeClient := range memberClients {
		ns, err := kubeClient.CoreV1().Namespaces().Get(context.TODO(), "kube-system", metav1.GetOptions{})
		if err != nil {
			fmt.Println(fmt.Sprintf("メンバークラスタ %s の kube-system の取得に失敗しました: %v", cluster, err))
			continue
		}
		fmt.Println(fmt.Sprintf("クラスタ %s kube-system 名前空間 UID: %s", cluster, ns.UID))
	}
}

// クラスタの KubeClient を生成します。
func GenerateMemberClusterKubeClients(fleetKubeconfigPath string) (map[string]kubernetes.Interface, error) {
	fleetConfig, err := clientcmd.BuildConfigFromFlags("", fleetKubeconfigPath)
	if err != nil {
		return nil, err
	}

	// ocmClusterClient によって managedclusters を取得します
	ocmClusterClient, err := ocmcluster.NewForConfig(fleetConfig)
	if err != nil {
		return nil, fmt.Errorf("ocm クラスタクライアントの作成に失敗しました: %v", err)
	}
	managedClusters, err := ocmClusterClient.ClusterV1().ManagedClusters().List(context.Background(), metav1.ListOptions{})
	if err != nil {
		return nil, err
	}

	var errs []error
	memberClients := make(map[string]kubernetes.Interface)
	for _, cluster := range managedClusters.Items {
		configCopy := *fleetConfig
		configCopy.Host = fmt.Sprintf("%s/apis/cluster.core.oam.dev/v1alpha1/clustergateways/%s/proxy", fleetConfig.Host, cluster.Name)
		kubeClient, err := kubernetes.NewForConfig(&configCopy)
		if err != nil {
			errs = append(errs, fmt.Errorf("クラスタ %s の kube クライアントの作成に失敗しました: %v", cluster.Name, err))
			continue
		}
		memberClients[cluster.Name] = kubeClient
	}

	return memberClients, errors.NewAggregate(errs)
}

go.mod 構成

go 1.21.0


require (
	k8s.io/apimachinery v0.29.0
	k8s.io/client-go v0.29.0
	open-cluster-management.io/api v0.14.0
)

require (
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/emicklei/go-restful/v3 v3.11.0 // indirect
	github.com/go-logr/logr v1.4.1 // indirect
	github.com/go-openapi/jsonpointer v0.19.6 // indirect
	github.com/go-openapi/jsonreference v0.20.2 // indirect
	github.com/go-openapi/swag v0.22.3 // indirect
	github.com/gogo/protobuf v1.3.2 // indirect
	github.com/golang/protobuf v1.5.4 // indirect
	github.com/google/gnostic-models v0.6.8 // indirect
	github.com/google/gofuzz v1.2.0 // indirect
	github.com/google/uuid v1.3.0 // indirect
	github.com/imdario/mergo v0.3.6 // indirect
	github.com/josharian/intern v1.0.0 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/mailru/easyjson v0.7.7 // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
	github.com/spf13/pflag v1.0.5 // indirect
	golang.org/x/net v0.23.0 // indirect
	golang.org/x/oauth2 v0.12.0 // indirect
	golang.org/x/sys v0.18.0 // indirect
	golang.org/x/term v0.18.0 // indirect
	golang.org/x/text v0.14.0 // indirect
	golang.org/x/time v0.3.0 // indirect
	google.golang.org/appengine v1.6.7 // indirect
	google.golang.org/protobuf v1.33.0 // indirect
	gopkg.in/inf.v0 v0.9.1 // indirect
	gopkg.in/yaml.v2 v2.4.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
	k8s.io/api v0.30.0 // indirect
	k8s.io/klog/v2 v2.120.1 // indirect
	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
	k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
	sigs.k8s.io/yaml v1.4.0 // indirect
)