如何在Cloud Functions中以代码方式替代gke-gcloud-auth-plugin访问GKE 1.26+
GKE 1.26+ 无二进制依赖认证适配(Cloud Functions 单二进制场景)
问题说明
原有代码因GKE 1.26+集群移除内置GCP认证提供商,改用gke-gcloud-auth-plugin而失效。由于运行环境是Cloud Functions,无法安装该二进制程序,因此需要实现单二进制方案:通过Application Default Credentials(ADC)运行时身份自动完成认证刷新,效果与GKE 1.26以下版本一致。
现有代码情况
集群信息获取代码
原有代码通过GKE API获取集群配置信息:
ctx := context.Background() containerService, _ := container.NewService(ctx) name := fmt.Sprintf("projects/%s/locations/%s/clusters/%s", clusterProject, clusterLocation, clusterName, ) rqst := containerService.Projects.Locations.Clusters.Get(name) resp, _ := rqst.Do() cert, _ := base64.StdEncoding.DecodeString(resp.MasterAuth.ClusterCaCertificate) server := fmt.Sprintf("https://%s", resp.Endpoint) apiConfig := api.Config{ APIVersion: "v1", Kind: "Config", Clusters: map[string]*api.Cluster{ clusterName: { CertificateAuthorityData: cert, Server: server, }, }, Contexts: map[string]*api.Context{ clusterName: { Cluster: clusterName, AuthInfo: clusterName, }, }, AuthInfos: map[string]*api.AuthInfo{ clusterName: { // 原认证配置在此处 }, }, }
旧认证配置(已失效)
原代码使用GCP认证提供商,在GKE 1.26+已不再被支持:
AuthProvider: &api.AuthProviderConfig{ Name: "gcp", Config: map[string]string{ "scopes": "https://www.googleapis.com/auth/cloud-platform", }, }
官方推荐的二进制调用方式(不可用)
官方推荐的gke-gcloud-auth-plugin二进制调用方案,因Cloud Functions无法安装二进制而不可行:
Exec: &api.ExecConfig{ Command: "gke-gcloud-auth-plugin", APIVersion: "client.authentication.k8s.io/v1", InstallHint: "Requires gke-gcloud-auth-plugin", ProvideClusterInfo: true, InteractiveMode: api.IfAvailableExecInteractiveMode, },
解决方案:集成gke-gcloud-auth-plugin核心逻辑
gke-gcloud-auth-plugin底层仍基于GCP OAuth2机制,仅调整了认证令牌的受众(audience)为GKE集群的特定值。我们可以直接在代码中实现该逻辑,无需依赖外部二进制:
步骤1:引入必要依赖
确保项目中包含以下依赖(根据client-go版本调整):
import ( "context" "fmt" "encoding/base64" "google.golang.org/api/container/v1" "google.golang.org/api/option" "k8s.io/client-go/tools/clientcmd/api" "k8s.io/client-go/rest" "golang.org/x/oauth2/google" "google.golang.org/api/idtoken" )
步骤2:实现GKE专用令牌获取逻辑
GKE要求认证令牌的受众为https://container.googleapis.com/v1/projects/{PROJECT}/locations/{LOCATION}/clusters/{CLUSTER},我们直接通过ADC获取符合要求的令牌:
func getGKEToken(ctx context.Context, clusterResourceName string) (string, error) { ts, err := idtoken.NewTokenSource(ctx, clusterResourceName) if err != nil { return "", fmt.Errorf("failed to create token source: %w", err) } token, err := ts.Token() if err != nil { return "", fmt.Errorf("failed to get token: %w", err) } return token.AccessToken, nil }
步骤3:构建支持自动刷新的配置
替换原AuthInfos中的配置,推荐直接构建rest.Config(自动处理令牌刷新),如需兼容旧代码也可转换为api.Config:
// 获取集群信息(原有代码保留,补充错误处理) ctx := context.Background() containerService, err := container.NewService(ctx, option.WithCredentialsFile("")) // 使用ADC if err != nil { // 错误处理逻辑 } clusterResourceName := fmt.Sprintf("projects/%s/locations/%s/clusters/%s", clusterProject, clusterLocation, clusterName) rqst := containerService.Projects.Locations.Clusters.Get(clusterResourceName) resp, err := rqst.Do() if err != nil { // 错误处理逻辑 } cert, err := base64.StdEncoding.DecodeString(resp.MasterAuth.ClusterCaCertificate) if err != nil { // 错误处理逻辑 } server := fmt.Sprintf("https://%s", resp.Endpoint) // 创建自动刷新的令牌源 tokenSource, err := idtoken.NewTokenSource(ctx, clusterResourceName) if err != nil { // 错误处理逻辑 } // 构建rest.Config(推荐方式,自动处理令牌过期刷新) restConfig := &rest.Config{ Host: server, TLSClientConfig: rest.TLSClientConfig{ CAData: cert, }, BearerTokenSource: tokenSource, } // 如需转换为api.Config(兼容旧代码场景) apiConfig := api.Config{ APIVersion: "v1", Kind: "Config", Clusters: map[string]*api.Cluster{ clusterName: { CertificateAuthorityData: cert, Server: server, }, }, Contexts: map[string]*api.Context{ clusterName: { Cluster: clusterName, AuthInfo: clusterName, }, }, AuthInfos: map[string]*api.AuthInfo{ clusterName: { AuthProvider: &api.AuthProviderConfig{ Name: "gcp", Config: map[string]string{ "cluster_resource_name": clusterResourceName, }, }, }, }, CurrentContext: clusterName, }
关键说明
- 使用
idtoken.NewTokenSource获取针对GKE集群资源的专用令牌,完全匹配gke-gcloud-auth-plugin的认证要求 - 直接集成到
rest.Config的BearerTokenSource字段,client-go会自动处理令牌过期与刷新 - 无需依赖任何外部二进制,完全通过代码实现,适配Cloud Functions单二进制部署场景
内容的提问来源于stack exchange,提问作者DazWilkin
相关产品推荐
相关产品推荐

