Creé un clúster de AWS EKS. Para obtener su kubeconfig, generalmente ejecuto aws eks update-kubeconfig --name cluster-name --region us-west-2 usando un shell.
Sin embargo, ahora deseo obtener el kubeconfig en Go sin tener que ejecutar nada en el shell (el objetivo es crear y luego manipular un clúster de EKS en una prueba de Go). Puedo describir un clúster de EKS usando este código:
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) } Después de eso, actualmente no tengo idea de cómo podría obtener el kubeconfig de ese clúster para luego usarlo con el cliente Go para Kubernetes sin tener que usar aws eks por separado.
Revisé la documentación de AWS, el código base de la CLI de AWS y el código base de eksctl sin suerte hasta ahora. La conexión a un clúster de EKS solo se documenta en esta página web y utiliza un shell: https://aws.amazon.com/premiumsupport/knowledge-center/eks-cluster-connection/
¿Algunas ideas?
El flujo general es algo como esto:
package token de aws-iam-authenticator 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) }Aquí está mi go.mod para las versiones:
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 )Agregando a la gran respuesta de Simon , es posible que también desee pasar la sesión en la estructura GetTokenOptions , así:
opts := &token.GetTokenOptions{ ClusterID: aws.StringValue(cluster.Name), Session: sess, } tok, err := gen.GetWithOptions(opts) De lo contrario, la gen.GetWithOptions(opts) intentará leer sus credenciales de AWS de fuentes locales (por ejemplo ~/.aws/credentials ) y puede fallar con este error:
NoCredentialProviders: no valid providers in chain. Deprecated. For verbose messaging see aws.Config.CredentialsChainVerboseErrors