无法在 Go 代码中获取 AWS EKS 集群的 kubeconfig
Unable to obtain kubeconfig of an AWS EKS cluster in Go code
我已经创建了一个 AWS EKS 集群。为了获取它的kubeconfig,我通常运行 aws eks update-kubeconfig --name cluster-name --region us-west-2
使用shell.
但是,我现在希望在 Go 中获取 kubeconfig 而不必 运行 shell 中的任何内容(目标是在 Go 测试中创建然后操作 EKS 集群)。我能够使用以下代码描述 EKS 集群:
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/eks"
)
func main() {
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String("us-west-2"),
}))
eksSvc := eks.New(sess, aws.NewConfig().WithRegion("us-west-2"))
clusterOutput, err := eksSvc.DescribeCluster(&eks.DescribeClusterInput{
Name: aws.String("cluster-name"),
})
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", clusterOutput)
}
在那之后,我目前不知道如何获取该集群的 kubeconfig,然后将其与 Kubernetes 的 Go 客户端一起使用,而无需单独使用 aws eks
。
我已经检查了 AWS 文档、AWS CLI 代码库和 eksctl
代码库,但到目前为止都没有成功。与 EKS 集群的连接仅记录在此网页中,它使用 shell:https://aws.amazon.com/premiumsupport/knowledge-center/eks-cluster-connection/
有什么想法吗?
一般流程是这样的:
- DescribeCluster(正如您所做的那样)并提取一些必要的数据
- 使用必要的数据,使用 aws-iam-authenticator 的
package token
获取令牌
- 使用该令牌,在 client-go 的帮助下创建 Kubernetes 客户端集。
package main
import (
"encoding/base64"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/eks"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"sigs.k8s.io/aws-iam-authenticator/pkg/token"
)
func newClientset(cluster *eks.Cluster) (*kubernetes.Clientset, error) {
log.Printf("%+v", cluster)
gen, err := token.NewGenerator(true, false)
if err != nil {
return nil, err
}
opts := &token.GetTokenOptions{
ClusterID: aws.StringValue(cluster.Name),
}
tok, err := gen.GetWithOptions(opts)
if err != nil {
return nil, err
}
ca, err := base64.StdEncoding.DecodeString(aws.StringValue(cluster.CertificateAuthority.Data))
if err != nil {
return nil, err
}
clientset, err := kubernetes.NewForConfig(
&rest.Config{
Host: aws.StringValue(cluster.Endpoint),
BearerToken: tok.Token,
TLSClientConfig: rest.TLSClientConfig{
CAData: ca,
},
},
)
if err != nil {
return nil, err
}
return clientset, nil
}
func main() {
name := "wonderful-outfit-1583362361"
region := "us-east-2"
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(region),
}))
eksSvc := eks.New(sess)
input := &eks.DescribeClusterInput{
Name: aws.String(name),
}
result, err := eksSvc.DescribeCluster(input)
if err != nil {
log.Fatalf("Error calling DescribeCluster: %v", err)
}
clientset, err := newClientset(result.Cluster)
if err != nil {
log.Fatalf("Error creating clientset: %v", err)
}
nodes, err := clientset.CoreV1().Nodes().List(metav1.ListOptions{})
if err != nil {
log.Fatalf("Error getting EKS nodes: %v", err)
}
log.Printf("There are %d nodes associated with cluster %s", len(nodes.Items), name)
}
这是我的 go.mod 版本:
module github.com/swoldemi/sandbox
go 1.14
require (
github.com/aws/aws-sdk-go v1.29.19
k8s.io/apimachinery v0.0.0-20190612125636-6a5db36e93ad
k8s.io/client-go v0.0.0-20190425172711-65184652c889
sigs.k8s.io/aws-iam-authenticator v0.5.0
)
添加到 ,您可能还想在 GetTokenOptions
结构中传递会话,如下所示:
opts := &token.GetTokenOptions{
ClusterID: aws.StringValue(cluster.Name),
Session: sess,
}
tok, err := gen.GetWithOptions(opts)
否则 gen.GetWithOptions(opts)
调用将尝试从本地来源(例如 ~/.aws/credentials
)读取您的 AWS 凭证,并且可能会失败并出现此错误:
NoCredentialProviders: no valid providers in chain. Deprecated.
For verbose messaging see aws.Config.CredentialsChainVerboseErrors
我已经创建了一个 AWS EKS 集群。为了获取它的kubeconfig,我通常运行 aws eks update-kubeconfig --name cluster-name --region us-west-2
使用shell.
但是,我现在希望在 Go 中获取 kubeconfig 而不必 运行 shell 中的任何内容(目标是在 Go 测试中创建然后操作 EKS 集群)。我能够使用以下代码描述 EKS 集群:
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/eks"
)
func main() {
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String("us-west-2"),
}))
eksSvc := eks.New(sess, aws.NewConfig().WithRegion("us-west-2"))
clusterOutput, err := eksSvc.DescribeCluster(&eks.DescribeClusterInput{
Name: aws.String("cluster-name"),
})
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", clusterOutput)
}
在那之后,我目前不知道如何获取该集群的 kubeconfig,然后将其与 Kubernetes 的 Go 客户端一起使用,而无需单独使用 aws eks
。
我已经检查了 AWS 文档、AWS CLI 代码库和 eksctl
代码库,但到目前为止都没有成功。与 EKS 集群的连接仅记录在此网页中,它使用 shell:https://aws.amazon.com/premiumsupport/knowledge-center/eks-cluster-connection/
有什么想法吗?
一般流程是这样的:
- DescribeCluster(正如您所做的那样)并提取一些必要的数据
- 使用必要的数据,使用 aws-iam-authenticator 的
package token
获取令牌
- 使用该令牌,在 client-go 的帮助下创建 Kubernetes 客户端集。
package main
import (
"encoding/base64"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/eks"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"sigs.k8s.io/aws-iam-authenticator/pkg/token"
)
func newClientset(cluster *eks.Cluster) (*kubernetes.Clientset, error) {
log.Printf("%+v", cluster)
gen, err := token.NewGenerator(true, false)
if err != nil {
return nil, err
}
opts := &token.GetTokenOptions{
ClusterID: aws.StringValue(cluster.Name),
}
tok, err := gen.GetWithOptions(opts)
if err != nil {
return nil, err
}
ca, err := base64.StdEncoding.DecodeString(aws.StringValue(cluster.CertificateAuthority.Data))
if err != nil {
return nil, err
}
clientset, err := kubernetes.NewForConfig(
&rest.Config{
Host: aws.StringValue(cluster.Endpoint),
BearerToken: tok.Token,
TLSClientConfig: rest.TLSClientConfig{
CAData: ca,
},
},
)
if err != nil {
return nil, err
}
return clientset, nil
}
func main() {
name := "wonderful-outfit-1583362361"
region := "us-east-2"
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(region),
}))
eksSvc := eks.New(sess)
input := &eks.DescribeClusterInput{
Name: aws.String(name),
}
result, err := eksSvc.DescribeCluster(input)
if err != nil {
log.Fatalf("Error calling DescribeCluster: %v", err)
}
clientset, err := newClientset(result.Cluster)
if err != nil {
log.Fatalf("Error creating clientset: %v", err)
}
nodes, err := clientset.CoreV1().Nodes().List(metav1.ListOptions{})
if err != nil {
log.Fatalf("Error getting EKS nodes: %v", err)
}
log.Printf("There are %d nodes associated with cluster %s", len(nodes.Items), name)
}
这是我的 go.mod 版本:
module github.com/swoldemi/sandbox
go 1.14
require (
github.com/aws/aws-sdk-go v1.29.19
k8s.io/apimachinery v0.0.0-20190612125636-6a5db36e93ad
k8s.io/client-go v0.0.0-20190425172711-65184652c889
sigs.k8s.io/aws-iam-authenticator v0.5.0
)
添加到 GetTokenOptions
结构中传递会话,如下所示:
opts := &token.GetTokenOptions{
ClusterID: aws.StringValue(cluster.Name),
Session: sess,
}
tok, err := gen.GetWithOptions(opts)
否则 gen.GetWithOptions(opts)
调用将尝试从本地来源(例如 ~/.aws/credentials
)读取您的 AWS 凭证,并且可能会失败并出现此错误:
NoCredentialProviders: no valid providers in chain. Deprecated.
For verbose messaging see aws.Config.CredentialsChainVerboseErrors