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

如何配置Cloud Run中的Kubernetes客户端连接GKE集群?

配置Cloud Run中的Kubernetes客户端连接GKE集群

问题背景

本地运行的Java代码可正常在GKE集群创建Job,但部署到Cloud Run后触发UnknownHostException: kubernetes.default.svc: Name or service not known错误。这是因为Cloud Run不属于Kubernetes集群内部环境,无法访问集群内部DNS,也没有挂载集群内的ServiceAccount凭证文件。

解决方案

1. 为Cloud Run绑定具备GKE操作权限的ServiceAccount

  • 创建或选择一个Cloud IAM服务账号(ServiceAccount),授予其GKE资源操作权限,比如roles/container.developer(或更细粒度的权限,如roles/batch.jobsCreator)。
  • 部署Cloud Run服务时指定该ServiceAccount:
    gcloud run deploy [你的Cloud Run服务名] \
      --image southamerica-east1-docker.pkg.dev/kubernetes-hello-world-360615/hello-repo/cloud-run:v1 \
      --service-account [服务账号邮箱,如xxx@your-project.iam.gserviceaccount.com]
    

2. 修改Java代码配置Kubernetes客户端

Cloud Run无法自动获取Kubernetes集群配置,需要手动指定GKE集群的外部API端点,并使用Google Cloud的应用默认凭证进行身份验证:

  • 先获取GKE集群的API端点:
    gcloud container clusters describe [你的GKE集群名] \
      --zone [集群所在区域,如southamerica-east1-a] \
      --format="value(endpoint)"
    
  • 修改Java代码,配置客户端连接参数:
    import com.google.auth.oauth2.GoogleCredentials;
    import io.fabric8.kubernetes.client.ConfigBuilder;
    import io.fabric8.kubernetes.client.KubernetesClient;
    import io.fabric8.kubernetes.client.KubernetesClientBuilder;
    import java.io.IOException;
    import java.util.Collections;
    import io.fabric8.kubernetes.api.model.batch.Job;
    import io.fabric8.kubernetes.api.model.batch.JobBuilder;
    import io.fabric8.kubernetes.api.model.PodList;
    import io.fabric8.kubernetes.client.KubernetesClientException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Main {
        private static final Logger logger = LoggerFactory.getLogger(Main.class);
    
        public static void main(String[] args) {
            try {
                // 获取Google应用默认凭证(由Cloud Run绑定的ServiceAccount提供)
                GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
                String authToken = credentials.refreshAccessToken().getTokenValue();
                // 替换为你的GKE集群API端点
                String clusterEndpoint = "https://[你的GKE集群端点]";
    
                ConfigBuilder configBuilder = new ConfigBuilder()
                        .withMasterUrl(clusterEndpoint)
                        .withOauthToken(authToken)
                        .withTrustCerts(true); // GKE的公网端点可信任默认证书
    
                try (KubernetesClient client = new KubernetesClientBuilder().withConfig(configBuilder.build()).build()) {
                    // 原有的Job创建及日志获取逻辑保持不变
                    final String namespace = "default";
                    final Job job = new JobBuilder()
                            .withApiVersion("batch/v1")
                            .withNewMetadata()
                            .withName("pi")
                            .withLabels(Collections.singletonMap("label1", "maximum-length-of-63-characters"))
                            .withAnnotations(Collections.singletonMap("annotation1", "some-very-long-annotation"))
                            .endMetadata()
                            .withNewSpec()
                            .withNewTemplate()
                            .withNewSpec()
                            .addNewContainer()
                            .withName("pi")
                            .withImage("perl:5.34.0")
                            .withArgs("perl", "-Mbignum=bpi", "-wle", "print bpi(2000)")
                            .endContainer()
                            .withRestartPolicy("Never")
                            .endSpec()
                            .endTemplate()
                            .endSpec()
                            .build();
    
                    logger.info("Creating job pi.");
                    client.batch().v1().jobs().inNamespace(namespace).createOrReplace(job);
    
                    PodList podList = client.pods().inNamespace(namespace).withLabel("job-name", job.getMetadata().getName()).list();
                    String joblog = client.batch().v1().jobs().inNamespace(namespace).withName("pi").getLog();
                    logger.info(joblog);
                } catch (KubernetesClientException e) {
                    logger.error("Unable to create job", e);
                }
            } catch (IOException e) {
                logger.error("Failed to get Google credentials", e);
            }
        }
    }
    
  • 添加Google Auth依赖到Maven/POM文件:
    <dependency>
        <groupId>com.google.auth</groupId>
        <artifactId>google-auth-library-oauth2-http</artifactId>
        <version>1.19.0</version>
    </dependency>
    

3. 验证网络与权限

  • 如果GKE集群使用私有端点,需要配置Cloud Run的VPC连接器,让服务可以访问GKE所在的VPC网络;如果是公网端点,确保集群控制平面允许公网访问(默认GKE公网端点允许所有IP,可按需限制)。
  • 确认ServiceAccount权限生效:通过以下命令验证权限绑定:
    gcloud projects get-iam-policy [你的项目ID] \
      --filter="bindings.members:serviceAccount:[你的服务账号邮箱]" \
      --format="value(bindings.role)"
    

内容的提问来源于stack exchange,提问作者carlos palma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:39:20