You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:05:40