若您希望在平台中整合ACK One艦隊以訪問各子叢集資源,可以利用Go SDK進行操作。本文介紹如何使用Go SDK通過艦隊KubeConfig管理多叢集的Kubernetes資源。
多叢集資源訪問原理
ACK One採用開源社區的Cluster Gateway,通過艦隊的KubeConfig實現對多叢集的Kubernetes資源的統一訪問,並通過User impersonation來控制使用者對子叢集RBAC許可權的訪問。
使用阿里雲帳號(主帳號)或者RAM User登入艦隊後,擷取艦隊KubeConfig。
對於RAM User,可預先配置其對子叢集的RBAC許可權。
在艦隊中擷取OCM ManagedCluster資源,Cluster Gateway通過ManagedCluster的名稱來切換叢集,以訪問子叢集的Kubernetes資源。
User impersonation
Cluster Gateway支援通過偽裝(user impersonation)來控制訪問子叢集Kubernetes資源許可權,具體步驟如下。
使用阿里雲帳號(主帳號)登入ACK One控制台,在左側導覽列選擇。進入關聯集群頁簽,為RAM User授予每個子叢集的RBAC許可權。
使用RAM User登入ACK One控制台,在左側導覽列選擇。進入串連艦隊頁簽擷取KubeConfig。
使用該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。主要步驟如下。
通過KubeConfig擷取關聯集群對應的OCM ManagedCluster資源。
通過Cluster Gateway為每個子叢集構建kubeClient。
列印所有子叢集的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
)