分散クラウドコンテナプラットフォーム Kubernetes 版 (ACK One) Fleet インスタンスをプラットフォームに統合して各クラスタのリソースにアクセスする場合、Go 用 SDK を使用できます。このトピックでは、Go 用 SDK を使用して、Fleet インスタンスの kubeconfig ファイルを使用して複数のクラスタの Kubernetes リソースを管理する方法について説明します。
マルチクラスタリソースアクセスの原則
ACK One は、オープンソースコミュニティの Cluster Gateway を使用して、Fleet インスタンスの kubeconfig ファイルを使用した複数のクラスタの Kubernetes リソースへの一元的なアクセスを実現しています。また、ACK One は ユーザー偽装 を使用して、クラスタのロールベースアクセス制御 (RBAC) 権限へのユーザーアクセスを管理します。
Alibaba Cloud アカウントまたは RAM ユーザーを使用して Fleet にログオンします。次に、kubeconfig ファイルを取得します。
事前にクラスタの RBAC 権限を RAM ユーザーに付与できます。
Fleet 内の Open Cluster Management (OCM) ManagedCluster リソースを取得します。Cluster Gateway は、ManagedCluster の名前を使用してクラスタを変更し、クラスタの Kubernetes リソースにアクセスします。
ユーザー偽装
Cluster Gateway では、ユーザー偽装を使用して、クラスタ内の Kubernetes リソースへのアクセスを管理できます。次のセクションでは、詳細な手順について説明します。
Alibaba Cloud アカウントを使用して、ACK コンソール にログオンします。左側のナビゲーションウィンドウで、 を選択します。 [関連付けられたクラスタ] タブをクリックし、各クラスタの RBAC 権限を RAM ユーザーに付与します。
ACK One コンソール にログオンします。左側のナビゲーションウィンドウで、 を選択します。 [fleet に接続] タブをクリックして、kubeconfig ファイルを取得します。
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 を出力する方法の例を示しています。次の手順を実行します。
kubeconfig ファイルを使用して、関連付けられたクラスタに対応する OCM ManagedCluster リソースを取得します。
Cluster Gateway を使用して、各クラスタの kubeClient パラメータを構成できます。
すべてのクラスタの 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
)