全部產品
Search
文件中心

Container Service for Kubernetes:通過Go SDK訪問多叢集資源

更新時間:Dec 26, 2025

若您希望在平台中整合ACK One艦隊以訪問各子叢集資源,可以利用Go SDK進行操作。本文介紹如何使用Go SDK通過艦隊KubeConfig管理多叢集的Kubernetes資源。

多叢集資源訪問原理

image

ACK One採用開源社區的Cluster Gateway,通過艦隊的KubeConfig實現對多叢集的Kubernetes資源的統一訪問,並通過User impersonation來控制使用者對子叢集RBAC許可權的訪問。

  1. 使用阿里雲帳號(主帳號)或者RAM User登入艦隊後,擷取艦隊KubeConfig。

    對於RAM User,可預先配置其對子叢集的RBAC許可權。

  2. 在艦隊中擷取OCM ManagedCluster資源,Cluster Gateway通過ManagedCluster的名稱來切換叢集,以訪問子叢集的Kubernetes資源。

User impersonation

Cluster Gateway支援通過偽裝(user impersonation)來控制訪問子叢集Kubernetes資源許可權,具體步驟如下。

  1. 使用阿里雲帳號(主帳號)登入ACK One控制台,在左側導覽列選擇艦隊 > 許可權管理進入關聯集群頁簽,為RAM User授予每個子叢集的RBAC許可權。

  2. 使用RAM User登入ACK One控制台,在左側導覽列選擇艦隊 > 艦隊資訊進入串連艦隊頁簽擷取KubeConfig。

  3. 使用該KubeConfig通過Cluster Gateway訪問各子叢集的Kubernetes資源。具體操作,請參見範例程式碼

    若無某個資源的操作許可權,Cluster Gateway會報類似如下錯誤資訊。

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

範例程式碼

以下範例程式碼基於OCM v0.14.0版本,通過艦隊KubeConfig訪問多叢集Kubernetes資源,列印所有子叢集的kube-system namespace的UID。主要步驟如下。

  1. 通過KubeConfig擷取關聯集群對應的OCM ManagedCluster資源。

  2. 通過Cluster Gateway為每個子叢集構建kubeClient。

  3. 列印所有子叢集的kube-system namespace的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 namespace的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("failed to get kube-system for member cluster %s: %v", cluster, err))
			continue
		}
		fmt.Println(fmt.Sprintf("Cluster %s kube-system namespace 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
	}

	// get managedclusters by ocmClusterClient
	ocmClusterClient, err := ocmcluster.NewForConfig(fleetConfig)
	if err != nil {
		return nil, fmt.Errorf("failed to create ocm cluster client: %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("failed to create kube client for cluster %s: %v", cluster.Name, err))
			continue
		}
		memberClients[cluster.Name] = kubeClient
	}

	return memberClients, errors.NewAggregate(errs)
}

go.mod配置

module example.com/ack-one-demo

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
)